diff options
author | Junio C Hamano <gitster@pobox.com> | 2009-02-05 19:40:41 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2009-02-05 19:40:41 -0800 |
commit | ba743d1b0ce0b44c797c0de06c9db2781e4d1fdd (patch) | |
tree | a1fb2a7e5be4820b4f4386c41b77c1c8f22e06b9 | |
parent | 7b75b331f6744fbf953fe8913703378ef86a2189 (diff) | |
parent | 441adf0ccf571a9fe15658fdfcd856d2aabc01cb (diff) | |
download | git-ba743d1b0ce0b44c797c0de06c9db2781e4d1fdd.tar.gz git-ba743d1b0ce0b44c797c0de06c9db2781e4d1fdd.tar.xz |
Merge branch 'js/maint-remote-remove-mirror'
* js/maint-remote-remove-mirror:
builtin-remote: make rm operation safer in mirrored repository
builtin-remote: make rm() use properly named variable to hold return value
-rw-r--r-- | builtin-remote.c | 39 | ||||
-rwxr-xr-x | t/t5505-remote.sh | 26 |
2 files changed, 58 insertions, 7 deletions
diff --git a/builtin-remote.c b/builtin-remote.c index abc8dd838..db18bcfc9 100644 --- a/builtin-remote.c +++ b/builtin-remote.c @@ -298,7 +298,7 @@ static int add_known_remote(struct remote *remote, void *cb_data) struct branches_for_remote { struct remote *remote; - struct string_list *branches; + struct string_list *branches, *skipped; struct known_remotes *keep; }; @@ -323,6 +323,16 @@ static int add_branch_for_removal(const char *refname, return 0; } + /* don't delete non-remote refs */ + if (prefixcmp(refname, "refs/remotes")) { + /* advise user how to delete local branches */ + if (!prefixcmp(refname, "refs/heads/")) + string_list_append(abbrev_branch(refname), + branches->skipped); + /* silently skip over other non-remote refs */ + return 0; + } + /* make sure that symrefs are deleted */ if (flags & REF_ISSYMREF) return unlink(git_path("%s", refname)); @@ -542,8 +552,11 @@ static int rm(int argc, const char **argv) struct strbuf buf = STRBUF_INIT; struct known_remotes known_remotes = { NULL, NULL }; struct string_list branches = { NULL, 0, 0, 1 }; - struct branches_for_remote cb_data = { NULL, &branches, &known_remotes }; - int i; + struct string_list skipped = { NULL, 0, 0, 1 }; + struct branches_for_remote cb_data = { + NULL, &branches, &skipped, &known_remotes + }; + int i, result; if (argc != 2) usage_with_options(builtin_remote_usage, options); @@ -583,14 +596,26 @@ static int rm(int argc, const char **argv) * refs, which are invalidated when deleting a branch. */ cb_data.remote = remote; - i = for_each_ref(add_branch_for_removal, &cb_data); + result = for_each_ref(add_branch_for_removal, &cb_data); strbuf_release(&buf); - if (!i) - i = remove_branches(&branches); + if (!result) + result = remove_branches(&branches); string_list_clear(&branches, 1); - return i; + if (skipped.nr) { + fprintf(stderr, skipped.nr == 1 ? + "Note: A non-remote branch was not removed; " + "to delete it, use:\n" : + "Note: Non-remote branches were not removed; " + "to delete them, use:\n"); + for (i = 0; i < skipped.nr; i++) + fprintf(stderr, " git branch -d %s\n", + skipped.items[i].string); + } + string_list_clear(&skipped, 0); + + return result; } static void show_list(const char *title, struct string_list *list, diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 1f59960d9..bc5b7ce4a 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -107,6 +107,32 @@ test_expect_success 'remove remote' ' ) ' +test_expect_success 'remove remote protects non-remote branches' ' +( + cd test && + (cat >expect1 <<EOF +Note: A non-remote branch was not removed; to delete it, use: + git branch -d master +EOF + cat >expect2 <<EOF +Note: Non-remote branches were not removed; to delete them, use: + git branch -d foobranch + git branch -d master +EOF +) && + git tag footag + git config --add remote.oops.fetch "+refs/*:refs/*" && + git remote rm oops 2>actual1 && + git branch foobranch && + git config --add remote.oops.fetch "+refs/*:refs/*" && + git remote rm oops 2>actual2 && + git branch -d foobranch && + git tag -d footag && + test_cmp expect1 actual1 && + test_cmp expect2 actual2 +) +' + cat > test/expect << EOF * remote origin URL: $(pwd)/one |