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

Tag peeling peculiarities

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Mar 13, 2013, 14:59 UTC
Message-ID
<51409439.5090001@alum.mit.edu>

I have been working on the pack-refs code [1] and noticed what looks like a problem with the handling of peeled refs in the packed-refs file and in the reference cache. In particular, the peeled versions of tags outside of refs/tags are *not* stored in packed-refs, but after the packed-refs file is read it is assumed that such tags cannot be peeled.

It is clear that annotated tags want to live under refs/tags, but there are some ways to create them in other places (see below). It is not clear to me whether the prohibition of tags outside of refs/tags should be made more airtight or whether the peeling of tags outside of refs/tags should be fixed.

Example:
~/tmp$ git init foo
Initialized empty Git repository in /home/mhagger/tmp/foo/.git/
~/tmp$ cd foo
~/tmp/foo$ git config user.name 'Lou User'
~/tmp/foo$ git config user.email 'luser@exaple.com'
~/tmp/foo$
~/tmp/foo$ git commit --allow-empty -m "Initial commit"
[master (root-commit) 7e80ddd] Initial commit
~/tmp/foo$ git tag -m footag footag
~/tmp/foo$
~/tmp/foo$ # This is prohibited:
~/tmp/foo$ git update-ref refs/heads/foobranch $(git rev-parse footag)
error: Trying to write non-commit object
d9cdc84dd156ff83799f5226794711fbb2c8273a to branch refs/heads/foobranch
fatal: Cannot update the ref 'refs/heads/foobranch'.
~/tmp/foo$
~/tmp/foo$ # But this is allowed:
~/tmp/foo$ git update-ref refs/remotes/foo/bar $(git rev-parse footag)
~/tmp/foo$
~/tmp/foo$ # So is this:
~/tmp/foo$ git update-ref refs/yak/foobranch $(git rev-parse footag)
~/tmp/foo$
~/tmp/foo$ # Before packing, all tags are available in peel versions:
~/tmp/foo$ git show-ref -d
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/heads/master
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/remotes/foo/bar
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/remotes/foo/bar^{}
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/tags/footag
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/tags/footag^{}
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/yak/foobranch
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/yak/foobranch^{}
~/tmp/foo$
~/tmp/foo$ git pack-refs --all
~/tmp/foo$
~/tmp/foo$ # After packing, tags outside of refs/tags are not peeled any
more:
~/tmp/foo$ git show-ref -d
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/heads/master
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/remotes/foo/bar
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/tags/footag
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/tags/footag^{}
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/yak/foobranch
~/tmp/foo$
~/tmp/foo$ # Peeling the tags via "tag^0" works even after packing:
~/tmp/foo$ git rev-parse refs/yak/foobranch^0
7e80ddd68f0225a0ea221f7cddbacf050be5a265
~/tmp/foo$
~/tmp/foo$ # Here is another way to create a tag outside of refs/tags:
~/tmp/foo$ cd ..
~/tmp$ git clone foo foo-clone
Cloning into 'foo-clone'...
done.
~/tmp$ cd foo-clone
~/tmp/foo-clone$ git config --add remote.origin.fetch
'+refs/tags/*:refs/remotes/origin/tags/*'
~/tmp/foo-clone$ git fetch
From /home/mhagger/tmp/foo
 * [new tag]         footag     -> origin/tags/footag
~/tmp/foo-clone$
~/tmp/foo-clone$ # Again, the tag outside of refs/tags are not peeled
correctly after packing:
~/tmp/foo-clone$ git pack-refs --all
~/tmp/foo-clone$ git show-ref -d
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/heads/master
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/remotes/origin/HEAD
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/remotes/origin/master
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/remotes/origin/tags/footag
d9cdc84dd156ff83799f5226794711fbb2c8273a refs/tags/footag
7e80ddd68f0225a0ea221f7cddbacf050be5a265 refs/tags/footag^{}
Michael

[1] I am trying to fix the problem that peeled refs are lost whenever a packed reference is deleted.

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
Next: Michael Haggerty
Message 1 of 17 in “Tag peeling peculiarities”
  1. Michael HaggertyMar 13, 2013
  2. Michael HaggertyMar 13, 2013
  3. Junio C HamanoMar 13, 2013
  4. Jeff KingMar 13, 2013
  5. Michael HaggertyMar 14, 2013
  6. Jeff KingMar 14, 2013
  7. Jeff KingMar 14, 2013
  8. Junio C HamanoMar 14, 2013
  9. Michael HaggertyMar 14, 2013
  10. Jeff KingMar 14, 2013
  11. Michael HaggertyMar 15, 2013
  12. Junio C HamanoMar 15, 2013
  13. Michael HaggertyMar 16, 2013
  14. Jeff KingMar 16, 2013
  15. Michael HaggertyMar 16, 2013
  16. Michael HaggertyMar 18, 2013
  17. Jeff KingMar 22, 2013

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.