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

[PATCH 2/5] pack-refs: prune top-level refs like "refs/foo"

From
Jeff King <peff@peff.net>
Date
Aug 23, 2014, 05:27 UTC
Message-ID
<20140823052707.GB18075@peff.net>
In-Reply-To
<20140823052334.GA17813@peff.net>

After we have packed all refs, we prune any loose refs that correspond to what we packed. We do so by first taking a lock with lock_ref_sha1, and then deleting the loose ref file.

However, lock_ref_sha1 will refuse to take a lock on any refs that exist at the top-level of the "refs/" directory, and we skip pruning the ref. This is almost certainly not what we want to happen here. The criteria to be pruned should not differ from that to be packed; if a ref makes it to prune_ref, it's because we want it both packed and pruned (if there are refs you do not want to be packed, they should be omitted much earlier by pack_ref_is_possible, which we do in this case if --all is not given).

We can fix this by switching to lock_any_ref_for_update. This behaves exactly the same with the exception of this top-level check.

Signed-off-by: Jeff King <peff@peff.net>
---
 refs.c               | 3 ++-
 t/t3210-pack-refs.sh | 7 +++++++
 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/refs.c b/refs.c
index 27927f2..82e5b1b 100644
--- a/refs.c
+++ b/refs.c
@@ -2387,7 +2387,8 @@ static void try_remove_empty_parents(char *name)
 /* make sure nobody touched the ref, and unlink */
 static void prune_ref(struct ref_to_prune *r)
 {
-	struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);
+	struct ref_lock *lock = lock_any_ref_for_update(r->name, r->sha1,
+							0, NULL);
 
 	if (lock) {
 		unlink_or_warn(git_path("%s", r->name));
diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh
index 1a2080e..3a017bf 100755
--- a/t/t3210-pack-refs.sh
+++ b/t/t3210-pack-refs.sh
@@ -151,4 +151,11 @@ test_expect_success 'delete ref while another dangling packed ref' '
 	test_cmp /dev/null result
 '
 
+test_expect_success 'pack ref directly below refs/' '
+	git update-ref refs/top HEAD &&
+	git pack-refs --all --prune &&
+	grep refs/top .git/packed-refs &&
+	test_path_is_missing .git/refs/top
+'
+
 test_done
-- 
2.1.0.346.ga0367b9
Previous: Jeff KingNext: Jeff King
Message 3 of 14 in “fix pack-refs pruning of refs/foo”
  1. 0/5 fix pack-refs pruning of refs/fooJeff King, Aug 23, 2014
  2. 1/5 git-prompt: do not look for refs/stash in $GIT_DIRJeff King, Aug 23, 2014
  3. 2/5 pack-refs: prune top-level refs like "refs/foo"Jeff King, Aug 23, 2014
  4. 3/5 fast-import: clean up pack_data pointer in end_packfileJeff King, Aug 23, 2014
  5. Ronnie SahlbergAug 25, 2014
  6. Jeff KingAug 25, 2014
  7. 4/5 fast-import: fix buffer overflow in dump_tagsJeff King, Aug 23, 2014
  8. Ronnie SahlbergAug 25, 2014
  9. 5/5 fast-import: stop using lock_ref_sha1Jeff King, Aug 23, 2014
  10. Ronnie SahlbergAug 25, 2014
  11. Michael HaggertyAug 23, 2014
  12. Jeff KingAug 23, 2014
  13. Ronnie SahlbergAug 25, 2014
  14. Jeff KingAug 25, 2014

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.