From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Michael Haggerty" <mhagger@alum.mit.edu>,
"Stefan Beller" <sbeller@google.com>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v4 11/16] revision.c: --all adds HEAD from all worktrees
Date: Wed, 23 Aug 2017 19:36:59 +0700 [thread overview]
Message-ID: <20170823123704.16518-12-pclouds@gmail.com> (raw)
In-Reply-To: <20170823123704.16518-1-pclouds@gmail.com>
Unless single_worktree is set, --all now adds HEAD from all worktrees.
Since reachable.c code does not use setup_revisions(), we need to call
other_head_refs_submodule() explicitly there to have the same effect on
"git prune", so that we won't accidentally delete objects needed by some
other HEADs.
A new FIXME is added because we would need something like
int refs_other_head_refs(struct ref_store *, each_ref_fn, cb_data);
in addition to other_head_refs() to handle it, which might require
int get_submodule_worktrees(const char *submodule, int flags);
It could be a separate topic to reduce the scope of this one.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
reachable.c | 2 ++
revision.c | 14 ++++++++++++++
submodule.c | 2 ++
t/t5304-prune.sh | 12 ++++++++++++
worktree.c | 22 ++++++++++++++++++++++
worktree.h | 8 ++++++++
6 files changed, 60 insertions(+)
diff --git a/reachable.c b/reachable.c
index c62efbfd43..492e87b9fa 100644
--- a/reachable.c
+++ b/reachable.c
@@ -9,6 +9,7 @@
#include "cache-tree.h"
#include "progress.h"
#include "list-objects.h"
+#include "worktree.h"
struct connectivity_progress {
struct progress *progress;
@@ -176,6 +177,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
/* detached HEAD is not included in the list above */
head_ref(add_one_ref, revs);
+ other_head_refs(add_one_ref, revs);
/* Add all reflog info */
if (mark_reflog)
diff --git a/revision.c b/revision.c
index 8d04516266..0e98444857 100644
--- a/revision.c
+++ b/revision.c
@@ -2133,6 +2133,14 @@ static int handle_revision_pseudo_opt(const char *submodule,
int argcount;
if (submodule) {
+ /*
+ * We need some something like get_submodule_worktrees()
+ * before we can go through all worktrees of a submodule,
+ * .e.g with adding all HEADs from --all, which is not
+ * supported right now, so stick to single worktree.
+ */
+ if (!revs->single_worktree)
+ die("BUG: --single-worktree cannot be used together with submodule");
refs = get_submodule_ref_store(submodule);
} else
refs = get_main_ref_store();
@@ -2150,6 +2158,12 @@ static int handle_revision_pseudo_opt(const char *submodule,
if (!strcmp(arg, "--all")) {
handle_refs(refs, revs, *flags, refs_for_each_ref);
handle_refs(refs, revs, *flags, refs_head_ref);
+ if (!revs->single_worktree) {
+ struct all_refs_cb cb;
+
+ init_all_refs_cb(&cb, revs, *flags);
+ other_head_refs(handle_one_ref, &cb);
+ }
clear_ref_exclusion(&revs->ref_excludes);
} else if (!strcmp(arg, "--branches")) {
handle_refs(refs, revs, *flags, refs_for_each_branch_ref);
diff --git a/submodule.c b/submodule.c
index 98e1f9d3c7..61a38adcd4 100644
--- a/submodule.c
+++ b/submodule.c
@@ -1685,6 +1685,8 @@ static int find_first_merges(struct object_array *result, const char *path,
oid_to_hex(&a->object.oid));
init_revisions(&revs, NULL);
rev_opts.submodule = path;
+ /* FIXME: can't handle linked worktrees in submodules yet */
+ revs.single_worktree = path != NULL;
setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts);
/* save all revisions from the above list that contain b */
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index cba45c7be9..683bdb031c 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -292,4 +292,16 @@ test_expect_success 'prune: handle index in multiple worktrees' '
test_cmp second-worktree/blob actual
'
+test_expect_success 'prune: handle HEAD in multiple worktrees' '
+ git worktree add --detach third-worktree &&
+ echo "new blob for third-worktree" >third-worktree/blob &&
+ git -C third-worktree add blob &&
+ git -C third-worktree commit -m "third" &&
+ rm .git/worktrees/third-worktree/index &&
+ test_must_fail git -C third-worktree show :blob &&
+ git prune --expire=now &&
+ git -C third-worktree show HEAD:blob >actual &&
+ test_cmp third-worktree/blob actual
+'
+
test_done
diff --git a/worktree.c b/worktree.c
index e28ffbeb09..389e2e952c 100644
--- a/worktree.c
+++ b/worktree.c
@@ -386,3 +386,25 @@ int submodule_uses_worktrees(const char *path)
closedir(dir);
return ret;
}
+
+int other_head_refs(each_ref_fn fn, void *cb_data)
+{
+ struct worktree **worktrees, **p;
+ int ret = 0;
+
+ worktrees = get_worktrees(0);
+ for (p = worktrees; *p; p++) {
+ struct worktree *wt = *p;
+ struct ref_store *refs;
+
+ if (wt->is_current)
+ continue;
+
+ refs = get_worktree_ref_store(wt);
+ ret = refs_head_ref(refs, fn, cb_data);
+ if (ret)
+ break;
+ }
+ free_worktrees(worktrees);
+ return ret;
+}
diff --git a/worktree.h b/worktree.h
index 5ea5e503fb..9276c81ae7 100644
--- a/worktree.h
+++ b/worktree.h
@@ -1,6 +1,8 @@
#ifndef WORKTREE_H
#define WORKTREE_H
+#include "refs.h"
+
struct worktree {
char *path;
char *id;
@@ -70,6 +72,12 @@ extern void free_worktrees(struct worktree **);
extern const struct worktree *find_shared_symref(const char *symref,
const char *target);
+/*
+ * Similar to head_ref() for all HEADs _except_ one from the current
+ * worktree, which is covered by head_ref().
+ */
+int other_head_refs(each_ref_fn fn, void *cb_data);
+
int is_worktree_being_rebased(const struct worktree *wt, const char *target);
int is_worktree_being_bisected(const struct worktree *wt, const char *target);
--
2.11.0.157.gd943d85
next prev parent reply other threads:[~2017-08-23 12:38 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-23 12:36 [PATCH v4 00/16] Fix git-gc losing objects in multi worktree Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 01/16] revision.h: new flag in struct rev_info wrt. worktree-related refs Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 02/16] refs.c: use is_dir_sep() in resolve_gitlink_ref() Nguyễn Thái Ngọc Duy
2017-08-23 19:14 ` Stefan Beller
2017-09-06 11:08 ` Duy Nguyen
2017-09-06 17:41 ` Stefan Beller
2017-08-23 12:36 ` [PATCH v4 03/16] revision.c: refactor add_index_objects_to_pending() Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 04/16] revision.c: --indexed-objects add objects from all worktrees Nguyễn Thái Ngọc Duy
2017-08-23 19:25 ` Stefan Beller
2017-08-23 12:36 ` [PATCH v4 05/16] refs.c: refactor get_submodule_ref_store(), share common free block Nguyễn Thái Ngọc Duy
2017-08-23 19:34 ` Stefan Beller
2017-08-23 12:36 ` [PATCH v4 06/16] refs: move submodule slash stripping code to get_submodule_ref_store Nguyễn Thái Ngọc Duy
2017-09-09 5:45 ` Michael Haggerty
2017-08-23 12:36 ` [PATCH v4 07/16] refs: add refs_head_ref() Nguyễn Thái Ngọc Duy
2017-08-24 21:52 ` Junio C Hamano
2017-09-06 11:23 ` Duy Nguyen
2017-08-23 12:36 ` [PATCH v4 08/16] revision.c: use refs_for_each*() instead of for_each_*_submodule() Nguyễn Thái Ngọc Duy
2017-08-24 21:56 ` Junio C Hamano
2017-08-23 12:36 ` [PATCH v4 09/16] refs.c: move for_each_remote_ref_submodule() to submodule.c Nguyễn Thái Ngọc Duy
2017-08-23 12:36 ` [PATCH v4 10/16] refs: remove dead for_each_*_submodule() Nguyễn Thái Ngọc Duy
2017-08-23 19:45 ` Stefan Beller
2017-09-09 5:59 ` Michael Haggerty
2017-08-23 12:36 ` Nguyễn Thái Ngọc Duy [this message]
2017-08-23 19:54 ` [PATCH v4 11/16] revision.c: --all adds HEAD from all worktrees Stefan Beller
2017-09-06 11:19 ` Duy Nguyen
2017-09-06 17:43 ` Stefan Beller
2017-09-09 6:04 ` Michael Haggerty
2017-08-23 12:37 ` [PATCH v4 12/16] files-backend: make reflog iterator go through per-worktree reflog Nguyễn Thái Ngọc Duy
2017-08-24 14:13 ` Richard Maw
2017-09-09 6:30 ` Michael Haggerty
2017-08-23 12:37 ` [PATCH v4 13/16] revision.c: --reflog add HEAD reflog from all worktrees Nguyễn Thái Ngọc Duy
2017-08-23 12:37 ` [PATCH v4 14/16] rev-list: expose and document --single-worktree Nguyễn Thái Ngọc Duy
2017-08-23 20:45 ` Stefan Beller
2017-08-23 12:37 ` [PATCH v4 15/16] refs.c: remove fallback-to-main-store code get_submodule_ref_store() Nguyễn Thái Ngọc Duy
2017-09-09 6:36 ` Michael Haggerty
2017-08-23 12:37 ` [PATCH v4 16/16] refs.c: reindent get_submodule_ref_store() Nguyễn Thái Ngọc Duy
2017-09-09 6:41 ` Michael Haggerty
2017-08-25 11:21 ` [PATCH v4 00/16] Fix git-gc losing objects in multi worktree Michael J Gruber
2017-09-06 10:53 ` Duy Nguyen
2017-09-09 6:45 ` Michael Haggerty
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170823123704.16518-12-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=mhagger@alum.mit.edu \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).