# [RFC 3/3] Change naming convention for the reflog graveyard

21 messages from 2012-08-18 to 2012-08-21. Participants: mhagger@alum.mit.edu, Junio C Hamano, Alexey Muranov, Michael Haggerty, Jeff King.
Thread: https://gitlist.dev/t/31279

## mhagger@alum.mit.edu, 2012-08-18 17:14

Subject: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <1345310086-20089-1-git-send-email-mhagger@alum.mit.edu>
URL: https://gitlist.dev/e/1345310086-20089-1-git-send-email-mhagger%40alum.mit.edu
In-Reply-To: <20120719213311.GA20385@sigill.intra.peff.net>

```
From: Michael Haggerty <mhagger@alum.mit.edu>

On 08/17/2012 01:29 AM, Junio C Hamano wrote:> Junio C Hamano <gitster@pobox.com> writes:
>> I like the general direction.  Perhaps a long distant future
>> direction could be to also use the same trick in the ref namespace
>> so that we can have 'next' branch itself, and 'next/foo', 'next/bar'
>> forks that are based on the 'next' branch at the same time (it
>> obviously is a totally unrelated topic)?
> 
> I notice that I was responsible for making this topic veer in the
> wrong direction by bringing up a new feature "having 'next' and
> 'next/bar' at the same time" which nobody asked.  Perhaps we can
> drop that for now to simplify the scope of the topic, to bring the
> log graveyard back on track?

Given that a flag day would anyway be required to add a d/f-tolerant
system, I could live with a separate "graveyard" namespace as
originally proposed by Jeff.

However, I still think that as long as we are making a jump, we could
try to land closer to the ultimate destination.  So here are some
patches that apply on top of Jeff's to show what I mean.  (Please also
note that I made some technical comments about Jeff's patches in an
earlier email.)

The first two patches fix a breakage that I see when I apply Jeff's
patches to master.

The third changes the implementation of refname_to_graveyard_reflog()
and graveyard_reflog_to_refname() and touches up some test cases.  It
changes the naming convention for dead references to

    "$GIT_DIR/logs/refs~d/heads~d/foo~d/bar~d/baz~f"

I.e., the dead reflogs are stored closer to the living.  It is not
obvious whether the "refs" part of the name should be munged to
"refs~d" as I have done, or left unmunged.  The argument in favor of
munging is that the algorithm is more uniform.  On the other hand,
extending the same scheme to loose references would produce filenames
like

    "$GIT_DIR/refs~d/heads~d/foo~d/bar~d/baz~f"

or maybe they should be nested inside of the refs directory like

    "$GIT_DIR/refs/refs~d/heads~d/foo~d/bar~d/baz~f"

(which would also give a better place to store top-level reference
names).

I structured the patches to apply on top of Jeff's for presentation
purposes, but if they are desired it would of course make more sense
to squash his and mine together in the obvious way.

I am a little bit worried that there are other test cases that use
"git prune" in the belief that it will remove all commits that were
referred to by deleted references.  The test suite runs cleanly for me
with these patches, but before they are integrated we should audit the
places where the test suite calls to "git prune" to make sure that
they are still testing what they think.

Michael Haggerty (3):
  t9300: format test in modern style prior to modifying it
  Delete reflogs for dead references to allow pruning
  Change naming convention for the reflog graveyard

 refs.c                               | 31 ++++++++++++++++++++++++-------
 t/t7701-repack-unpack-unreachable.sh |  4 ++--
 t/t9300-fast-import.sh               | 13 +++++++------
 3 files changed, 33 insertions(+), 15 deletions(-)

-- 
1.7.11.3

```

## mhagger@alum.mit.edu, 2012-08-18 17:14

Subject: [RFC 1/3] t9300: format test in modern style prior to modifying it
Message-ID: <1345310086-20089-2-git-send-email-mhagger@alum.mit.edu>
URL: https://gitlist.dev/e/1345310086-20089-2-git-send-email-mhagger%40alum.mit.edu
In-Reply-To: <1345310086-20089-1-git-send-email-mhagger@alum.mit.edu>

```
From: Michael Haggerty <mhagger@alum.mit.edu>


Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 t/t9300-fast-import.sh | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 2fcf269..266ae30 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1698,12 +1698,12 @@ M 160000 $SUBLAST sub
 
 INPUT_END
 
-test_expect_success \
-	'P: verbatim SHA gitlinks' \
-	'git branch -D sub &&
-	 git gc && git prune &&
-	 git fast-import <input &&
-	 test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)'
+test_expect_success 'P: verbatim SHA gitlinks' '
+	git branch -D sub &&
+	git gc && git prune &&
+	git fast-import <input &&
+	test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)
+'
 
 test_tick
 cat >input <<INPUT_END
-- 
1.7.11.3

```

## mhagger@alum.mit.edu, 2012-08-18 17:14

