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

BUG when trying to delete symbolic refs

From
Johan Herland <johan@herland.net>
Date
Oct 15, 2012, 08:50 UTC
Message-ID
<CALKQrgfnvV+1XHjeSytj+LxkAabZJK3hewxH7WT0nkX-ewOKUA@mail.gmail.com>
Hi,

At $dayjob we renamed a branch, and for a grace period, we kept the old name as a symref/alias to the new name, to give our users a window for switching. This has worked well, until we tried to remove the symref/alias. The following script demonstrates what we discovered:

 $ git --version
 git version 1.8.0.rc2.249.g6cc8227
 $ git init symref_delete_test/
 Initialized empty Git repository in .../symref_delete_test/.git/
 $ cd symref_delete_test/
 $ echo foo > foo && git add foo && git commit -m foo
 [master (root-commit) c7ae77e] foo
  1 file changed, 1 insertion(+)
  create mode 100644 foo
 $ git gc
 Counting objects: 3, done.
 Writing objects: 100% (3/3), done.
 Total 3 (delta 0), reused 0 (delta 0)
 $ cat .git/packed-refs
 # pack-refs with: peeled
 c7ae77e537138bee3f722e57e1af87a7011466cb refs/heads/master
 $ echo bar > foo && git commit -am bar
 [master 7451bf0] bar
  1 file changed, 1 insertion(+), 1 deletion(-)
 $ git symbolic-ref refs/heads/alias refs/heads/master
 $ git rev-parse master
 7451bf08b7aacedc9e88a9fa37a6c1f701071bbe
 $ git rev-parse alias
 7451bf08b7aacedc9e88a9fa37a6c1f701071bbe
 $ git branch -d alias
 Deleted branch alias (was 7451bf0).
 $ git rev-parse master
 c7ae77e537138bee3f722e57e1af87a7011466cb
 $ git rev-parse alias
 c7ae77e537138bee3f722e57e1af87a7011466cb
 $ cat .git/packed-refs
 # pack-refs with: peeled
 c7ae77e537138bee3f722e57e1af87a7011466cb refs/heads/master
 $ ls .git/refs/heads/
 alias

Basically, there is a "master" branch, and an "alias" symref to "master". When we naively try to delete the symref with "git branch -d alias", it ends up:

 - NOT deleting the "alias" symref
 - DELETING the "master" loose ref
 - NOT deleting the "master" packed ref

So, from the user perspective, "git branch -d alias" ends up resetting "master" (and "alias") back to the last time we happened to run "git gc". Needless to say, this is not quite what we had in mind...

AFAICS, there may be three possible "acceptable" outcomes when we run "git branch -d alias" in the above scenario:

 A. The symbolic ref is deleted. This is obviously what we expected...
 B. The command fails because "alias" is a symref. This would be
understandable if we don't want to teach "branch -d" about symrefs.
But then, the error message should ideally explain which command we
should use to remove the symref.
 C. The "master" ref (BOTH loose and packed versions of it) is
deleted. This would be less helpful for us, but Git would at least be
internally consistent (in that the symref would be resolved, and the
command would become "git branch -d master").
Obviously, I would advocate for option A. What say you?
Have fun! :)
...Johan
-- 
Johan Herland, <johan@herland.net>
www.herland.net
Next: René Scharfe
Message 1 of 16 in “BUG when trying to delete symbolic refs”
  1. Johan HerlandOct 15, 2012
  2. René ScharfeOct 16, 2012
  3. refs: lock symref that is to be deleted, not its targetRené Scharfe, Oct 16, 2012
  4. Junio C HamanoOct 16, 2012
  5. René ScharfeOct 18, 2012
  6. 1/5 branch: factor out check_branch_commit()René Scharfe, Oct 18, 2012
  7. 2/5 branch: factor out delete_branch_config()René Scharfe, Oct 18, 2012
  8. 3/5 branch: delete symref branch, not its targetRené Scharfe, Oct 18, 2012
  9. 4/5 branch: skip commit checks when deleting symref branchesRené Scharfe, Oct 18, 2012
  10. Junio C HamanoOct 18, 2012
  11. 0/2 Fix remaining issue when deleting symrefsJohan Herland, Oct 21, 2012
  12. 1/2 t1400-update-ref: Add test verifying bug with symrefs in delete_ref()Johan Herland, Oct 21, 2012
  13. 2/2 Fix failure to delete a packed ref through a symrefJohan Herland, Oct 21, 2012
  14. René ScharfeOct 21, 2012
  15. Junio C HamanoOct 21, 2012
  16. 5/5 branch: show targets of deleted symrefs, not sha1sRené Scharfe, Oct 18, 2012

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.