Skip to content

Commit 0cc01c9

Browse files
committed
Merge branch 'sp/remote'
* sp/remote: Make "git-remote rm" delete refs acccording to fetch specs Make "git-remote prune" delete refs according to fetch specs Remove unused remote_prefix member in builtin-remote
2 parents d8ad63a + 7ad2458 commit 0cc01c9

File tree

2 files changed

+74
-36
lines changed

2 files changed

+74
-36
lines changed

builtin-remote.c

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ static void read_branches(void)
206206

207207
struct ref_states {
208208
struct remote *remote;
209-
struct strbuf remote_prefix;
210209
struct path_list new, stale, tracked;
211210
};
212211

@@ -262,35 +261,71 @@ static int get_ref_states(const struct ref *ref, struct ref_states *states)
262261
}
263262
free_refs(fetch_map);
264263

265-
strbuf_addf(&states->remote_prefix,
266-
"refs/remotes/%s/", states->remote->name);
267264
for_each_ref(handle_one_branch, states);
268265
sort_path_list(&states->stale);
269266

270267
return 0;
271268
}
272269

270+
struct known_remote {
271+
struct known_remote *next;
272+
struct remote *remote;
273+
};
274+
275+
struct known_remotes {
276+
struct remote *to_delete;
277+
struct known_remote *list;
278+
};
279+
280+
static int add_known_remote(struct remote *remote, void *cb_data)
281+
{
282+
struct known_remotes *all = cb_data;
283+
struct known_remote *r;
284+
285+
if (!strcmp(all->to_delete->name, remote->name))
286+
return 0;
287+
288+
r = xmalloc(sizeof(*r));
289+
r->remote = remote;
290+
r->next = all->list;
291+
all->list = r;
292+
return 0;
293+
}
294+
273295
struct branches_for_remote {
274-
const char *prefix;
296+
struct remote *remote;
275297
struct path_list *branches;
298+
struct known_remotes *keep;
276299
};
277300

278301
static int add_branch_for_removal(const char *refname,
279302
const unsigned char *sha1, int flags, void *cb_data)
280303
{
281304
struct branches_for_remote *branches = cb_data;
305+
struct refspec refspec;
306+
struct path_list_item *item;
307+
struct known_remote *kr;
282308

283-
if (!prefixcmp(refname, branches->prefix)) {
284-
struct path_list_item *item;
309+
memset(&refspec, 0, sizeof(refspec));
310+
refspec.dst = (char *)refname;
311+
if (remote_find_tracking(branches->remote, &refspec))
312+
return 0;
313+
314+
/* don't delete a branch if another remote also uses it */
315+
for (kr = branches->keep->list; kr; kr = kr->next) {
316+
memset(&refspec, 0, sizeof(refspec));
317+
refspec.dst = (char *)refname;
318+
if (!remote_find_tracking(kr->remote, &refspec))
319+
return 0;
320+
}
285321

286-
/* make sure that symrefs are deleted */
287-
if (flags & REF_ISSYMREF)
288-
return unlink(git_path(refname));
322+
/* make sure that symrefs are deleted */
323+
if (flags & REF_ISSYMREF)
324+
return unlink(git_path(refname));
289325

290-
item = path_list_append(refname, branches->branches);
291-
item->util = xmalloc(20);
292-
hashcpy(item->util, sha1);
293-
}
326+
item = path_list_append(refname, branches->branches);
327+
item->util = xmalloc(20);
328+
hashcpy(item->util, sha1);
294329

295330
return 0;
296331
}
@@ -316,8 +351,9 @@ static int rm(int argc, const char **argv)
316351
};
317352
struct remote *remote;
318353
struct strbuf buf;
354+
struct known_remotes known_remotes = { NULL, NULL };
319355
struct path_list branches = { NULL, 0, 0, 1 };
320-
struct branches_for_remote cb_data = { NULL, &branches };
356+
struct branches_for_remote cb_data = { NULL, &branches, &known_remotes };
321357
int i;
322358

323359
if (argc != 2)
@@ -327,6 +363,9 @@ static int rm(int argc, const char **argv)
327363
if (!remote)
328364
die("No such remote: %s", argv[1]);
329365

366+
known_remotes.to_delete = remote;
367+
for_each_remote(add_known_remote, &known_remotes);
368+
330369
strbuf_init(&buf, 0);
331370
strbuf_addf(&buf, "remote.%s", remote->name);
332371
if (git_config_rename_section(buf.buf, NULL) < 1)
@@ -355,9 +394,7 @@ static int rm(int argc, const char **argv)
355394
* the branches one by one, since for_each_ref() relies on cached
356395
* refs, which are invalidated when deleting a branch.
357396
*/
358-
strbuf_reset(&buf);
359-
strbuf_addf(&buf, "refs/remotes/%s/", remote->name);
360-
cb_data.prefix = buf.buf;
397+
cb_data.remote = remote;
361398
i = for_each_ref(add_branch_for_removal, &cb_data);
362399
strbuf_release(&buf);
363400

@@ -422,27 +459,10 @@ static int show_or_prune(int argc, const char **argv, int prune)
422459
states.remote->name);
423460

424461
if (prune) {
425-
struct strbuf buf;
426-
int prefix_len;
427-
428-
strbuf_init(&buf, 0);
429-
if (states.remote->fetch_refspec_nr == 1 &&
430-
states.remote->fetch->pattern &&
431-
!strcmp(states.remote->fetch->src,
432-
states.remote->fetch->dst))
433-
/* handle --mirror remote */
434-
strbuf_addstr(&buf, "refs/heads/");
435-
else
436-
strbuf_addf(&buf, "refs/remotes/%s/", *argv);
437-
prefix_len = buf.len;
438-
439462
for (i = 0; i < states.stale.nr; i++) {
440-
strbuf_setlen(&buf, prefix_len);
441-
strbuf_addstr(&buf, states.stale.items[i].path);
442-
result |= delete_ref(buf.buf, NULL);
463+
const char *refname = states.stale.items[i].util;
464+
result |= delete_ref(refname, NULL);
443465
}
444-
445-
strbuf_release(&buf);
446466
goto cleanup_states;
447467
}
448468

t/t5505-remote.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,24 @@ test_expect_success 'add --mirror && prune' '
164164
git rev-parse --verify refs/heads/side)
165165
'
166166

167+
test_expect_success 'add alt && prune' '
168+
(mkdir alttst &&
169+
cd alttst &&
170+
git init &&
171+
git remote add -f origin ../one &&
172+
git config remote.alt.url ../one &&
173+
git config remote.alt.fetch "+refs/heads/*:refs/remotes/origin/*") &&
174+
(cd one &&
175+
git branch -m side side2) &&
176+
(cd alttst &&
177+
git rev-parse --verify refs/remotes/origin/side &&
178+
! git rev-parse --verify refs/remotes/origin/side2 &&
179+
git fetch alt &&
180+
git remote prune alt &&
181+
! git rev-parse --verify refs/remotes/origin/side &&
182+
git rev-parse --verify refs/remotes/origin/side2)
183+
'
184+
167185
cat > one/expect << EOF
168186
apis/master
169187
apis/side

0 commit comments

Comments
 (0)