Subject: [RFC 2/3] Delete reflogs for dead references to allow pruning
Message-ID: <1345310086-20089-3-git-send-email-mhagger@alum.mit.edu>
URL: https://gitlist.dev/e/1345310086-20089-3-git-send-email-mhagger%40alum.mit.edu
In-Reply-To: <1345310086-20089-1-git-send-email-mhagger@alum.mit.edu>

```
From: Michael Haggerty <mhagger@alum.mit.edu>

This test is broken by "retain reflogs for deleted refs".  Explicitly
delete the reflogs in the graveyard to allow the corresponding commits
to be pruned.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---

Probably there should be a "git reflog" subcommand to do this.

 t/t9300-fast-import.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 266ae30..dc6c67d 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1700,6 +1700,7 @@ INPUT_END
 
 test_expect_success 'P: verbatim SHA gitlinks' '
 	git branch -D sub &&
+	rm -rf .git/logs/graveyard &&
 	git gc && git prune &&
 	git fast-import <input &&
 	test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)
-- 
1.7.11.3

```

## mhagger@alum.mit.edu, 2012-08-18 17:14

Subject: [RFC 3/3] Change naming convention for the reflog graveyard
Message-ID: <1345310086-20089-4-git-send-email-mhagger@alum.mit.edu>
URL: https://gitlist.dev/e/1345310086-20089-4-git-send-email-mhagger%40alum.mit.edu
In-Reply-To: <1345310086-20089-1-git-send-email-mhagger@alum.mit.edu>

```
From: Michael Haggerty <mhagger@alum.mit.edu>

Store reflogs for dead references among those for live references, in
a scheme that could in the future be extended to prevent
file/directory conflicts for live reference names, as well.  Store the
reflog for a dead reference "refs/foo/bar/baz" in file
"$GIT_DIR/logs/refs~d/heads~d/foo~d/bar~d/baz~f", where the suffix
"~d" is appended to "directory" names and "~f" is append to "file"
names.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 refs.c                               | 31 ++++++++++++++++++++++++-------
 t/t7701-repack-unpack-unreachable.sh |  4 ++--
 t/t9300-fast-import.sh               |  2 +-
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/refs.c b/refs.c
index 551a0f9..4797b20 100644
--- a/refs.c
+++ b/refs.c
@@ -2580,20 +2580,37 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
 
 char *refname_to_graveyard_reflog(const char *ref)
 {
-	return git_path("logs/graveyard/%s~", ref);
+	static struct strbuf buf = STRBUF_INIT;
+
+	const char *p, *slash;
+	strbuf_reset(&buf);
+	for (p = ref; (slash = strchr(p, '/')); p = slash + 1) {
+		strbuf_add(&buf, p, slash - p);
+		strbuf_addstr(&buf, "~d/");
+	}
+	strbuf_addstr(&buf, p);
+	strbuf_addstr(&buf, "~f");
+
+	return git_path("logs/%s", buf.buf);
 }
 
 char *graveyard_reflog_to_refname(const char *log)
 {
 	static struct strbuf buf = STRBUF_INIT;
 
-	if (!prefixcmp(log, "graveyard/"))
-		log += 10;
-
+	const char *p, *slash;
 	strbuf_reset(&buf);
-	strbuf_addstr(&buf, log);
-	if (buf.len > 0 && buf.buf[buf.len-1] == '~')
-		strbuf_setlen(&buf, buf.len - 1);
+	for (p = log; (slash = strchr(p, '/')); p = slash + 1) {
+		if (slash - p > 2 && slash[-2] == '~' && slash[-1] == 'd')
+			strbuf_add(&buf, p, slash - p - 2);
+		else
+			strbuf_add(&buf, p, slash - p);
+		strbuf_addch(&buf, '/');
+	}
+
+	strbuf_addstr(&buf, p);
+	if (buf.len > 2 && !strcmp(buf.buf + buf.len - 2, "~f"))
+		strbuf_setlen(&buf, buf.len - 2);
 
 	return buf.buf;
 }
diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh
index c06b715..f8d02db 100755
--- a/t/t7701-repack-unpack-unreachable.sh
+++ b/t/t7701-repack-unpack-unreachable.sh
@@ -40,7 +40,7 @@ test_expect_success '-A with -d option leaves unreachable objects unpacked' '
 	# now expire the reflog, while keeping reachable ones but expiring
 	# unreachables immediately; also remove any graveyard reflogs
 	# from deleted branches that would keep things reachable
-	rm -rf .git/logs/graveyard &&
+	rm -rf .git/logs/*~? &&
 	test_tick &&
 	sometimeago=$(( $test_tick - 10000 )) &&
 	git reflog expire --expire=$sometimeago --expire-unreachable=$test_tick --all &&
@@ -78,7 +78,7 @@ test_expect_success '-A without -d option leaves unreachable objects packed' '
 	test 1 = $(ls -1 .git/objects/pack/pack-*.pack | wc -l) &&
 	packfile=$(ls .git/objects/pack/pack-*.pack) &&
 	git branch -D transient_branch &&
-	rm -rf .git/logs/graveyard &&
+	rm -rf .git/logs/*~? &&
 	test_tick &&
 	git repack -A -l &&
 	test ! -f "$fsha1path" &&
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index dc6c67d..8d88f5f 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1700,7 +1700,7 @@ INPUT_END
 
 test_expect_success 'P: verbatim SHA gitlinks' '
 	git branch -D sub &&
-	rm -rf .git/logs/graveyard &&
+	rm -rf .git/logs/*~? &&
 	git gc && git prune &&
 	git fast-import <input &&
 	test $(git rev-parse --verify subuse2) = $(git rev-parse --verify subuse1)
-- 
1.7.11.3

```

