Web lists-archives.com

[PATCH 1/2] refs: Add for_each_worktree_ref for iterating over all worktree HEADs




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