git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Phillip Susi <psusi@cfl.rr.com>
Cc: git@vger.kernel.org, Christian Couder <chriscool@tuxfamily.org>
Subject: Re: clone breaks replace
Date: Thu, 6 Jan 2011 15:33:38 -0600	[thread overview]
Message-ID: <20110106213338.GA15325@burratino> (raw)
In-Reply-To: <4D262D68.2050804@cfl.rr.com>

Phillip Susi wrote:

> I managed to
> correctly add a replace commit that truncates the history and contains
> instructions where you can find it, and running git log only goes back
> to the replacement commit, unless you add --no-replace-objects, which
> causes it to show the original full history.

Before I get to your real question: this seems a bit backwards.  Let
me say a few words about why.

In the days before replacement refs (and today, too), each commit
name described not only the state of a tree at a moment but the
history that led up to it.  In fact you can see this somewhat directly:
given two distinct commits A and B if you try

	$ git cat-file commit A >a.commit
	$ git cat-file commit B >b.commit
	$ diff -u a.commit b.commit

then you will see precisely what can make them different:

 - the author's name and email and the date of authorship
 - the committer's name and email and the date committed
 - the names of the parent commits, describing the history
 - the name of a tree, describing the content
 - the log message, including its encoding

The commit name is a hash of that information (see git-hash-object(1))
and an invariant maintained is "if a repository has access to commit A,
it has access to its parents, their parents, and so on".  This invariant
is maintained during object transfer and garbage collection and relied
on by object transfer and revision traversal.

The beauty of replacement refs is that they can be easily added or
removed without breaking this invariant.  And a replacement ref is an
actual reference into history, so garbage collection does not remove
those commits and the repository keeps enough information to traverse
both the modified and unmodified history.

Therefore if you want clients to be able to choose between a minimal
history and a larger one to save bandwidth, it has to work like this

 - to get the minimal history, fetch _without_ any replacement refs
 - to get the full history, fetch the replacement refs on top of that.

because an additional reference can only increase the number of
objects to be downloaded.

> The problem is that when I clone the repository, I expect the clone to
> contain only history up to the replacement record, and not the old
> history before that.  Instead, the clone contains only the full original
> history, and the replacement ref is not imported at all.  A git replace
> in the new clone shows nothing.
>
> Shouldn't clone copy .git/refs/replace?

With that in mind, I suspect the best way to achieve what you are
looking for is the following:

 1. Make a big, ugly history (branch "big").  Presumably this part's
    already done.

 2. Find the part you want to get rid of and make appropriate
    replacement refs so "gitk big" shows what you want it to.

 3. Use "git filter-branch" to make that history a reality (branch
    "simpler").  Remove the replacement refs.

 4. Use "git replace" to graft back on the pieces you cauterized.
    Publish the result.

 5. Perhaps also run and publish "git replace big simpler", so
    contributors of branches based against the old 'big' can merge
    your latest changes from 'simpler'.  Encourage contributors to
    use 'git rebase' or 'git filter-branch' to rebase their
    contributions against the new, simpler history.

Does that make sense?

Jonathan

  reply	other threads:[~2011-01-06 21:33 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-06 21:00 clone breaks replace Phillip Susi
2011-01-06 21:33 ` Jonathan Nieder [this message]
2011-01-06 21:59   ` Junio C Hamano
2011-01-07 19:43   ` Phillip Susi
2011-01-07 20:51     ` Jonathan Nieder
2011-01-07 21:15       ` Stephen Bash
2011-01-07 21:34       ` Jonathan Nieder
2011-01-07 21:44       ` Phillip Susi
2011-01-07 21:49         ` Jonathan Nieder
2011-01-07 22:09           ` Phillip Susi
2011-01-07 22:09           ` Jeff King
2011-01-07 22:58             ` Junio C Hamano
2011-01-11  5:36               ` Jeff King
2011-01-11 17:40                 ` Junio C Hamano
2011-01-11 17:50                   ` Jeff King
2011-01-11 17:56                     ` Jonathan Nieder
2011-01-11 18:03                       ` Jeff King
2011-01-11 19:32                       ` Christian Couder
2011-01-08  0:43             ` Phillip Susi
2011-01-11  5:47               ` Jeff King
2011-01-11  6:52                 ` Jonathan Nieder
2011-01-11 15:37                   ` Phillip Susi
2011-01-11 18:22                     ` Jonathan Nieder
2011-01-11 18:42                       ` Phillip Susi
2011-01-11 15:24                 ` Phillip Susi
2011-01-11 17:39                   ` Jeff King
2011-01-11 19:48                     ` Johannes Sixt
2011-01-11 19:51                       ` Jeff King
2011-01-11 20:00                         ` Johannes Sixt
2011-01-11 20:22                           ` Phillip Susi
2011-01-11 20:50                             ` Jonathan Nieder
2011-01-12  0:59                               ` Phillip Susi
2011-01-14 20:53                                 ` small downloads and immutable history (Re: clone breaks replace) Jonathan Nieder
2011-01-15  5:27                                   ` Phillip Susi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110106213338.GA15325@burratino \
    --to=jrnieder@gmail.com \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=psusi@cfl.rr.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).