## Junio C Hamano, 2012-08-18 20:39

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7vboi8rl2q.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vboi8rl2q.fsf%40alter.siamese.dyndns.org
In-Reply-To: <1345310086-20089-1-git-send-email-mhagger@alum.mit.edu>

```
mhagger@alum.mit.edu writes:

> Given that a flag day would anyway be required to add a d/f-tolerant
> system, I could live with a separate "graveyard" namespace as
> originally proposed by Jeff.
>
> However, I still think that as long as we are making a jump, we could
> try to land closer to the ultimate destination.

Do we _know_ already what the "ultimate destination" looks like?  

If the answer is yes, then I agree, but otherwise, I doubt it is a
good idea to introduce unnecessary complexity to the system that may
have to be ripped out and redone.

I didn't get the impression that we know the "ultimate destination"
from the previous discussion, especially if we discount the tangent
around "having next and next/foo at the same time" which was on
nobody's wish, but I may be misremembering things.

```

## Alexey Muranov, 2012-08-18 21:11

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <B88EFDF9-0AB6-49AC-87E5-7515B99AE601@gmail.com>
URL: https://gitlist.dev/e/B88EFDF9-0AB6-49AC-87E5-7515B99AE601%40gmail.com
In-Reply-To: <7vboi8rl2q.fsf@alter.siamese.dyndns.org>

```
On 18 Aug 2012, at 22:39, Junio C Hamano wrote:

> Do we _know_ already what the "ultimate destination" looks like?  
> 
> If the answer is yes, then I agree, but otherwise, I doubt it is a
> good idea to introduce unnecessary complexity to the system that may
> have to be ripped out and redone.
> 
> I didn't get the impression that we know the "ultimate destination"
> from the previous discussion, especially if we discount the tangent
> around "having next and next/foo at the same time" which was on
> nobody's wish, but I may be misremembering things.

Excuse me if i miss something again, but i might be willing to discuss the "ultimate destination".  Could you possibly state in simple terms what the problem with determining the "ultimate destination" is?  I hope my opinion might be useful because i do not know anything about the actual implementation of Git, but for a while i thought i was understanding it's intended mathematical model, until i ran into unexpected for me default behavior of not pruning when fetching.

To just give a quick idea of my ideas, i thought that 'fetching' in Git was an inevitable evil that stands apart from other operations and is necessary only because the computer communication on Earth is not sufficiently developed to keep all Git repositories constantly in sync, and because one might prefer to work with a somewhat dated snapshot of a remote than with the constantly changing current version. I thought "snapshot" could be a good alternative name for "fetch".

-Alexey.
```

## Junio C Hamano, 2012-08-19 00:02

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7vehn3rbom.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vehn3rbom.fsf%40alter.siamese.dyndns.org
In-Reply-To: <B88EFDF9-0AB6-49AC-87E5-7515B99AE601@gmail.com>

```
Alexey Muranov <alexey.muranov@gmail.com> writes:

> On 18 Aug 2012, at 22:39, Junio C Hamano wrote:
>
>> Do we _know_ already what the "ultimate destination" looks like?  
>> 
>> If the answer is yes, then I agree, but otherwise, I doubt it is a
>> good idea to introduce unnecessary complexity to the system that may
>> have to be ripped out and redone.
>> 
>> I didn't get the impression that we know the "ultimate destination"
>> from the previous discussion, especially if we discount the tangent
>> around "having next and next/foo at the same time" which was on
>> nobody's wish, but I may be misremembering things.
>
> Excuse me if i miss something again, but i might be willing to
> discuss the "ultimate destination".  Could you possibly state in
> simple terms what the problem with determining the "ultimate
> destination" is?

Decide if it makes sense to break backward compatibility of loose
ref representation merely to support having a branch "next" and
another branch "next/foo" in the same repository, and if it does,
what the new loose ref representation looks like.

> I hope my opinion might be useful because i do not know anything
> about the actual implementation of Git,...

That sounds like contradiction.

> To just give a quick idea of my ideas, i thought that 'fetching'
> in Git was an inevitable evil that stands apart from other
> operations and is necessary only because the computer
> communication on Earth is not sufficiently developed to keep all
> Git repositories constantly in sync,...

It is a feature, not a symptom of an insufficiently developed
technology, that I do not have to know what random tweaks and
experiments are done in repositories of 47 thousands people who
clone from me, and I can sync with any one of them only when I know
there is something worth looking at when I say "git fetch".

```

