git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
@ 2011-01-11 10:41 Алексей Шумкин
  2011-01-11 11:49 ` "Martin Krüger"
  2011-01-11 13:21 ` Jakub Narebski
  0 siblings, 2 replies; 18+ messages in thread
From: Алексей Шумкин @ 2011-01-11 10:41 UTC (permalink / raw
  To: git

Hi all!

1.5 years ago I had sources of a project in a SVN repository (actually it does not
matter what SCM was used before). And I had two branches: v2.4 and v2.5.
They differed enough at that moment and (as usual for SVN branches)
laid in two different folders.
Then I had known of Git and I decided to try to use this powerful DVCS.
But as I was a newbie I created two git-repositories: one per each
branch. So v2.4 has its own git-repo. v2.5 (and above) has another one.

Now I'd like to merge them as v2.5 was a continuos branch from v2.4,
but without a rebasing (i.e. without a global changing of v2.5
repository, which already has another branches)
It must look like LAST commit of v2.4 should be a PARENT of FIRST commit of v2.5

Now there's a question: Is it possible to do so (no rebasing!), and If
"yes" then how to?

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  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 13:21 ` Jakub Narebski
  1 sibling, 1 reply; 18+ messages in thread
From: "Martin Krüger" @ 2011-01-11 11:49 UTC (permalink / raw
  To: "Алексей Шумкин",
	git

> 
> Now I'd like to merge them as v2.5 was a continuos branch from v2.4,
> but without a rebasing (i.e. without a global changing of v2.5
> repository, which already has another branches)
> It must look like LAST commit of v2.4 should be a PARENT of FIRST commit
> of v2.5
> 
> Now there's a question: Is it possible to do so (no rebasing!), and If
> "yes" then how to?
> 
>
It's possible with a little arts an crafts. 
You have 2 friends:  git format-patch & git am .
With "git format-patch" you  will see what a branch really is:
a serie of patches.  With "git am"  you can apply these patches to a branch created on the correct point of the commit-history . E voila the branch is recreated in the repository.

In your case:

On the 2.5 repository master branch:
git format-patch  INITIAL_COMMITID

On the 2.4 repository master branch:
git branch 2.5
git checkout 2.4
git reset --hard  INITIAL_COMMITID 
cat *.patch | git am

E voila you habe both branches in a single repository.

Nearly  same procedure for every  branch of the  2.5 repository
git checkout branchname 
git format-patch master

In the 2.4(Contains now both branches.) respository:
git checkout 2.5
git branch branchname
git reset --hard CORRECT_BRANCHBASE
cat *.patch | git am

Best regards 
   martin



 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re[2]: 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   ` Алексей Шумкин
  2011-01-11 12:41     ` Andreas Ericsson
  2011-01-11 12:47     ` "Martin Krüger"
  0 siblings, 2 replies; 18+ messages in thread
From: Алексей Шумкин @ 2011-01-11 12:33 UTC (permalink / raw
  To: "Martin Krüger"; +Cc: git

Thank you for the answer, but it's not what I want ))
Applying patches is the same as rebasing, I guess.
But I do not want to change v2.5-repo (let's call it so) that much.
I'd like to know is there any method (low-level I suppose, as far as Git
manages tree-objects as files) to make v2.4 LAST commit to be the
parent of v2.5 FIRST commit?

MK> It's possible with a little arts an crafts.
MK> You have 2 friends:  git format-patch & git am .
MK> With "git format-patch" you  will see what a branch really is:
MK> a serie of patches.  With "git am"  you can apply these patches
MK> to a branch created on the correct point of the commit-history . E
MK> voila the branch is recreated in the repository.

MK> In your case:

MK> On the 2.5 repository master branch:
MK> git format-patch  INITIAL_COMMITID

MK> On the 2.4 repository master branch:
MK> git branch 2.5
MK> git checkout 2.4
MK> git reset --hard  INITIAL_COMMITID 
MK> cat *.patch | git am

MK> E voila you habe both branches in a single repository.

MK> Nearly  same procedure for every  branch of the  2.5 repository
MK> git checkout branchname 
MK> git format-patch master

MK> In the 2.4(Contains now both branches.) respository:
MK> git checkout 2.5
MK> git branch branchname
MK> git reset --hard CORRECT_BRANCHBASE
MK> cat *.patch | git am

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  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"
  1 sibling, 1 reply; 18+ messages in thread
From: Andreas Ericsson @ 2011-01-11 12:41 UTC (permalink / raw
  To: Алексей Шумкин
  Cc: Martin Krüger, git

On 01/11/2011 01:33 PM, Алексей Шумкин wrote:
> Thank you for the answer, but it's not what I want ))
> Applying patches is the same as rebasing, I guess.
> But I do not want to change v2.5-repo (let's call it so) that much.
> I'd like to know is there any method (low-level I suppose, as far as Git
> manages tree-objects as files) to make v2.4 LAST commit to be the
> parent of v2.5 FIRST commit?
> 

You want grafts. Check them up in the docs. Googling for "git graft"
should get you a good starting point.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Re[2]: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  2011-01-11 12:33   ` Re[2]: " Алексей Шумкин
  2011-01-11 12:41     ` Andreas Ericsson
@ 2011-01-11 12:47     ` "Martin Krüger"
  1 sibling, 0 replies; 18+ messages in thread
From: "Martin Krüger" @ 2011-01-11 12:47 UTC (permalink / raw
  To: "Алексей Шумкин"
  Cc: git


> Thank you for the answer, but it's not what I want ))
> Applying patches is the same as rebasing, I guess.
> But I do not want to change v2.5-repo (let's call it so) that much.
> I'd like to know is there any method (low-level I suppose, as far as Git
> manages tree-objects as files) to make v2.4 LAST commit to be the
> parent of v2.5 FIRST commit?
> 
This is impossible.
The commit-id is calculated from the history of the whole repository.
So you  must rebase in the sense of dependency on another history. 
My  method  enables to rebase on the same content of the repository.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  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 13:21 ` Jakub Narebski
  2011-01-11 14:49   ` Re[2]: " Алексей Шумкин
                     ` (2 more replies)
  1 sibling, 3 replies; 18+ messages in thread
From: Jakub Narebski @ 2011-01-11 13:21 UTC (permalink / raw
  To: Алексей Шумкин
  Cc: git

=?windows-1251?B?wOvl6vHl6SDY8+zq6O0=?= <zapped@mail.ru> writes:

> 1.5 years ago I had sources of a project in a SVN repository (actually it does not
> matter what SCM was used before). And I had two branches: v2.4 and v2.5.
> They differed enough at that moment and (as usual for SVN branches)
> laid in two different folders.
> Then I had known of Git and I decided to try to use this powerful DVCS.
> But as I was a newbie I created two git-repositories: one per each
> branch. So v2.4 has its own git-repo. v2.5 (and above) has another one.
> 
> Now I'd like to merge them as v2.5 was a continuos branch from v2.4,
> but without a rebasing (i.e. without a global changing of v2.5
> repository, which already has another branches)
> It must look like LAST commit of v2.4 should be a PARENT of FIRST commit of v2.5
> 
> Now there's a question: Is it possible to do so (no rebasing!), and If
> "yes" then how to?

As Andreas Ericsson wrote, you can do this using grafts (and you can
make history with grafts permanent using "git filter-branch").

Better solution might be to use more modern replace mechanism, see
e.g. "git replace" manpage.  Below there is untested step-by-step
instruction.

First, you have put history of v2.4 and of v2.5 in a single repository
(e.g. using "git remote add").  Then you need to find FIRST commit of
v2.5 among

  $ git rev-list master --parents | grep -v ' '

The above finds all parent-less commits in 'master' branch; replace it
with branch holding v2.5 history.  Then you need to find LAST commit
of v2.4 and its SHA-1, e.g. via

  $ git rev-parse v2.4

Save current state of FIRST commit of v2.5 to a file

  $ git cat-file -p FIRST > tmp

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

(trailing space added for better readibility).

Then you need to add newly created object to repository:

  $ git hash-object -t commit -w tmp

and then use it as replacement

  $ git replace <SHA-1 of FIRST> <SHA-1 returned by hash-object>

Finally check that replacement works, e.g.:

  $ git show FIRST
  $ git log --graph --oneline -3 FIRST

The anyone who would fetch refs/replace/ would get joined history, and
who doesn't would see it not connected.


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

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re[2]: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  2011-01-11 13:21 ` Jakub Narebski
@ 2011-01-11 14:49   ` Алексей Шумкин
  2011-01-11 15:16   ` Алексей Шумкин
  2011-01-12  0:08   ` [RFC/PATCH] Documentation: start to explain what git replace is for Jonathan Nieder
  2 siblings, 0 replies; 18+ messages in thread
From: Алексей Шумкин @ 2011-01-11 14:49 UTC (permalink / raw
  To: Jakub Narebski; +Cc: git

Hello, Jakub.

Thank you very much. Your method works great and it suits for me well

>> 1.5 years ago I had sources of a project in a SVN repository (actually it does not
>> matter what SCM was used before). And I had two branches: v2.4 and v2.5.
>> They differed enough at that moment and (as usual for SVN branches)
>> laid in two different folders.
>> Then I had known of Git and I decided to try to use this powerful DVCS.
>> But as I was a newbie I created two git-repositories: one per each
>> branch. So v2.4 has its own git-repo. v2.5 (and above) has another one.
>> 
>> Now I'd like to merge them as v2.5 was a continuos branch from v2.4,
>> but without a rebasing (i.e. without a global changing of v2.5
>> repository, which already has another branches)
>> It must look like LAST commit of v2.4 should be a PARENT of FIRST commit of v2.5
>> 
>> Now there's a question: Is it possible to do so (no rebasing!), and If
>> "yes" then how to?

JN> As Andreas Ericsson wrote, you can do this using grafts (and you can
JN> make history with grafts permanent using "git filter-branch").

JN> Better solution might be to use more modern replace mechanism, see
JN> e.g. "git replace" manpage.  Below there is untested step-by-step
JN> instruction.

JN> First, you have put history of v2.4 and of v2.5 in a single repository
JN> (e.g. using "git remote add").  Then you need to find FIRST commit of
JN> v2.5 among

JN>   $ git rev-list master --parents | grep -v ' '

JN> The above finds all parent-less commits in 'master' branch; replace it
JN> with branch holding v2.5 history.  Then you need to find LAST commit
JN> of v2.4 and its SHA-1, e.g. via

JN>   $ git rev-parse v2.4

JN> Save current state of FIRST commit of v2.5 to a file

JN>   $ git cat-file -p FIRST > tmp

JN> Edit this file, adding 'parent' line between 'tree' and 'author'
JN> headers, so the header of this file looks like the following:

JN>   tree 13d050266e05f7c66000240814199fcf3b559d43
JN>   parent ada9983c4256f5a7bac1f7f0e29d52011741d6aa
JN>   author Jakub Narebski <jnareb@gmail.com> 1294231771 +0100

JN> (trailing space added for better readibility).

JN> Then you need to add newly created object to repository:

JN>   $ git hash-object -t commit -w tmp

JN> and then use it as replacement

JN>   $ git replace <SHA-1 of FIRST> <SHA-1 returned by hash-object>

JN> Finally check that replacement works, e.g.:

JN>   $ git show FIRST
JN>   $ git log --graph --oneline -3 FIRST

JN> The anyone who would fetch refs/replace/ would get joined history, and
JN> who doesn't would see it not connected.


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

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re[2]: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  2011-01-11 12:41     ` Andreas Ericsson
@ 2011-01-11 14:58       ` Алексей Шумкин
  0 siblings, 0 replies; 18+ messages in thread
From: Алексей Шумкин @ 2011-01-11 14:58 UTC (permalink / raw
  To: Andreas Ericsson; +Cc: Martin Krüger, git


AE> On 01/11/2011 01:33 PM, Алексей Шумкин wrote:
>> Thank you for the answer, but it's not what I want ))
>> Applying patches is the same as rebasing, I guess.
>> But I do not want to change v2.5-repo (let's call it so) that much.
>> I'd like to know is there any method (low-level I suppose, as far as Git
>> manages tree-objects as files) to make v2.4 LAST commit to be the
>> parent of v2.5 FIRST commit?
>> 

AE> You want grafts. Check them up in the docs. Googling for "git graft"
AE> should get you a good starting point.

Yes, you`re right, but unfortunately grafts ('info/grafts' file) cannot be cloned unless
'git filter-branch' is executed, but this command changes all the
"v2.5-repo" which is "equivalent" to 'git rebase' and what I aspire
to avoid.

But Jakub Narebski <jnareb@gmail.com> gave a solution which suits for
me great.

Thank you for your reply

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re[2]: Merge two different repositories (v2.4 + v2.5) into the one (v2.4 -> v2.5). Possible?
  2011-01-11 13:21 ` Jakub Narebski
  2011-01-11 14:49   ` Re[2]: " Алексей Шумкин
@ 2011-01-11 15:16   ` Алексей Шумкин
  2011-01-12  0:08   ` [RFC/PATCH] Documentation: start to explain what git replace is for Jonathan Nieder
  2 siblings, 0 replies; 18+ messages in thread
From: Алексей Шумкин @ 2011-01-11 15:16 UTC (permalink / raw
  To: Jakub Narebski; +Cc: git


There is one more method using grafts and fast-export/import
http://ben.straubnet.net/post/939181602/git-grafting-repositories

Let it be here too

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [RFC/PATCH] Documentation: start to explain what git replace is for
  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
  2011-01-12 22:47     ` Maaartin
  2 siblings, 1 reply; 18+ messages in thread
From: Jonathan Nieder @ 2011-01-12  0:08 UTC (permalink / raw
  To: Jakub Narebski
  Cc: Алексей Шумкин,
	git

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

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [RFC/PATCH] Documentation: start to explain what git replace is for
  2011-01-12  0:08   ` [RFC/PATCH] Documentation: start to explain what git replace is for Jonathan Nieder
@ 2011-01-12 22:47     ` Maaartin
  2011-01-13  7:52       ` Alexey Shumkin
  2011-01-14  8:49       ` [RFC/PATCH 2/1] fixup! " Jonathan Nieder
  0 siblings, 2 replies; 18+ messages in thread
From: Maaartin @ 2011-01-12 22:47 UTC (permalink / raw
  To: git

Jonathan Nieder <jrnieder <at> gmail.com> writes:

> +. The following example comes from ??????? ??????:

I know unicode exists already for many years, but in cygwin I get just a bunch 
of question marks instead of the name. So I'd suggest to replace "Алексей 
Шумкин" by "Alexej Shumkin" or whatever his preferred transcription is.


> +<1> Find all parentless commits in the 'master' branch;
> +for 'master' read the branch holding v2.5 history.

Aren't you later calling it "FIRST" and assuming there's only one?

> +$ sed -i "/^tree / a \\
> +parent $(git rev-parse v2.4)" <tmp >new          <4>

Isn't the combination of "-i" (=in-place edit) with redirection wrong? I hardly 
know anything about sed (abandoned it in favor of perl many years ago).

> +$ git hash-object -t commit -w new               <5>
> +$ git replace FIRST <object id from hash-object> <6>

I'd prefer something like

+$ objectId=$(git hash-object -t commit -w new)
+$ git replace FIRST $objectId

This is easier for people just willing to use it without much thinking, and 
also for those having no idea that git-hash-object creates a new object.

That said, it's a nice example and I've learned quite a few things.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC/PATCH] Documentation: start to explain what git replace is for
  2011-01-12 22:47     ` Maaartin
@ 2011-01-13  7:52       ` Alexey Shumkin
  2011-01-14  8:49       ` [RFC/PATCH 2/1] fixup! " Jonathan Nieder
  1 sibling, 0 replies; 18+ messages in thread
From: Alexey Shumkin @ 2011-01-13  7:52 UTC (permalink / raw
  To: git

Maaartin <grajcar1 <at> seznam.cz> writes:
> I know unicode exists already for many years, but in cygwin I get just a bunch 
> of question marks instead of the name. So I'd suggest to replace "Алексей 
> Шумкин" by "Alexej Shumkin" or whatever his preferred transcription is.

"Alexey Shumkin" I'd prefer ) (it can be noticed in the patche)

I use email-client for this account primarily for Russian correspondents
so the  signature is in Russian
* "Maybe that's the reason to know how "The Bat!" can change letter
templates for particular recipients" he thought *

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
  2011-01-12 22:47     ` Maaartin
  2011-01-13  7:52       ` Alexey Shumkin
@ 2011-01-14  8:49       ` Jonathan Nieder
  2011-01-14 17:44         ` Maaartin-1
  1 sibling, 1 reply; 18+ messages in thread
From: Jonathan Nieder @ 2011-01-14  8:49 UTC (permalink / raw
  To: Maaartin; +Cc: git, Jakub Narebski, Aleksey Shumkin

Some tweaks suggested by Maaartin:

- use a transliteration for Aleksey's name.  
- clarify that there will only be one parentless commit in a typical
  branch
- use variables so the recipe is easier to test by copy and paste
- remove unintended "-i" argument to sed

While at it, make a few miscellaneous grammar tweaks and make sure
each line of the example raw commit appears on a separate line.
The formatting is still not great for that --- there is too much
space between lines.

Still to do: check whether this actually works and add a test script
to make sure it keeps working.

Improved-by: Maaartin <grajcar1@seznam.cz>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
---
Can be tested with

	make -C Documentation git-replace.1
	man Documentation/git-replace.1

.

Maaartin wrote:
> Jonathan Nieder writes:
[side note: please do not prune the cc list; I only stumbled on this
message in the online archive by luck]

>> +. The following example comes from ??????? ??????:
>
> I know unicode exists already for many years, but in cygwin I get just a bunch 
> of question marks instead of the name. So I'd suggest to replace "Алексей 
> Шумкин" by "Alexej Shumkin" or whatever his preferred transcription is.

Makes sense.

>> +<1> Find all parentless commits in the 'master' branch;
>> +for 'master' read the branch holding v2.5 history.
>
> Aren't you later calling it "FIRST" and assuming there's only one?

Hmm.  I want to say that there _could_ be multiple parentless commits
in the v2.5 history and we are treating one of them as its root (just
like git master has multiple parentless ancestors but e83c5163 is
conventionally considered its beginning).  Not sure how to write that
clearly.

> Isn't the combination of "-i" (=in-place edit) with redirection wrong?

Good catch (the "-i" is a typo).

> +$ objectId=$(git hash-object -t commit -w new)
> +$ git replace FIRST $objectId
>
> This is easier for people just willing to use it without much thinking, and 
> also for those having no idea that git-hash-object creates a new object.

Right, thanks.

 Documentation/git-replace.txt |   40 ++++++++++++++++++++++------------------
 1 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/Documentation/git-replace.txt b/Documentation/git-replace.txt
index 02e5de8..5829901 100644
--- a/Documentation/git-replace.txt
+++ b/Documentation/git-replace.txt
@@ -68,16 +68,17 @@ $ git cat-file commit foo                      <3>
 <2> show information about the true commit 'foo'
 <3> show information about the replacement commit 'bar'
 
-. The following example comes from Алексей Шумкин:
+. The following example comes from Aleksey Shumkin:
 +
 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.
+They differed enough at that moment and lay 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.
+So v2.4 has one 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,
+Now I'd like to merge them as if v2.5 were a continuous development
+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
@@ -89,25 +90,28 @@ 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>
+$ git rev-list master --parents | grep -v ' '
+$ first=$(git rev-list master --parents | grep -v ' ') <1>
+$ git rev-parse v2.4                                   <2>
+$ git cat-file commit $first >tmp                      <3>
+$ sed "/^tree / a \\
+parent $(git rev-parse v2.4)" <tmp >new                <4>
+$ new_commit=$(git hash-object -t commit -w new)       <5>
+$ git replace $first $new_commit                       <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.
+<1> List all parentless commits in the 'master' branch and
+call the appropriate one (in this case the only one) $first.
+Instead of 'master' one would use 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
+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.
-- 
1.7.4.rc2

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
  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 22:48           ` [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for Jakub Narebski
  0 siblings, 2 replies; 18+ messages in thread
From: Maaartin-1 @ 2011-01-14 17:44 UTC (permalink / raw
  To: Jonathan Nieder; +Cc: git, Jakub Narebski, Aleksey Shumkin

On 11-01-14 09:49, Jonathan Nieder wrote:
> Some tweaks suggested by Maaartin:

[snip]

> [side note: please do not prune the cc list; I only stumbled on this
> message in the online archive by luck]

What could I have done about it? I didn't received it by email and
answered using post.gmane.org. There's no way to add CC there. If I'd
wrote an email instead, it wouldn't be placed in the thread.

[snip]

>>> +<1> Find all parentless commits in the 'master' branch;
>>> +for 'master' read the branch holding v2.5 history.
>>
>> Aren't you later calling it "FIRST" and assuming there's only one?
> 
> Hmm.  I want to say that there _could_ be multiple parentless commits
> in the v2.5 history and we are treating one of them as its root (just
> like git master has multiple parentless ancestors but e83c5163 is
> conventionally considered its beginning).  Not sure how to write that
> clearly.

Maybe just something like "Let's assume there's only one and let's call
it FIRST". For the example, this is enough.

>> Isn't the combination of "-i" (=in-place edit) with redirection wrong?
> 
> Good catch (the "-i" is a typo).

I'd go the other way round and use "-i" so I'd need only one file. Using
a shell variable instead would be even better, s. below.

[snip]

I tried to use the vars instead of files below, but never tested it. I
used "first_commit" instead of both "tmp" and "new", which is not really
nice.

> +$ git rev-list master --parents | grep -v ' '
> +$ first=$(git rev-list master --parents | grep -v ' ') <1>
> +$ git rev-parse v2.4                                   <2>
> +$ git cat-file commit $first >tmp                      <3>

$ first_commit = $(git cat-file commit FIRST)       <3>

> +$ sed "/^tree / a \\
> +parent $(git rev-parse v2.4)" <tmp >new                <4>

$ first_commit = $($ echo $first_commit |
sed  "/^tree / a \\
parent $(git rev-parse v2.4)")                      <4>

Unfortunately, the line got too long. For sed unaware people like me it
may not be obvious that a line break is required. I'd use perl, anyway.

$ first_commit = $($ echo $first_commit |
perl -p
"s/^tree .*/$&\nparent $(git rev-parse v2.4)/")      <4>

> +$ new_commit=$(git hash-object -t commit -w new)       <5>

$ new_commit=$(echo $first_commit |
git hash-object -t commit -w --stdin)       <5>

[snip]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
  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
  1 sibling, 1 reply; 18+ messages in thread
From: Jonathan Nieder @ 2011-01-14 19:30 UTC (permalink / raw
  To: Maaartin-1; +Cc: git, Jakub Narebski, Aleksey Shumkin

Maaartin wrote:
> On 11-01-14 09:49, Jonathan Nieder wrote:

>> [side note: please do not prune the cc list; I only stumbled on this
>> message in the online archive by luck]
>
> What could I have done about it?

See [1].

> Maybe just something like "Let's assume there's only one and let's call
> it FIRST". For the example, this is enough.

True enough.  Even better would be to give a reference to the "coolest merge
ever" (is that documented anywhere?) so the interested reader can discover
how there could be more than one.

> I'd go the other way round and use "-i" so I'd need only one file.

"sed -i" is not portable (not sure how important that is for documentation).
But perl -i is. :)

> $ first_commit = $($ echo $first_commit |
> perl -p
> "s/^tree .*/$&\nparent $(git rev-parse v2.4)/")      <4>

So:

	perl -pi -e "s/^tree .*$/\$&\nparent $(git rev-parse v2.4)/" new

Unfortunately "echo" and process substitution destroy some formatting
in the commit message --- in particular, trailing whitespace.

Thanks for the suggestions.  Please feel free to pick up the patch and
run with it (I trust you for this more than I would trust myself).

Regards,
Jonathan

[1] My current method: [2]  Yes, I agree that this is cumbersome.

I'm also told that Thunderbird when used as a newsreader can reply-to-all
easily, though I haven't tried it.

[2] http://thread.gmane.org/gmane.comp.version-control.git/154490

^ permalink raw reply	[flat|nested] 18+ messages in thread

* how multiple roots happen (Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for)
  2011-01-14 19:30           ` Jonathan Nieder
@ 2011-01-14 21:09             ` Jonathan Nieder
  0 siblings, 0 replies; 18+ messages in thread
From: Jonathan Nieder @ 2011-01-14 21:09 UTC (permalink / raw
  To: Maaartin-1; +Cc: git, Jakub Narebski, Aleksey Shumkin

Jonathan Nieder wrote:
> Maaartin wrote:

>> Maybe just something like "Let's assume there's only one and let's call
>> it FIRST". For the example, this is enough.
>
> True enough.  Even better would be to give a reference to the "coolest merge
> ever" (is that documented anywhere?) so the interested reader can discover
> how there could be more than one.

Apparently it was not clear what I was talking about (who knew?).  So
here you go:

 http://thread.gmane.org/gmane.comp.version-control.git/5126

For a more modern take on it:

 http://thread.gmane.org/gmane.comp.version-control.git/144302/focus=144323

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
  2011-01-14 17:44         ` Maaartin-1
  2011-01-14 19:30           ` Jonathan Nieder
@ 2011-01-14 22:48           ` Jakub Narebski
  2011-01-15  0:04             ` Maaartin-1
  1 sibling, 1 reply; 18+ messages in thread
From: Jakub Narebski @ 2011-01-14 22:48 UTC (permalink / raw
  To: Maaartin-1; +Cc: Jonathan Nieder, git, Aleksey Shumkin

On Fri, 14 Jan 2011, Maaartin-1 wrote:
> On 11-01-14 09:49, Jonathan Nieder wrote:
> > Some tweaks suggested by Maaartin:
> 
> [snip]
> 
>> [side note: please do not prune the cc list; I only stumbled on this
>> message in the online archive by luck]
> 
> What could I have done about it? I didn't received it by email and
> answered using post.gmane.org. There's no way to add CC there. If I'd
> wrote an email instead, it wouldn't be placed in the thread.

In a good newsreader, like e.g. Gnus from GNU Emacs, you have option
to do 'reply all via email', which includes also git@vger.kernel.org,
i.e. mailing list from which gmane newsgroup is created.  That's what
I do nowadays (usually).

> [snip]
> 
>>>> +<1> Find all parentless commits in the 'master' branch;
>>>> +for 'master' read the branch holding v2.5 history.
>>>
>>> Aren't you later calling it "FIRST" and assuming there's only one?
>> 
>> Hmm.  I want to say that there _could_ be multiple parentless commits
>> in the v2.5 history and we are treating one of them as its root (just
>> like git master has multiple parentless ancestors but e83c5163 is
>> conventionally considered its beginning).  Not sure how to write that
>> clearly.
> 
> Maybe just something like "Let's assume there's only one and let's call
> it FIRST". For the example, this is enough.

That might be good enough, as I don't think that at beginning (where you
are creating current and archive repository) one would have multiple roots
from joining separate projects.
 
>>> Isn't the combination of "-i" (=in-place edit) with redirection wrong?
>> 
>> Good catch (the "-i" is a typo).
> 
> I'd go the other way round and use "-i" so I'd need only one file. Using
> a shell variable instead would be even better, s. below.

No, using shell variable for storing commit object is *not* a good idea.
Either save it to temporary file, where you can edit it using editor of
your choice, or use pipeline.
 
> [snip]
> 
> I tried to use the vars instead of files below, but never tested it. I
> used "first_commit" instead of both "tmp" and "new", which is not really
> nice.
> 
>> +$ git rev-list master --parents | grep -v ' '
>> +$ first=$(git rev-list master --parents | grep -v ' ') <1>

Or using always the oldest commit:

   +$ first=$(git rev-list master --date-order --parents | grep -v ' ' | tail -1) <1>


>> +$ git rev-parse v2.4                                   <2>

Let's save it to a variable too

   +$ join=$(git rev-parse v2.4)                           <2>


>> +$ git cat-file commit $first >tmp                      <3>

We can use COMMIT, or even FIRST as a file name here.

> $ first_commit = $(git cat-file commit FIRST)            <3>

No.  Just... no.

> > +$ sed "/^tree / a \\
> > +parent $(git rev-parse v2.4)" <tmp >new                <4>
> 
> $ first_commit = $($ echo $first_commit |
> sed  "/^tree / a \\
> parent $(git rev-parse v2.4)")                      <4>
> 
> Unfortunately, the line got too long. For sed unaware people like me it
> may not be obvious that a line break is required.

No, it is not required, I think.

> I'd use perl, anyway. 
> 
> $ first_commit = $($ echo $first_commit |
> perl -p
> "s/^tree .*/$&\nparent $(git rev-parse v2.4)/")      <4>
> 
> > +$ new_commit=$(git hash-object -t commit -w new)       <5>
> 
> $ new_commit=$(echo $first_commit |
> git hash-object -t commit -w --stdin)       <5>

If you don't use temporary file, which you can edit, you can use pipeline
instead:

  $ new_commit=$(git cat-file commit $first_commit |
                 sed -e "/^tree / a\\parent $(git rev-parse v2.4)" |
                 git hash-object -t commit -w --stdin

  $ git replace $first_commit $new_commit

-- 
Jakub Narebski
Poland

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [RFC/PATCH 2/1] fixup! Documentation: start to explain what git replace is for
  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
  0 siblings, 0 replies; 18+ messages in thread
From: Maaartin-1 @ 2011-01-15  0:04 UTC (permalink / raw
  To: Jakub Narebski; +Cc: Jonathan Nieder, git, Aleksey Shumkin

On 11-01-14 23:48, Jakub Narebski wrote:
> On Fri, 14 Jan 2011, Maaartin-1 wrote:
>> On 11-01-14 09:49, Jonathan Nieder wrote:
>>> Some tweaks suggested by Maaartin:

>>> [side note: please do not prune the cc list; I only stumbled on this
>>> message in the online archive by luck]
>>
>> What could I have done about it? I didn't received it by email and
>> answered using post.gmane.org. There's no way to add CC there. If I'd
>> wrote an email instead, it wouldn't be placed in the thread.
> 
> In a good newsreader, like e.g. Gnus from GNU Emacs, you have option
> to do 'reply all via email', which includes also git@vger.kernel.org,
> i.e. mailing list from which gmane newsgroup is created.  That's what
> I do nowadays (usually).

I hate using Emacs for too many things. However, I'm starting to use
Thunderbird as newsreader, and it's quite OK.

>> I'd go the other way round and use "-i" so I'd need only one file. Using
>> a shell variable instead would be even better, s. below.
> 
> No, using shell variable for storing commit object is *not* a good idea.
> Either save it to temporary file, where you can edit it using editor of
> your choice, or use pipeline.

I see that the line-breaks get (for whatever reason) replaced by blanks,
sorry for the noise.

>>> +$ sed "/^tree / a \\
>>> +parent $(git rev-parse v2.4)" <tmp >new                <4>
>>
>> $ first_commit = $($ echo $first_commit |
>> sed  "/^tree / a \\
>> parent $(git rev-parse v2.4)")                      <4>
>>
>> Unfortunately, the line got too long. For sed unaware people like me it
>> may not be obvious that a line break is required.
> 
> No, it is not required, I think.

You're right, sorry again.

> If you don't use temporary file, which you can edit, you can use pipeline
> instead:
> 
>   $ new_commit=$(git cat-file commit $first_commit |
>                  sed -e "/^tree / a\\parent $(git rev-parse v2.4)" |
>                  git hash-object -t commit -w --stdin
> 
>   $ git replace $first_commit $new_commit

I know, I just thought, using such a pipe is not very enlightening, but
it's actually quite easy to follow.

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2011-01-15  0:04 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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   ` [RFC/PATCH] Documentation: start to explain what git replace is for Jonathan Nieder
2011-01-12 22:47     ` 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

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).