>From 3f8015efdcc122e0d345baeb5f1f0485a9f0fcd8 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar <manishearth@xxxxxxxxx> Date: Tue, 16 May 2017 16:46:36 -0700 Subject: [PATCH 2/2] reachable: Add HEADs of all worktrees to reachability analysis * reachable.c: mark_reachable_objects: Include other worktrees Signed-off-by: Manish Goregaokar <manishearth@xxxxxxxxx> --- reachable.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/reachable.c b/reachable.c index d0199ca..439708e 100644 --- a/reachable.c +++ b/reachable.c @@ -178,6 +178,9 @@ 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); + /* worktrees are not included in either */ + for_each_worktree_ref(add_one_ref, revs); + /* Add all reflog info */ if (mark_reflog) add_reflogs_to_pending(revs, 0); -- 2.10.1 -Manish Goregaokar On Tue, May 16, 2017 at 5:07 PM, Manish Goregaokar <manishearth@xxxxxxxxx> wrote: > Git prune will happily delete commits checked out in other worktrees. > This is probably not desired. > > (Tabs have been converted to spaces in this email sadly, because GMail > garbles these. This should suffice for review, and I'll send the patch > as an attachment or in some other form when done so that it can be > cleanly applied. Let me know if this won't work.) > > > Thanks! > > Patch 1/2 follows (based on maint) > > ----- > > From c3657cd0bb61921053fad4dd669589780881c574 Mon Sep 17 00:00:00 2001 > From: Manish Goregaokar <manishearth@xxxxxxxxx> > Date: Tue, 16 May 2017 16:46:00 -0700 > Subject: refs: Add for_each_worktree_ref for iterating over all worktree HEADs > > To ensure that `git prune` does not remove refs checked out > in other worktrees, we need to include these HEADs in the > set of roots. This adds the iteration function necessary > to do this. > > Signed-off-by: Manish Goregaokar <manishearth@xxxxxxxxx> > --- > refs.c | 16 ++++++++++++++++ > refs.h | 1 + > 2 files changed, 17 insertions(+) > > diff --git a/refs.c b/refs.c > index 2d71774..27e0b60 100644 > --- a/refs.c > +++ b/refs.c > @@ -3,6 +3,7 @@ > */ > > #include "cache.h" > +#include "commit.h" > #include "lockfile.h" > #include "refs.h" > #include "refs/refs-internal.h" > @@ -1157,6 +1158,21 @@ int head_ref(each_ref_fn fn, void *cb_data) > return head_ref_submodule(NULL, fn, cb_data); > } > > +int for_each_worktree_ref(each_ref_fn fn, void *cb_data) > +{ > + int i, flag, retval; > + struct object_id oid; > + struct worktree **worktrees = get_worktrees(GWT_SORT_LINKED); > + for (i = 0; worktrees[i]; i++) { > + struct commit* commit = > lookup_commit_reference(worktrees[i]->head_sha1); > + oid = commit->object.oid; > + if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag)) { > + if (retval = fn("HEAD", &oid, flag, cb_data)) > + return retval; > + } > + } > +} > + > /* > * Call fn for each reference in the specified submodule for which the > * refname begins with prefix. If trim is non-zero, then trim that > diff --git a/refs.h b/refs.h > index 9fbff90..425a853 100644 > --- a/refs.h > +++ b/refs.h > @@ -192,6 +192,7 @@ typedef int each_ref_fn(const char *refname, > * stop the iteration. > */ > int head_ref(each_ref_fn fn, void *cb_data); > +int for_each_worktree_ref(each_ref_fn fn, void *cb_data); > int for_each_ref(each_ref_fn fn, void *cb_data); > int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data); > int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, > -- > 2.10.1