## Alexey Muranov, 2012-08-19 07:07

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <AA92444F-B359-4C46-A1E2-13049C44C6D9@gmail.com>
URL: https://gitlist.dev/e/AA92444F-B359-4C46-A1E2-13049C44C6D9%40gmail.com
In-Reply-To: <7vehn3rbom.fsf@alter.siamese.dyndns.org>

```
On 19 Aug 2012, at 02:02, Junio C Hamano wrote:

> Alexey Muranov <alexey.muranov@gmail.com> writes:
> 
>> I hope my opinion might be useful because i do not know anything
>> about the actual implementation of Git,...
> 
> That sounds like contradiction.

I think that the implementation (the code), the model, and the interface are independent.
On the top level, for example, one does not need to know how commit storage is optimized, it is enough to understand that each commit is a snapshot of a subtree in a file directory.

>> To just give a quick idea of my ideas, i thought that 'fetching'
>> in Git was an inevitable evil that stands apart from other
>> operations and is necessary only because the computer
>> communication on Earth is not sufficiently developed to keep all
>> Git repositories constantly in sync,...
> 
> It is a feature, not a symptom of an insufficiently developed
> technology, that I do not have to know what random tweaks and
> experiments are done in repositories of 47 thousands people who
> clone from me, and I can sync with any one of them only when I know
> there is something worth looking at when I say "git fetch".

Currently, one of the main functions of 'fetch', apart from changing the remote tracking branches, is downloading the remote objects.  This is necessary because of an insufficiently developed technology.

The other main function is changing the local copies of remote branches (changing the remote tracking branches), this is what i described as "taking a snapshot".

I did not understand what you meant by

  "I do not have to know what random tweaks and experiments are done in repositories of 47 thousands people who clone from me, and I can sync with any one of them only when I know there is something worth looking at when I say "git fetch"."

How is it possible to know and not to know what is going on in the remote repository in the same time?

-Alexey.
```

## Alexey Muranov, 2012-08-19 07:15

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <49E12233-CD0E-410A-81BC-964B6CBE7DE8@gmail.com>
URL: https://gitlist.dev/e/49E12233-CD0E-410A-81BC-964B6CBE7DE8%40gmail.com
In-Reply-To: <7vehn3rbom.fsf@alter.siamese.dyndns.org>

```
On 19 Aug 2012, at 02:02, Junio C Hamano wrote:

> Alexey Muranov <alexey.muranov@gmail.com> writes:
> 
>> I hope my opinion might be useful because i do not know anything
>> about the actual implementation of Git,...
> 
> That sounds like contradiction.

I meant that i am psychologically not attached to the current behavior, and may provide a naïve view point, if you like.

-Alexey.
```

## Alexey Muranov, 2012-08-19 11:28

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <A15D5621-7EF5-4409-967A-0DA20B007899@gmail.com>
URL: https://gitlist.dev/e/A15D5621-7EF5-4409-967A-0DA20B007899%40gmail.com
In-Reply-To: <7vehn3rbom.fsf@alter.siamese.dyndns.org>

```
On 19 Aug 2012, at 02:02, Junio C Hamano wrote:

> Alexey Muranov <alexey.muranov@gmail.com> writes:
> 
>> Excuse me if i miss something again, but i might be willing to
>> discuss the "ultimate destination".  Could you possibly state in
>> simple terms what the problem with determining the "ultimate
>> destination" is?
> 
> Decide if it makes sense to break backward compatibility of loose
> ref representation merely to support having a branch "next" and
> another branch "next/foo" in the same repository, and if it does,
> what the new loose ref representation looks like.

I looked again through this thread and tried to understand better the issues.

1. I vote for moving dead reflogs to "logs/graveyard" (or to "logs/deadlogs").

2. I think that allowing both "next" and "next/foo" complicates the mapping from branch names to file paths, and it does not seem necessary if dead reflogs are moved away to "graveyard" anyway.

3. There remains the question what to do with dead reflogs for different branches having the same name.  Maybe, keep the death date and time under the graveyard directory and not allow the user to delete 2 times in less than 1 second?

/logs/graveyard/yyyy-mm-dd-hhmmss/refs/heads/next/foo

In a sense this is similar to the git storage model: an "atomic" destructive operation creates a timestamped "commit" in logs/graveyard directory.
```

