|
10 | 10 | #include "diff.h"
|
11 | 11 | #include "revision.h"
|
12 | 12 | #include "reachable.h"
|
| 13 | +#include "worktree.h" |
13 | 14 |
|
14 | 15 | /* NEEDSWORK: switch to using parse_options */
|
15 | 16 | static const char reflog_expire_usage[] =
|
@@ -52,6 +53,7 @@ struct collect_reflog_cb {
|
52 | 53 | struct collected_reflog **e;
|
53 | 54 | int alloc;
|
54 | 55 | int nr;
|
| 56 | + struct worktree *wt; |
55 | 57 | };
|
56 | 58 |
|
57 | 59 | /* Remember to update object flag allocation in object.h */
|
@@ -330,13 +332,27 @@ static int push_tip_to_list(const char *refname, const struct object_id *oid,
|
330 | 332 | return 0;
|
331 | 333 | }
|
332 | 334 |
|
| 335 | +static int is_head(const char *refname) |
| 336 | +{ |
| 337 | + switch (ref_type(refname)) { |
| 338 | + case REF_TYPE_OTHER_PSEUDOREF: |
| 339 | + case REF_TYPE_MAIN_PSEUDOREF: |
| 340 | + if (parse_worktree_ref(refname, NULL, NULL, &refname)) |
| 341 | + BUG("not a worktree ref: %s", refname); |
| 342 | + break; |
| 343 | + default: |
| 344 | + break; |
| 345 | + } |
| 346 | + return !strcmp(refname, "HEAD"); |
| 347 | +} |
| 348 | + |
333 | 349 | static void reflog_expiry_prepare(const char *refname,
|
334 | 350 | const struct object_id *oid,
|
335 | 351 | void *cb_data)
|
336 | 352 | {
|
337 | 353 | struct expire_reflog_policy_cb *cb = cb_data;
|
338 | 354 |
|
339 |
| - if (!cb->cmd.expire_unreachable || !strcmp(refname, "HEAD")) { |
| 355 | + if (!cb->cmd.expire_unreachable || is_head(refname)) { |
340 | 356 | cb->tip_commit = NULL;
|
341 | 357 | cb->unreachable_expire_kind = UE_HEAD;
|
342 | 358 | } else {
|
@@ -388,8 +404,19 @@ static int collect_reflog(const char *ref, const struct object_id *oid, int unus
|
388 | 404 | {
|
389 | 405 | struct collected_reflog *e;
|
390 | 406 | struct collect_reflog_cb *cb = cb_data;
|
| 407 | + struct strbuf newref = STRBUF_INIT; |
| 408 | + |
| 409 | + /* |
| 410 | + * Avoid collecting the same shared ref multiple times because |
| 411 | + * they are available via all worktrees. |
| 412 | + */ |
| 413 | + if (!cb->wt->is_current && ref_type(ref) == REF_TYPE_NORMAL) |
| 414 | + return 0; |
| 415 | + |
| 416 | + strbuf_worktree_ref(cb->wt, &newref, ref); |
| 417 | + FLEX_ALLOC_STR(e, reflog, newref.buf); |
| 418 | + strbuf_release(&newref); |
391 | 419 |
|
392 |
| - FLEX_ALLOC_STR(e, reflog, ref); |
393 | 420 | oidcpy(&e->oid, oid);
|
394 | 421 | ALLOC_GROW(cb->e, cb->nr + 1, cb->alloc);
|
395 | 422 | cb->e[cb->nr++] = e;
|
@@ -512,7 +539,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
512 | 539 | {
|
513 | 540 | struct expire_reflog_policy_cb cb;
|
514 | 541 | timestamp_t now = time(NULL);
|
515 |
| - int i, status, do_all; |
| 542 | + int i, status, do_all, all_worktrees = 1; |
516 | 543 | int explicit_expiry = 0;
|
517 | 544 | unsigned int flags = 0;
|
518 | 545 |
|
@@ -549,6 +576,8 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
549 | 576 | flags |= EXPIRE_REFLOGS_UPDATE_REF;
|
550 | 577 | else if (!strcmp(arg, "--all"))
|
551 | 578 | do_all = 1;
|
| 579 | + else if (!strcmp(arg, "--single-worktree")) |
| 580 | + all_worktrees = 0; |
552 | 581 | else if (!strcmp(arg, "--verbose"))
|
553 | 582 | flags |= EXPIRE_REFLOGS_VERBOSE;
|
554 | 583 | else if (!strcmp(arg, "--")) {
|
@@ -577,10 +606,19 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)
|
577 | 606 |
|
578 | 607 | if (do_all) {
|
579 | 608 | struct collect_reflog_cb collected;
|
| 609 | + struct worktree **worktrees, **p; |
580 | 610 | int i;
|
581 | 611 |
|
582 | 612 | memset(&collected, 0, sizeof(collected));
|
583 |
| - for_each_reflog(collect_reflog, &collected); |
| 613 | + worktrees = get_worktrees(0); |
| 614 | + for (p = worktrees; *p; p++) { |
| 615 | + if (!all_worktrees && !(*p)->is_current) |
| 616 | + continue; |
| 617 | + collected.wt = *p; |
| 618 | + refs_for_each_reflog(get_worktree_ref_store(*p), |
| 619 | + collect_reflog, &collected); |
| 620 | + } |
| 621 | + free_worktrees(worktrees); |
584 | 622 | for (i = 0; i < collected.nr; i++) {
|
585 | 623 | struct collected_reflog *e = collected.e[i];
|
586 | 624 | set_reflog_expiry_param(&cb.cmd, explicit_expiry, e->reflog);
|
|
0 commit comments