git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jonathan Nieder <jrnieder@gmail.com>
To: Jakub Narebski <jnareb@gmail.com>
Cc: "Алексей Шумкин" <zapped@mail.ru>, git@vger.kernel.org
Subject: [RFC/PATCH] Documentation: start to explain what git replace is for
Date: Tue, 11 Jan 2011 18:08:12 -0600	[thread overview]
Message-ID: <20110112000812.GA31950@burratino> (raw)
In-Reply-To: <m3lj2rbmq5.fsf@localhost.localdomain>

Jakub Narebski wrote:

> P.S. This probably should made it into Documentation/howto

Or even better, the git-replace manpage.  How about something like
this?  Still very rough.  I'd be happy if someone else can pick this
up and make it into something better (for example, with an addition
to the test suite to make sure we are not telling lies).

-- 8< --
Subject: Documentation: start to explain what git replace is for

With an example from Алексей Шумкин <zapped@mail.ru>.

Based-on-message-by: Jakub Narebski <jnareb@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
 Documentation/git-replace.txt |  106 +++++++++++++++++++++++++++++++----------
 1 files changed, 80 insertions(+), 26 deletions(-)

diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index fde2092..02e5de8 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -14,38 +14,29 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Adds a 'replace' reference in `.git/refs/replace/`
 
-The name of the 'replace' reference is the SHA1 of the object that is
-replaced. The content of the 'replace' reference is the SHA1 of the
-replacement object.
+The `git replace <object> <replacement>` command adds a ref in the
+`refs/replace/` hierarchy requesting that requests for <object> be
+handled by retrieving <replacement> instead.  This is most commonly
+used to replace one commit by another.
 
-Unless `-f` is given, the 'replace' reference must not yet exist in
-`.git/refs/replace/` directory.
+The name of this 'replace' reference is the object id for the object
+that is replaced.  Unless `-f` is given, the 'replace' reference must
+not already exist in the `refs/replace/` hierarchy.
 
-Replacement references will be used by default by all git commands
-except those doing reachability traversal (prune, pack transfer and
-fsck).
+Replacement references will be used by default by most git commands,
+with the notable exception of reachability calculations.  This
+exception means that replacements do not affect the result of 'git gc'
+or 'git clone', ensuring that (1) it is always safe to remove a
+replacement reference without harming repository integrity and
+(2) replacements do not change the meaning of 'have' lines during
+pack transfer, so the client and server do not need to have the same
+replacements during object transfer for it to succeed.
 
 It is possible to disable use of replacement references for any
 command using the `--no-replace-objects` option just after 'git'.
-
-For example if commit 'foo' has been replaced by commit 'bar':
-
-------------------------------------------------
-$ git --no-replace-objects cat-file commit foo
-------------------------------------------------
-
-shows information about commit 'foo', while:
-
-------------------------------------------------
-$ git cat-file commit foo
-------------------------------------------------
-
-shows information about commit 'bar'.
-
-The 'GIT_NO_REPLACE_OBJECTS' environment variable can be set to
-achieve the same effect as the `--no-replace-objects` option.
+Additionally, the 'GIT_NO_REPLACE_OBJECTS' environment variable can
+be set to achieve the same effect.
 
 OPTIONS
 -------
@@ -62,6 +53,69 @@ OPTIONS
 	Typing "git replace" without arguments, also lists all replace
 	refs.
 
+EXAMPLES
+--------
+. The following sequence replaces commit 'foo' with commit 'bar'
+and then views the replaced and unreplaced versions of 'foo'.
++
+------------------------------------------------
+$ git replace foo^{commit} bar^{commit}        <1>
+$ git --no-replace-objects cat-file commit foo <2>
+$ git cat-file commit foo                      <3>
+------------------------------------------------
++
+<1> request replacement
+<2> show information about the true commit 'foo'
+<3> show information about the replacement commit 'bar'
+
+. The following example comes from Алексей Шумкин:
++
+1.5 years ago I had sources of a project in another version control
+system.  And I had two branches: v2.4 and v2.5.
+They differed enough at that moment and laid in two different folders.
+Then I learned about Git and I decided to try to use this DVCS.
+I created two git repositories: one for each branch.
+So v2.4 has its own git repo and v2.5 (and above) has another one.
++
+Now I'd like to merge them as v2.5 was a continuous branch from v2.4,
+but without rebasing (i.e. without a global change to the v2.5
+repository, which already has other branches).  It should look like
+the last commit of from the v2.4 branch is a parent of the first
+commit of v2.5.
++
+You can do this using grafts (and you can make history with grafts
+permanent using 'git filter-branch').  A better solution might be to
+use the more modern replace mechanism.  Below are untested step-by-step
+instructions.
++
+--------------------------------------------------
+$ git rev-list master --parents | grep -v ' '    <1>
+$ git rev-parse v2.4                             <2>
+$ git cat-file commit FIRST >tmp                 <3>
+$ sed -i "/^tree / a \\
+parent $(git rev-parse v2.4)" <tmp >new          <4>
+$ git hash-object -t commit -w new               <5>
+$ git replace FIRST <object id from hash-object> <6>
+$ git show FIRST
+$ git log --graph --oneline -3 FIRST             <7>
+--------------------------------------------------
++
+<1> Find all parentless commits in the 'master' branch;
+for 'master' read the branch holding v2.5 history.
+<2> Find the last commit of v2.4.
+<3> Save the current state of the first commit of v2.5 to a file.
+<4> Edit this file, adding 'parent' line between 'tree' and 'author'
+headers, so the header of this file looks like the following:
+  tree 13d050266e05f7c66000240814199fcf3b559d43
+  parent ada9983c4256f5a7bac1f7f0e29d52011741d6aa
+  author Jakub Narebski <jnareb@gmail.com> 1294231771 +0100
+<5> Add the newly created object to the repository.
+<6> Use it as a replacement.
+<7> Check that replacement works.
++
+Then anyone who fetches `refs/replace/*` will get the joined history,
+and those who doesn't will see it not connected.
+
 BUGS
 ----
 Comparing blobs or trees that have been replaced with those that
-- 
1.7.4.rc1

  parent reply	other threads:[~2011-01-12  0:08 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-11 10:41 Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible? Алексей Шумкин
2011-01-11 11:49 ` "Martin Krüger"
2011-01-11 12:33   ` Re[2]: " Алексей Шумкин
2011-01-11 12:41     ` Andreas Ericsson
2011-01-11 14:58       ` Re[2]: " Алексей Шумкин
2011-01-11 12:47     ` "Martin Krüger"
2011-01-11 13:21 ` Jakub Narebski
2011-01-11 14:49   ` Re[2]: " Алексей Шумкин
2011-01-11 15:16   ` Алексей Шумкин
2011-01-12  0:08   ` Jonathan Nieder [this message]
2011-01-12 22:47     ` [RFC/PATCH] Documentation: start to explain what git replace is for Maaartin
2011-01-13  7:52       ` Alexey Shumkin
2011-01-14  8:49       ` [RFC/PATCH 2/1] fixup! " Jonathan Nieder
2011-01-14 17:44         ` Maaartin-1
2011-01-14 19:30           ` Jonathan Nieder
2011-01-14 21:09             ` how multiple roots happen (Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for) Jonathan Nieder
2011-01-14 22:48           ` [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for Jakub Narebski
2011-01-15  0:04             ` Maaartin-1

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=20110112000812.GA31950@burratino \
    --to=jrnieder@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=jnareb@gmail.com \
    --cc=zapped@mail.ru \
    /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).