## Michael Haggerty, 2012-08-19 13:19

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <5030E7D6.8020206@alum.mit.edu>
URL: https://gitlist.dev/e/5030E7D6.8020206%40alum.mit.edu
In-Reply-To: <7vboi8rl2q.fsf@alter.siamese.dyndns.org>

```
On 08/18/2012 10:39 PM, Junio C Hamano wrote:
> mhagger@alum.mit.edu writes:
> 
>> Given that a flag day would anyway be required to add a d/f-tolerant
>> system, I could live with a separate "graveyard" namespace as
>> originally proposed by Jeff.
>>
>> However, I still think that as long as we are making a jump, we could
>> try to land closer to the ultimate destination.
> 
> Do we _know_ already what the "ultimate destination" looks like?  

No; we can only guess.  I just wanted to submit some code so that the
existence/absence of code would not prejudice the decision.

> If the answer is yes, then I agree, but otherwise, I doubt it is a
> good idea to introduce unnecessary complexity to the system that may
> have to be ripped out and redone.
> 
> I didn't get the impression that we know the "ultimate destination"
> from the previous discussion, especially if we discount the tangent
> around "having next and next/foo at the same time" which was on
> nobody's wish, but I may be misremembering things.

It's been a wish of mine, but it's pretty low priority.  I've also
brainstormed about some other changes that could be connected with a new
repo format:

* Allow "deleted" loose references (for example denoted by value 0{40})
that override packed references with the same name.  This would remove
the need to rewrite the packed-refs file when a reference is deleted.
(A prerequisite for this change would be to allow next and next/foo at
the same time.)

* Push HEAD and its friends down out of $GIT_DIR into a
reference-specific directory.

* Rename lock files to look less like reference names (e.g., something
like "refs/foo~lock" instead of "refs/foo.lock").

* Somehow munge reference names in a way to avoid other filesystem
limitations -- e.g., case insensitivity, filenames like "com" and "prn"
or with multiple dots under Windows.

* ...or maybe a packed-refs file that can (usually) be updated in-place,
and get rid of loose references entirely.

Michael

-- 
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/

```

## Junio C Hamano, 2012-08-19 16:27

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7vlihaq22v.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vlihaq22v.fsf%40alter.siamese.dyndns.org
In-Reply-To: <5030E7D6.8020206@alum.mit.edu>

```
Michael Haggerty <mhagger@alum.mit.edu> writes:

> It's been a wish of mine, but it's pretty low priority.  I've also
> brainstormed about some other changes that could be connected with a new
> repo format:
>
> * Allow "deleted" loose references (for example denoted by value 0{40})
> that override packed references with the same name.  This would remove
> the need to rewrite the packed-refs file when a reference is deleted.
> (A prerequisite for this change would be to allow next and next/foo at
> the same time.)

We would need to think the performance implications through of the
approach; it tempts us to accumulate the loose "removed" markers in
the hope that it would be an improvement than having to rewrite the
packed-refs over and over, and without numbers to back that theory
up, we may be worsening the system without knowing.

Having said that, it is an interesting idea. I wouldn't use 0{40} as
the sentinel value but rather use letters outside [0-9a-f], though.

> * Push HEAD and its friends down out of $GIT_DIR into a
> reference-specific directory.

Not going to happen for several years, I am afraid, as I think many
casual tools do an equivalent of "test -f $DIR/HEAD" to see if $DIR
is a repository; even our own gitweb does so.

We should advertise an easy way for scripted Porcelains to directly
ask is_git_directory().

> * Rename lock files to look less like reference names (e.g., something
> like "refs/foo~lock" instead of "refs/foo.lock").

If you do the ~d/~f thing, foo.lock becomes a non-issue, no?

> * Somehow munge reference names in a way to avoid other filesystem
> limitations -- e.g., case insensitivity, filenames like "com" and "prn"
> or with multiple dots under Windows.

Very interesting.  I however am afraid that the users and the
projects will learn to avoid the problematic names a lot sooner than
such a change will be implemented to make the issue go away (or they
have already learned long time ago), and the end result may end up
solving a non-issue only to make the output from "find .git/refs"
even more unreadable.

> * ...or maybe a packed-refs file that can (usually) be updated in-place,
> and get rid of loose references entirely.

I find this equally intriguing as your "deleted" one above.

```

## Junio C Hamano, 2012-08-19 17:38

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7v1uj2pysd.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v1uj2pysd.fsf%40alter.siamese.dyndns.org
In-Reply-To: <A15D5621-7EF5-4409-967A-0DA20B007899@gmail.com>

