git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/4] reachable.c: make reachable reflogs for all per-worktree reflogs

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Jun 1, 2016, 10:45 UTC
Message-ID
<20160601104519.16563-5-pclouds@gmail.com>
In-Reply-To
<20160601104519.16563-1-pclouds@gmail.com>

Same reason as the previous commit, this is to avoid deleting objects being referenced by per-worktree reflogs from other worktrees. "logs/HEAD" is most important. "logs/refs/bisect" should not live long enough to matter, but let's add it too for safety.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 reachable.c      |  7 ++++---
 revision.c       | 19 +++++++++++++++++++
 revision.h       |  3 +++
 t/t5304-prune.sh | 19 +++++++++++++++++++
 4 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/reachable.c b/reachable.c
index e5f9170..73915e0 100644
--- a/reachable.c
+++ b/reachable.c
@@ -156,7 +156,7 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
 				      FOR_EACH_OBJECT_LOCAL_ONLY);
 }
 
-static void add_objects_from_worktree(struct rev_info *revs)
+static void add_objects_from_worktree(struct rev_info *revs, int mark_reflog)
 {
 	struct worktree **worktrees, **p;
 
@@ -176,7 +176,8 @@ static void add_objects_from_worktree(struct rev_info *revs)
 			o = parse_object_or_die(wt->head_sha1, "HEAD");
 			add_pending_object(revs, o, "");
 		}
-
+		if (mark_reflog)
+			add_worktree_reflogs_to_pending(revs, 0, wt);
 	}
 	free_worktrees(worktrees);
 
@@ -214,7 +215,7 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
 	 * Add all objects from the in-core index file and detached
 	 * HEAD which is not included in the list above
 	 */
-	add_objects_from_worktree(revs);
+	add_objects_from_worktree(revs, mark_reflog);
 
 	cp.progress = progress;
 	cp.count = 0;
diff --git a/revision.c b/revision.c
index bbb6ff1..6a197a4 100644
--- a/revision.c
+++ b/revision.c
@@ -19,6 +19,7 @@
 #include "dir.h"
 #include "cache-tree.h"
 #include "bisect.h"
+#include "worktree.h"
 
 volatile show_early_output_fn_t show_early_output;
 
@@ -1245,6 +1246,24 @@ static int handle_one_reflog(const char *path, const struct object_id *oid,
 	return 0;
 }
 
+void add_worktree_reflogs_to_pending(struct rev_info *revs, unsigned flags,
+				     struct worktree *wt)
+{
+	struct all_refs_cb cb;
+	char *path;
+
+	cb.all_revs = revs;
+	cb.all_flags = flags;
+	path = xstrdup(worktree_git_path(wt, "logs/HEAD"));
+	if (file_exists(path))
+		handle_one_reflog(path, NULL, 0, &cb);
+	free(path);
+	path = xstrdup(worktree_git_path(wt, "logs/refs/bisect"));
+	if (file_exists(path))
+		handle_one_reflog(path, NULL, 0, &cb);
+	free(path);
+}
+
 void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
 {
 	struct all_refs_cb cb;
diff --git a/revision.h b/revision.h
index d06d098..9f3f148 100644
--- a/revision.h
+++ b/revision.h
@@ -30,6 +30,7 @@ struct log_info;
 struct string_list;
 struct saved_parents;
 struct index_state;
+struct worktree;
 
 struct rev_cmdline_info {
 	unsigned int nr;
@@ -272,6 +273,8 @@ extern void add_pending_sha1(struct rev_info *revs,
 
 extern void add_head_to_pending(struct rev_info *);
 extern void add_reflogs_to_pending(struct rev_info *, unsigned int flags);
+extern void add_worktree_reflogs_to_pending(struct rev_info *, unsigned int flags,
+					    struct worktree *);
 extern void add_index_objects_to_pending(struct rev_info *, unsigned int flags,
 					 const struct index_state *);
 
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index 683bdb0..6b1c456 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -304,4 +304,23 @@ test_expect_success 'prune: handle HEAD in multiple worktrees' '
 	test_cmp third-worktree/blob actual
 '
 
+test_expect_success 'prune: handle HEAD reflog in multiple worktrees' '
+	(
+		cd third-worktree &&
+		git config core.logAllRefUpdates true &&
+		echo "HEAD{1} blob for third-worktree" >blob &&
+		git add blob &&
+		git commit -m "second commit in third" &&
+		cp blob expected &&
+		echo "HEAD{0} blob for third-worktree" >blob &&
+		git add blob &&
+		git commit -m "third commit in third" &&
+		git show HEAD@{1}:blob >actual &&
+		test_cmp expected actual
+	) &&
+	git prune --expire=now &&
+	git -C third-worktree show HEAD@{1}:blob >actual &&
+	test_cmp third-worktree/expected actual
+'
+
 test_done
-- 
2.8.2.524.g6ff3d78
Previous: Nguyễn Thái Ngọc DuyNext: Michael Haggerty
Message 19 of 25 in “git gc and worktrees”
  1. Johannes SixtMay 31, 2016
  2. Duy NguyenMay 31, 2016
  3. Jeff KingMay 31, 2016
  4. Johannes SixtJun 1, 2016
  5. Michael HaggertyJun 1, 2016
  6. Junio C HamanoJun 1, 2016
  7. Michael HaggertyJun 1, 2016
  8. Junio C HamanoJun 1, 2016
  9. Michael HaggertyJun 2, 2016
  10. Junio C HamanoJun 3, 2016
  11. 0/4 Fix prune/gc problem with multiple worktreesNguyễn Thái Ngọc Duy, Jun 1, 2016
  12. 1/4 revision.c: move read_cache() out of add_index_objects_to_pending()Nguyễn Thái Ngọc Duy, Jun 1, 2016
  13. 2/4 reachable.c: mark reachable objects in index from all worktreesNguyễn Thái Ngọc Duy, Jun 1, 2016
  14. Eric SunshineJun 1, 2016
  15. Duy NguyenJun 2, 2016
  16. David TurnerJun 1, 2016
  17. Duy NguyenJun 2, 2016
  18. 3/4 reachable.c: mark reachable detached HEAD from all worktreesNguyễn Thái Ngọc Duy, Jun 1, 2016
  19. 4/4 reachable.c: make reachable reflogs for all per-worktree reflogsNguyễn Thái Ngọc Duy, Jun 1, 2016
  20. Michael HaggertyJun 1, 2016
  21. Jeff KingJun 1, 2016
  22. Junio C HamanoJun 1, 2016
  23. Duy NguyenJun 2, 2016
  24. Michael HaggertyJun 2, 2016
  25. Junio C HamanoJun 2, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.