Subject: Re: clone breaks replace

From: Phillip Susi <[email-masked]>
Date: Fri, 07 Jan 2011 16:44:16 -0500

On 1/7/2011 3:51 PM, Jonathan Nieder wrote:
> Phillip Susi wrote:
> 
>> Isn't the whole purpose of using replace to avoid having to use
>> filter-branch, which throws out all of the existing commit records, and
>> creates an entirely new commit chain that is slightly modified?
> 
> No.  What documentation suggested that?  Maybe it can be fixed.

It's just what made sense to me.  If you can modify the history with
filter-branch, then you don't need replace refs.  The downside to
filter-branch is that it breaks people tracking your repository, since
the history they had been tracking is thrown out and replaced with a
completely new commit chain that looks similar, but as far as git is
concerned, is unrelated to the original.  Replace refs seem to have been
created to allow you to accomplish the goal of modifying an old commit
record, but without having to rewrite that and all subsequent commits,
causing breakage.

>  - can choose to fetch or not fetch with the usual
>    "git fetch repo refs/replace/*:refs/replace/*" syntax

It seems like this should be the default behavior.  Or perhaps
refs/replace should be forked into one meant to be private, and one
meant to be public, and fetched by default.  Or maybe it should be
fetched by default, but not pushed, so you have to explicitly push
replacements to the public mirror that you intend for public
consumption.  Having the replace only apply locally and still needing to
filter-branch to make the change visible to the public seems to render
the replace somewhat pointless.

Take the kernel history as an example, only imagine that Linus did not
originally make that first commit leaving out the prior history, but
wants to go back and fix it now.  He can do it with a replace, but then
if he runs filter-branch as you suggest to make the change 'real', then
everyone tracking his tree will fail the next time they try to pull.
You could get the same result without replace, so why bother?

If the replace was fetched by default, the people already tracking would
get it the next time they pull and would not have a problem.  If they
wanted to see the old history, then they would already have it in the
repository and just need to add --no-replace-objects to see it, or run
git log on the original commit id that the replace record should refer
you to ( in the comments ).  Those cloning the repository for the first
time would get it, and avoid fetching all of the old history since they
would be using the replace record in place of the original commit.