```
Alexey Muranov <alexey.muranov@gmail.com> writes:

> 2. I think that allowing both "next" and "next/foo" complicates
> the mapping from branch names to file paths, and it does not seem
> necessary if dead reflogs are moved away to "graveyard" anyway.

It is unclear why the first two lines above leads to the conclusion
"it does not seem necessary" (but honestly, I do not particularly
care).

> 3. There remains the question what to do with dead reflogs for
> different branches having the same name.  Maybe, keep the death
> date and time under the graveyard directory and not allow the user
> to delete 2 times in less than 1 second?
>
> /logs/graveyard/yyyy-mm-dd-hhmmss/refs/heads/next/foo

How would that help us in what way?

When I ask "git log -g next/foo" for the "next/foo" branch that
currently exists, I want to see the update history of its tip since
I created it for the last time, and then an entry that says I
created it at such and such time.  If I used to have the branch
before but deleted, then the output should be followed by another
entry that says I deleted it at such and such time, followed by the
history of the tip updates.

```

## Alexey Muranov, 2012-08-19 22:09

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <9E4BBC27-5B26-4048-93D4-FE02C550F4E2@gmail.com>
URL: https://gitlist.dev/e/9E4BBC27-5B26-4048-93D4-FE02C550F4E2%40gmail.com
In-Reply-To: <7v1uj2pysd.fsf@alter.siamese.dyndns.org>

```
On 19 Aug 2012, at 19:38, Junio C Hamano wrote:

> Alexey Muranov <alexey.muranov@gmail.com> writes:
> 
>> 2. I think that allowing both "next" and "next/foo" complicates
>> the mapping from branch names to file paths, and it does not seem
>> necessary if dead reflogs are moved away to "graveyard" anyway.
> 
> It is unclear why the first two lines above leads to the conclusion
> "it does not seem necessary" (but honestly, I do not particularly
> care).

I thought that the first reason that allowing "next" and "next/foo" seemed necessary was avoiding conflicts with dead reflogs or between dead reflogs.  If dead reflog for "next/foo" is moved away, it will not conflict with a new one for "next".  There remains a problem with a conflict between dead "next/foo" and dead "next".  This can be solved as Jeff suggested by adding special "escape" symbols, or as i suggested below, by keeping reflogs deleted on different occasions in different "timestamp" directories.

>> 3. There remains the question what to do with dead reflogs for
>> different branches having the same name.  Maybe, keep the death
>> date and time under the graveyard directory and not allow the user
>> to delete 2 times in less than 1 second?
>> 
>> /logs/graveyard/yyyy-mm-dd-hhmmss/refs/heads/next/foo
> 
> How would that help us in what way?
> 
> When I ask "git log -g next/foo" for the "next/foo" branch that
> currently exists, I want to see the update history of its tip since
> I created it for the last time, and then an entry that says I
> created it at such and such time.  If I used to have the branch
> before but deleted, then the output should be followed by another
> entry that says I deleted it at such and such time, followed by the
> history of the tip updates.

I only suggested how to resolve conflicts between dead reflogs in graveyard if "next" and "next/foo" cannot coexist.
For example, if first "next/foo" was created and deleted, and then "next" was created and deleted.  It also seems nice to me to have dead reflogs for different identically named branches (created and deleted independently) in separate files.

It is possible to collect the information for "git log -g next/foo" by looking through all "timestamp" subdirectories in graveyard.

-Alexey.
```

## Junio C Hamano, 2012-08-20 00:26

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7vobm6o1cu.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vobm6o1cu.fsf%40alter.siamese.dyndns.org
In-Reply-To: <9E4BBC27-5B26-4048-93D4-FE02C550F4E2@gmail.com>

```
Alexey Muranov <alexey.muranov@gmail.com> writes:

> I only suggested how to resolve conflicts between dead reflogs in
> graveyard if "next" and "next/foo" cannot coexist.

But Jeff's patch series already has the support for a case where you
delete next (graveyard gets 'next'), create next/foo and then delete
that (graveyard gets 'next/foo', too) anyway (check the list archive
before posting).  It is a solved problem.

> It is possible to collect the information for "git log -g
> next/foo" by looking through all "timestamp" subdirectories in
> graveyard.

It is possible if you wrote a new file every time you add one entry
to reflog, or if you created a directory with timestamp in its name
and wrote a new file there, too.

We are not particularly interested in "it is possible" when many
implementations can all trivially allow it to be "possible"; the
question is what a sensible solution is among them, and I didn't
find "a directory with timestamp in its name" a particularly
sensible way to go.

Either Jeff's "refname $name's log goes to logs/graveyard/$name~" or
Michael's "append ~d to each directory component, append ~f to the
leaf component" that are already proposed will keep "one file per
name" property to allow us to open once and efficiently read the
file through.  Why would we want to see an inferiour alternative
added to the discussion?

```

## Junio C Hamano, 2012-08-20 01:01

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7v7gsunzpk.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v7gsunzpk.fsf%40alter.siamese.dyndns.org
In-Reply-To: <7vobm6o1cu.fsf@alter.siamese.dyndns.org>

