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

Re: [PATCH 1/3] retain reflogs for deleted refs

From
Jeff King <peff@peff.net>
Date
Jul 20, 2012, 15:44 UTC
Message-ID
<20120720154403.GB2862@sigill.intra.peff.net>
In-Reply-To
<50092993.6010203@alum.mit.edu>
On Fri, Jul 20, 2012 at 11:49:07AM +0200, Michael Haggerty wrote:
Show 23 quoted lines
> >This patch moves reflog entries into a special "graveyard"
> >namespace, and appends a tilde (~) character, which is
> >not allowed in a valid ref name. This means that the deleted
> >reflogs of these refs:
> >
> >    refs/heads/a
> >    refs/heads/a/b
> >    refs/heads/a/b/c
> >
> >will be stored in:
> >
> >    logs/graveyard/refs/heads/a~
> >    logs/graveyard/refs/heads/a/b~
> >    logs/graveyard/refs/heads/a/b/c~
> >
> >Putting them in the graveyard namespace ensures they will
> >not conflict with live refs, and the tilde prevents D/F
> >conflicts within the graveyard namespace.
> 
> I agree with Junio that long-term, it would be nice to allow
> references "foo" and "foo/bar" to exist simultaneously.  To get
> there, we would have to redesign the mapping between reference names
> and the filenames used for the references and for the reflogs.

Yes, I would really like that, as it could make the alternate namespace go away, which is the source of about half the code in my patches (i.e., we would only need to loosen the reflog reading code to handle reflogs that do not have a matching ref).

But I fear that the fallouts from that will be much, much larger. Even with just this change, older versions of git will be slightly unhappy (e.g., you will get some extra warnings during fsck and reflog expiration about these reflogs). But changing the on-disk representation of the refs namespace will mean a totally new representation of locking. That's going to break old versions of git completely, and possibly even some user scripts.

Show 9 quoted lines
> The easiest thing would be to mark files and directories differently;
> something like
> 
>     $GIT_DIR/{,logs/}refs/heads/a/b/c~
> [...]
> The first convention, "logs/refs/heads/a/b/c~" is not usable because
> a reflog for a dead reference with this name would conflict with a
> reflog for a live reference "heads/a" or "heads/a/b" that uses the
> current filename convention.

Right. That's what I started with, then created the graveyard hierarchy to avoid conflicts between the "old" namespace (that cannot handle D/F conflicts) and the "new" one (that can, because it represents files and directories differently).

Show 7 quoted lines
> or
> 
>     $GIT_DIR/{,logs/}refs/heads~/a~/b~/c
> 
> i.e., munging either directory or file names to strings that are
> illegal in refnames such that it is unambiguous from the name whether
> a path is a file or directory.

This one can have conflicts in the opposite direction if you don't have any directories. E.g., you have $GIT_DIR/foo, a deleted ref, which has no tildes because it has no directories in the path. But you want to create foo/bar under the "old" system, which cannot happen (under the new system, it is fine, but the point of this exercise is to overlay the old and new systems).

That may be an OK tradeoff. We are restrictive in what goes into the top-level. Although I notice that you did not mark "refs" in the above example. So you could have the same problem with "refs/stash", for example. Again, though, we don't tend to have arbitrary data at the top-level (and I think refs/stash gets special cased in a couple places already). So it might be an acceptable limitation.

