Skip to content

Commit

Permalink
gc: remove broken symrefs
Browse files Browse the repository at this point in the history
When encountering broken symrefs, such as a stale remote HEAD (which can
happen if the active branch was renamed in the remote), it is more
helpful to remove those symrefs than to exit with an error.

This fixes git-for-windows#423

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
  • Loading branch information
dscho committed Sep 28, 2015
1 parent b040339 commit 66c8a99
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 2 deletions.
12 changes: 11 additions & 1 deletion builtin/prune.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "reachable.h"
#include "parse-options.h"
#include "progress.h"
#include "refs.h"

static const char * const prune_usage[] = {
N_("git prune [-n] [-v] [--expire <time>] [--] [<head>...]"),
Expand Down Expand Up @@ -100,6 +101,7 @@ static void remove_temporary_files(const char *path)
int cmd_prune(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
struct string_list broken_symrefs = STRING_LIST_INIT_DUP;
struct progress *progress = NULL;
const struct option options[] = {
OPT__DRY_RUN(&show_only, N_("do not remove, show only")),
Expand All @@ -110,6 +112,7 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
OPT_END()
};
char *s;
int i;

expire = ULONG_MAX;
save_commit_buffer = 0;
Expand All @@ -136,7 +139,14 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
if (show_progress)
progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);

mark_reachable_objects(&revs, 1, expire, progress, NULL);
revs.ignore_missing = 1;
mark_reachable_objects(&revs, 1, expire, progress, &broken_symrefs);
for (i = 0; i < broken_symrefs.nr; i++) {
char *path = broken_symrefs.items[i].string;
printf("Removing stale ref %s\n", path);
if (!show_only && delete_ref(path, NULL, REF_NODEREF))
die("Could not remove stale ref %s", path);
}
stop_progress(&progress);
for_each_loose_file_in_objdir(get_object_directory(), prune_object,
prune_cruft, prune_subdir, NULL);
Expand Down
2 changes: 1 addition & 1 deletion t/t6500-gc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test_expect_success 'gc -h with invalid configuration' '
test_i18ngrep "[Uu]sage" broken/usage
'

test_expect_failure 'gc removes broken refs/remotes/<name>/HEAD' '
test_expect_success 'gc removes broken refs/remotes/<name>/HEAD' '
git init remote &&
(
cd remote &&
Expand Down

0 comments on commit 66c8a99

Please sign in to comment.