```
Junio C Hamano <gitster@pobox.com> writes:

> Either Jeff's "refname $name's log goes to logs/graveyard/$name~" or
> Michael's "append ~d to each directory component, append ~f to the
> leaf component" that are already proposed will keep "one file per
> name" property to allow us to open once and efficiently read the
> file through.  Why would we want to see an inferiour alternative
> added to the discussion?

Note that there may be some "other" advantage I am not seeing in the
"directory with timestamp in its name"; if it is a big enough
advantage over what have already been proposed, then that would be a
valid reason why we may want to see it as an alternative (and at
that point, it is no longer inferior).  That is the reason why I
asked "How would that help us in what way?"

```

## Alexey Muranov, 2012-08-20 11:32

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <62FFD304-1902-4D69-9287-ECD1E32BABC9@gmail.com>
URL: https://gitlist.dev/e/62FFD304-1902-4D69-9287-ECD1E32BABC9%40gmail.com
In-Reply-To: <7vobm6o1cu.fsf@alter.siamese.dyndns.org>

```
Dear Junio,

On 20 Aug 2012, at 02:26, Junio C Hamano wrote:

> We are not particularly interested in "it is possible" when many
> implementations can all trivially allow it to be "possible"; the
> question is what a sensible solution is among them, and I didn't
> find "a directory with timestamp in its name" a particularly
> sensible way to go.
> 
> Either Jeff's "refname $name's log goes to logs/graveyard/$name~" or
> Michael's "append ~d to each directory component, append ~f to the
> leaf component" that are already proposed will keep "one file per
> name" property to allow us to open once and efficiently read the
> file through.  Why would we want to see an inferiour alternative
> added to the discussion?

I let the others decide if my idea with "timestamp" directories has a significant advantage over other proposed solutions or not.  It seemed different, so i wanted to add it to the discussion.  I cannot clearly formulate an advantage, but i will try to explain why i proposed it.

I would like also to propose another solution for allowing both "next" and "next/foo" branches, and to try to explain how it is different from the other proposed solutions (unless i missed something).

I would like that the solutions introduce as little new as possible to the existing solutions used in similar situation.

The problem of mapping branch names to file paths looks to me very similar to the problem of mapping URLs to file paths for static web sites, so i would propose to use the same solution: add a special extension to distinguish a file from a directory, for example ".branch" and ".tag" (like ".html" in the case of URL).  This would allow having both branches "next" and "next/foo" with refs stored in files "next.branch" and "next/foo.branch".  This will look very clear and familiar to people not specialist in Git, but familiar with static web sites.  The only limitation this would introduces is that branch names "foo.branch" would need to be forbidden.  If the extension is optional, this makes the new rule almost compatible with the current one, except if somebody is currently using branches n
 amed like "foo.branch" or "next.branch/foo".

For the reflogs of deleted branches, if both "next/foo" and "next" are allowed and it is decided to append to the reflogs when a new branch with the same name is deleted, then of course "timestamp" directories are useless.  However, i do not think that if a branch "tmp" was created and deleted multiple times, all its reflogs have to be concatenated into a single file.  So i viewed the problem of deleting identically named branches as the problem of deleting files under an operating system environment that uses a Trash Bin.  In this case, adding a timestamp usually solves the problem.

-Alexey.
```

## Alexey Muranov, 2012-08-20 11:57

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <A42CEB6A-5951-4869-B890-92BDD2361EC1@gmail.com>
URL: https://gitlist.dev/e/A42CEB6A-5951-4869-B890-92BDD2361EC1%40gmail.com
In-Reply-To: <62FFD304-1902-4D69-9287-ECD1E32BABC9@gmail.com>

```
On 20 Aug 2012, at 13:32, Alexey Muranov wrote:

> The problem of mapping branch names to file paths looks to me very similar to the problem of mapping URLs to file paths for static web sites, so i would propose to use the same solution: add a special extension to distinguish a file from a directory, for example ".branch" and ".tag" (like ".html" in the case of URL).  This would allow having both branches "next" and "next/foo" with refs stored in files "next.branch" and "next/foo.branch".  This will look very clear and familiar to people not specialist in Git, but familiar with static web sites.  The only limitation this would introduces is that branch names "foo.branch" would need to be forbidden.  If the extension is optional, this makes the new rule almost compatible with the current one, except if somebody is currently using branches
  named like "foo.branch" or "next.branch/foo".

Another possible choice for the extensions: ".~br" and ".~tg" (to keep readability of file names and allow all currently allowed branch names).
```

## Jeff King, 2012-08-21 08:27

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <20120821082719.GA13252@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120821082719.GA13252%40sigill.intra.peff.net
In-Reply-To: <7vboi8rl2q.fsf@alter.siamese.dyndns.org>