If we want to be pedantic, my patch causes conflicts for top-level refs called "graveyard" (although I know we have talked about restricting top-level refs to [A-Z_-], I don't recall if that has actually happened).

> And *if* we did that, then we wouldn't need a separate "graveyard"
> namespace, would we?  The reflogs for dead references could live
> among those for living references.

Right, assuming the limitation above is OK. But note that it doesn't really save us any code. We still have to convert between refnames and graveyard versions. _Eventually_ if the refnames were all converted, that code could go away.

> But the second convention, "logs/refs/heads~/a~/b~/c, cannot conflict
> with current reflog files.  And it would be a step towards allowing
> "foo" and "foo/bar" at the same time.  What do you think about using
> a convention like this instead of the one that you proposed?

I think it's reasonable. As I said, it doesn't save any code _now_, but since I am pulling a convention out of thin air, it might as well be one that has a possibility of converging in the future (all other things being equal, of course; I do find marking the directories a little uglier to read, but that is mostly because of the tilde).

Show 7 quoted lines
> Another minor concern is the choice of trailing tilde in the file or
> directory names.  Given that emacs creates backup files by appending
> a tilde to the filename, (1) it would be easy to inadvertently create
> such files, which git might try to interpret as reflogs and (2) there
> might be tools that innately "know" to skip such files in their
> processing. ack-grep, a replacement for grep, is an example that
> springs to mind.

The use of "~" for backup files was actually something that made me choose it, since these are, after all, backups of the reflog. But they are probably more precious than editor backup files, so the special treatment they're given by other programs is probably not desirable.

Show 8 quoted lines
> Other possibilities (according to git-check-ref-format(1)):
> 
>     refs/.heads/.a/.b/c
>     refs/heads./a./b./c (problematic on some Windows filesystems?)
>     refs/heads../a../b../c
>     refs/heads~dir/a~dir/b~dir/c (or some other suffix)
>     refs/heads..a..b..c (not recommended because it flattens
> directory hierarchy)

I don't like leading-dot, because those files are also often skipped by directory traversal of some programs (and certainly they are confusing to work with if you try to use "ls" to debug your $GIT_DIR/logs directory). Trailing dot is less ugly to me, but I do wonder about its special meaning as an extension separator. Double-dots just look gross.

Note that we have a few other magic characters available, too. Colon is probably the least offensive (metacharacters like *, ?, and [ just make things unnecessarily painful for shell users).

So I think a suffix like ":d" is probably the least horrible.
-Peff
Previous: Michael HaggertyNext: Johannes Sixt
Message 31 of 52 in “Feature request: fetch --prune by default”
  1. Alexey MuranovJul 19, 2012
  2. Jeff KingJul 19, 2012
  3. Dan JohnsonJul 19, 2012
  4. Stefan HallerJul 19, 2012
  5. Junio C HamanoAug 16, 2012
  6. Jeff KingAug 21, 2012
  7. Sam RobertsJun 20, 2013
  8. Alexey MuranovJul 19, 2012
  9. Konstantin KhomoutovJul 19, 2012
  10. Alexey MuranovJul 19, 2012
  11. Alexey MuranovJul 19, 2012
  12. Johannes SixtJul 20, 2012
  13. Alexey MuranovJul 20, 2012
  14. Junio C HamanoAug 16, 2012
  15. Alexey MuranovJul 19, 2012
  16. Dan JohnsonJul 19, 2012
  17. Alexey MuranovJul 19, 2012
  18. 0/3 reflog graveyardJeff King, Jul 19, 2012
  19. 1/3 retain reflogs for deleted refsJeff King, Jul 19, 2012
  20. Alexey MuranovJul 19, 2012
  21. Jeff KingJul 20, 2012
  22. Alexey MuranovJul 20, 2012
  23. Junio C HamanoJul 19, 2012
  24. Jeff KingJul 20, 2012
  25. Jeff KingJul 20, 2012
  26. Junio C HamanoJul 20, 2012
  27. Junio C HamanoJul 20, 2012
  28. Jeff KingJul 20, 2012
  29. Junio C HamanoAug 16, 2012
  30. Michael HaggertyJul 20, 2012
  31. Jeff KingJul 20, 2012
  32. Johannes SixtJul 20, 2012
  33. Jeff KingJul 20, 2012
  34. Alexey MuranovJul 22, 2012
  35. Nguyen Thai Ngoc DuyJul 26, 2012
  36. Alexey MuranovJul 26, 2012
  37. Matthieu MoyJul 26, 2012
  38. Jeff KingJul 26, 2012
  39. Alexey MuranovJul 26, 2012
  40. Junio C HamanoJul 26, 2012
  41. Jeff KingJul 26, 2012
  42. Alexey MuranovJul 22, 2012
  43. Alexey MuranovJul 22, 2012
  44. Jeff KingJul 22, 2012
  45. Alexey MuranovJul 22, 2012
  46. Jeff KingJul 22, 2012
  47. Johannes SixtJul 20, 2012
  48. 2/3 teach sha1_name to look in graveyard reflogsJeff King, Jul 19, 2012
  49. Junio C HamanoJul 19, 2012
  50. Jeff KingJul 20, 2012
  51. Junio C HamanoJul 22, 2012
  52. 3/3 add tests for reflogs of deleted refsJeff King, Jul 19, 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.