Skip to content

Commit 2f5bfa7

Browse files
committed
Merge branch 'js/maint-1.6.1-remote-remove-mirror' into maint-1.6.1
* js/maint-1.6.1-remote-remove-mirror: builtin-remote: make rm operation safer in mirrored repository builtin-remote: make rm() use properly named variable to hold return value
2 parents 592ebd0 + 441adf0 commit 2f5bfa7

File tree

2 files changed

+58
-7
lines changed

2 files changed

+58
-7
lines changed

builtin-remote.c

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ static int add_known_remote(struct remote *remote, void *cb_data)
298298

299299
struct branches_for_remote {
300300
struct remote *remote;
301-
struct string_list *branches;
301+
struct string_list *branches, *skipped;
302302
struct known_remotes *keep;
303303
};
304304

@@ -323,6 +323,16 @@ static int add_branch_for_removal(const char *refname,
323323
return 0;
324324
}
325325

326+
/* don't delete non-remote refs */
327+
if (prefixcmp(refname, "refs/remotes")) {
328+
/* advise user how to delete local branches */
329+
if (!prefixcmp(refname, "refs/heads/"))
330+
string_list_append(abbrev_branch(refname),
331+
branches->skipped);
332+
/* silently skip over other non-remote refs */
333+
return 0;
334+
}
335+
326336
/* make sure that symrefs are deleted */
327337
if (flags & REF_ISSYMREF)
328338
return unlink(git_path("%s", refname));
@@ -542,8 +552,11 @@ static int rm(int argc, const char **argv)
542552
struct strbuf buf = STRBUF_INIT;
543553
struct known_remotes known_remotes = { NULL, NULL };
544554
struct string_list branches = { NULL, 0, 0, 1 };
545-
struct branches_for_remote cb_data = { NULL, &branches, &known_remotes };
546-
int i;
555+
struct string_list skipped = { NULL, 0, 0, 1 };
556+
struct branches_for_remote cb_data = {
557+
NULL, &branches, &skipped, &known_remotes
558+
};
559+
int i, result;
547560

548561
if (argc != 2)
549562
usage_with_options(builtin_remote_usage, options);
@@ -583,14 +596,26 @@ static int rm(int argc, const char **argv)
583596
* refs, which are invalidated when deleting a branch.
584597
*/
585598
cb_data.remote = remote;
586-
i = for_each_ref(add_branch_for_removal, &cb_data);
599+
result = for_each_ref(add_branch_for_removal, &cb_data);
587600
strbuf_release(&buf);
588601

589-
if (!i)
590-
i = remove_branches(&branches);
602+
if (!result)
603+
result = remove_branches(&branches);
591604
string_list_clear(&branches, 1);
592605

593-
return i;
606+
if (skipped.nr) {
607+
fprintf(stderr, skipped.nr == 1 ?
608+
"Note: A non-remote branch was not removed; "
609+
"to delete it, use:\n" :
610+
"Note: Non-remote branches were not removed; "
611+
"to delete them, use:\n");
612+
for (i = 0; i < skipped.nr; i++)
613+
fprintf(stderr, " git branch -d %s\n",
614+
skipped.items[i].string);
615+
}
616+
string_list_clear(&skipped, 0);
617+
618+
return result;
594619
}
595620

596621
static void show_list(const char *title, struct string_list *list,

t/t5505-remote.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,32 @@ test_expect_success 'remove remote' '
107107
)
108108
'
109109

110+
test_expect_success 'remove remote protects non-remote branches' '
111+
(
112+
cd test &&
113+
(cat >expect1 <<EOF
114+
Note: A non-remote branch was not removed; to delete it, use:
115+
git branch -d master
116+
EOF
117+
cat >expect2 <<EOF
118+
Note: Non-remote branches were not removed; to delete them, use:
119+
git branch -d foobranch
120+
git branch -d master
121+
EOF
122+
) &&
123+
git tag footag
124+
git config --add remote.oops.fetch "+refs/*:refs/*" &&
125+
git remote rm oops 2>actual1 &&
126+
git branch foobranch &&
127+
git config --add remote.oops.fetch "+refs/*:refs/*" &&
128+
git remote rm oops 2>actual2 &&
129+
git branch -d foobranch &&
130+
git tag -d footag &&
131+
test_cmp expect1 actual1 &&
132+
test_cmp expect2 actual2
133+
)
134+
'
135+
110136
cat > test/expect << EOF
111137
* remote origin
112138
URL: $(pwd)/one

0 commit comments

Comments
 (0)