```
On Sat, Aug 18, 2012 at 01:39:41PM -0700, Junio C Hamano wrote:

> mhagger@alum.mit.edu writes:
> 
> > Given that a flag day would anyway be required to add a d/f-tolerant
> > system, I could live with a separate "graveyard" namespace as
> > originally proposed by Jeff.
> >
> > However, I still think that as long as we are making a jump, we could
> > try to land closer to the ultimate destination.
> 
> Do we _know_ already what the "ultimate destination" looks like?  
> 
> If the answer is yes, then I agree, but otherwise, I doubt it is a
> good idea to introduce unnecessary complexity to the system that may
> have to be ripped out and redone.
> 
> I didn't get the impression that we know the "ultimate destination"
> from the previous discussion, especially if we discount the tangent
> around "having next and next/foo at the same time" which was on
> nobody's wish, but I may be misremembering things.

Sorry for the slow response on this topic; I was traveling all last week
and am still catching up with emails.

I don't think we know what the ultimate destination looks like. If I had
to choose, it would probably be something like:

  refs/heads/next.ref
  refs/heads/next/foo.ref

which is easy to read and manipulate. But this is not compatible with
the current system, because:

  1. It cannot use ".ref", as that is allowed in ref names currently.

  2. This can't co-exist with existing, non-tweaked refs, since
     "refs/heads/next" would still conflict (you'd have to instead do
     "refs/heads.dir/next.dir/foo".

But since making a change like this would involve bumping the
repositoryformatversion flag _anyway_, so at that point we don't really
have to care about compatibility, and we are free to design what looks
good.

So in other words, I do not think any ultimate destination that I find
palatable would be achievable without making the full format jump
anyway. If all things were equal, I'd say there is no reason not to get
as close as we can. But I find some of the proposals significantly less
readable (in particular, the directory-munging is IMHO much harder to
read). And it is not as if it is buying us anything; you still have to
make a magic translation between a dead log and a live one.

Another option I've considered is simply holding back the graveyard
topic, working on the d/f tolerant storage, and then implementing the
graveyards on top (which is basically free at that point). But as you
note, it is not really a commonly-requested feature. If it were easy,
I'd say let's do it. But the idea of bumping repositoryformatversion for
the first time in git's history just to add a feature nobody wants is
not very appealing to me.

-Peff

```

## Jeff King, 2012-08-21 08:33

Subject: Re: [RFC 2/3] Delete reflogs for dead references to allow pruning
Message-ID: <20120821083345.GB13252@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20120821083345.GB13252%40sigill.intra.peff.net
In-Reply-To: <1345310086-20089-3-git-send-email-mhagger@alum.mit.edu>

```
On Sat, Aug 18, 2012 at 07:14:45PM +0200, mhagger@alum.mit.edu wrote:

> From: Michael Haggerty <mhagger@alum.mit.edu>
> 
> This test is broken by "retain reflogs for deleted refs".  Explicitly
> delete the reflogs in the graveyard to allow the corresponding commits
> to be pruned.
> 
> Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
> ---
> 
> Probably there should be a "git reflog" subcommand to do this.
> 
>  t/t9300-fast-import.sh | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
> index 266ae30..dc6c67d 100755
> --- a/t/t9300-fast-import.sh
> +++ b/t/t9300-fast-import.sh
> @@ -1700,6 +1700,7 @@ INPUT_END
>  
>  test_expect_success 'P: verbatim SHA gitlinks' '
>  	git branch -D sub &&
> +	rm -rf .git/logs/graveyard &&

I think "git reflog expire --expire=now refs/heads/sub" would be less
leaky. That didn't work in my initial version, but it obviously should.
I'll include a tweaked version of your fix when I re-roll.

-Peff

```

## Junio C Hamano, 2012-08-21 17:56

Subject: Re: [RFC 0/3] Reflogs for deleted refs: fix breakage and suggest namespace change
Message-ID: <7v4nnwdt7m.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7v4nnwdt7m.fsf%40alter.siamese.dyndns.org
In-Reply-To: <20120821082719.GA13252@sigill.intra.peff.net>

```
Jeff King <peff@peff.net> writes:

> So in other words, I do not think any ultimate destination that I find
> palatable would be achievable without making the full format jump
> anyway. If all things were equal, I'd say there is no reason not to get
> as close as we can. But I find some of the proposals significantly less
> readable (in particular, the directory-munging is IMHO much harder to
> read). And it is not as if it is buying us anything; you still have to
> make a magic translation between a dead log and a live one.

Yes, that is where the earlier comment of mine on this topic came from.

> Another option I've considered is simply holding back the graveyard
> topic, working on the d/f tolerant storage, and then implementing the
> graveyards on top (which is basically free at that point). But as you
> note, it is not really a commonly-requested feature. If it were easy,
> I'd say let's do it. But the idea of bumping repositoryformatversion for
> the first time in git's history just to add a feature nobody wants is
> not very appealing to me.

Amen.

```
