threads / discuss / 17042

collapsing commits with rebase

Subject: collapsing commits with rebase

## tl;dr

12 messages between Jan 8, 2009 and Jan 10, 2009.

replies: 11people: 6as markdown or json

Geoff Russell· Jan 8, 2009, 00:08 UTC · lore
Dear gits,
I have a series of commits:
    A---B---C---D---E---F

I want to collapse B---C---D into one single commit. git rebase -i B will allow me to do this, but I'm looking for a non-interactive incantation.

Cheers, Geoff Russell

P.S. The context is a program that performs a single high level operation on a repository as a series of commits but then wants to turn it back into a single commit without user intervention so it subsequently looks like a single op in the history.

Johannes Schindelin· Jan 8, 2009, 00:45 UTC · re: Geoff Russell · lore

Re: collapsing commits with rebase

Hi,
On Thu, 8 Jan 2009, Geoff Russell wrote:
Show 9 quoted lines
> Dear gits,
> 
> I have a series of commits:
> 
>     A---B---C---D---E---F
> 
> I want to collapse B---C---D into one single commit. git rebase -i B 
> will allow me to do this, but I'm looking for a non-interactive 
> incantation.
You set GIT_EDITOR to a script ;-)
Alternatively, something like this should work for you:
	$ git checkout A
	$ git read-tree -u -m D
	$ git commit -m "My message"
	$ git cherry-pick E
	$ git cherry-pick F

Hth, Dscho

Geoff Russell· Jan 8, 2009, 01:59 UTC · re: Johannes Schindelin · lore

Re: collapsing commits with rebase

On Thu, Jan 8, 2009 at 11:15 AM, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:

Show 15 quoted lines
> Hi,
>
> On Thu, 8 Jan 2009, Geoff Russell wrote:
>
>> Dear gits,
>>
>> I have a series of commits:
>>
>>     A---B---C---D---E---F
>>
>> I want to collapse B---C---D into one single commit. git rebase -i B
>> will allow me to do this, but I'm looking for a non-interactive
>> incantation.
>
> You set GIT_EDITOR to a script ;-)
This is plan B.
Show 8 quoted lines
>
> Alternatively, something like this should work for you:
>
>        $ git checkout A
>        $ git read-tree -u -m D
>        $ git commit -m "My message"
>        $ git cherry-pick E
>        $ git cherry-pick F

Plan B is looking good, because I'd generally like the commit message to be the concatenation of the messages for B,C and D.

Many thanks.
Geoff.
Johannes Schindelin· Jan 8, 2009, 11:07 UTC · re: Geoff Russell · lore

Re: collapsing commits with rebase

Hi,
On Thu, 8 Jan 2009, Geoff Russell wrote:
Show 13 quoted lines
> On Thu, Jan 8, 2009 at 11:15 AM, Johannes Schindelin
> <Johannes.Schindelin@gmx.de> wrote:
>
> > Alternatively, something like this should work for you:
> >
> >        $ git checkout A
> >        $ git read-tree -u -m D
> >        $ git commit -m "My message"
> >        $ git cherry-pick E
> >        $ git cherry-pick F
> 
> Plan B is looking good, because I'd generally like the commit message to 
> be the concatenation of the messages for B,C and D.
Replace the commit call by this:
	$ for commit in B C D
	  do
		git cat-file commit $commit | sed '1,/^$/d'
		# possibly add an empty line between the commit messages,
		# git commit will strip away empty lines at the end.
	  done |
	  git commit -F -

Hth, Dscho

Geoff Russell· Jan 10, 2009, 10:34 UTC · re: Johannes Schindelin · lore

Re: collapsing commits with rebase

On 1/8/09, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
Show 32 quoted lines
> Hi,
>
>  On Thu, 8 Jan 2009, Geoff Russell wrote:
>
>  > On Thu, Jan 8, 2009 at 11:15 AM, Johannes Schindelin
>  > <Johannes.Schindelin@gmx.de> wrote:
>  >
>
> > > Alternatively, something like this should work for you:
>  > >
>  > >        $ git checkout A
>  > >        $ git read-tree -u -m D
>  > >        $ git commit -m "My message"
>  > >        $ git cherry-pick E
>  > >        $ git cherry-pick F
>  >
>  > Plan B is looking good, because I'd generally like the commit message to
>  > be the concatenation of the messages for B,C and D.
>
>
> Replace the commit call by this:
>
>         $ for commit in B C D
>           do
>                 git cat-file commit $commit | sed '1,/^$/d'
>                 # possibly add an empty line between the commit messages,
>                 # git commit will strip away empty lines at the end.
>           done |
>           git commit -F -
>
>  Hth,
>  Dscho
That makes sense, many thanks.

Cheers, Geoff.

Boyd Stephen Smith Jr.· Jan 8, 2009, 02:11 UTC · re: Geoff Russell · lore

Re: collapsing commits with rebase

On Wednesday 2009 January 07 18:08:44 Geoff Russell wrote:
>I have a series of commits:
>
>    A---B---C---D---E---F

Assuming you also have a ref (e.g. Foo) that points to F: git checkout sha(B) git merge -s sha(D) git rebase --onto $(cat .git/HEAD) sha(E) Foo

should do what you want.

After the checkout: A -> B [HEAD] -> C -> D -> E -> F [Foo] (detached HEAD)

After the merge:
A -> B -> C -> D -> E -> F [Foo]
     |
     +--> [HEAD]
(detached HEAD)
After the rebase:
A -> B -> E' -> F' [Foo, HEAD]
     |
     +--> C -> D -> E -> F
(C, D, E, and F will be pruned at some point)
-- 
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
bss@iguanasuicide.net                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     
Miklos Vajna· Jan 8, 2009, 02:32 UTC · re: Boyd Stephen Smith Jr. · lore

Re: collapsing commits with rebase

On Wed, Jan 07, 2009 at 08:11:32PM -0600, "Boyd Stephen Smith Jr." <bss@iguanasuicide.net> wrote:
> git merge -s sha(D)

You probably mean --squash here, -s stands for --strategy - and I *hope* you don't have git-sha(D) in your PATH, as a custom merge strategy. ;-)

Boyd Stephen Smith Jr.· Jan 8, 2009, 02:39 UTC · re: Miklos Vajna · lore

Re: collapsing commits with rebase

On Wednesday 2009 January 07 20:32:24 Miklos Vajna wrote:
>On Wed, Jan 07, 2009 at 08:11:32PM -0600, "Boyd Stephen Smith Jr." 
<bss@iguanasuicide.net> wrote:
>> git merge -s sha(D)
>
>You probably mean --squash here, -s stands for --strategy - and I *hope*
>you don't have git-sha(D) in your PATH, as a custom merge strategy. ;-)
Oops.  Yes.  My mistake.
-- 
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
bss@iguanasuicide.net                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     
Geoff Russell· Jan 8, 2009, 09:49 UTC · re: Boyd Stephen Smith Jr. · lore

Re: collapsing commits with rebase

On 1/8/09, Boyd Stephen Smith Jr. <bss@iguanasuicide.net> wrote:
Show 8 quoted lines
> On Wednesday 2009 January 07 20:32:24 Miklos Vajna wrote:
>  >On Wed, Jan 07, 2009 at 08:11:32PM -0600, "Boyd Stephen Smith Jr."
>  <bss@iguanasuicide.net> wrote:
>  >> git merge -s sha(D)
>  >
>  >You probably mean --squash here, -s stands for --strategy - and I *hope*
>  >you don't have git-sha(D) in your PATH, as a custom merge strategy. ;-)
>
Many thanks, now I have plenty of ways to think about!

Cheers, Geoff.

Sitaram Chamarty· Jan 8, 2009, 04:09 UTC · re: Boyd Stephen Smith Jr. · lore

Re: collapsing commits with rebase

On 2009-01-08, Boyd Stephen Smith Jr. <bss@iguanasuicide.net> wrote:
>>    A---B---C---D---E---F
> Assuming you also have a ref (e.g. Foo) that points to F:
> git checkout sha(B)
> git merge -s sha(D)

I think you now need to do a commit (assuming you meant "--squash"). Squash will not commit, and your rebase below (if it runs at all -- I suspect it will refuse to run) will hard reset to B, the current HEAD. IOW

> After the merge:
> A -> B -> C -> D -> E -> F [Foo]
>      |
>      +--> [HEAD]
is not true.  You have C+D in the index, not in the tree.
> git rebase --onto $(cat .git/HEAD) sha(E) Foo

Also I think you have an off-by-one error here; you need sha(D) in that rebase command, not sha(E).

As your rebase command stands, you will lose commit E completely; neither the merge nor the rebase will pick it up.

[Haven't tested, but I *think* I understand rebase well enough now to say so...]

Boyd Stephen Smith Jr.· Jan 8, 2009, 04:23 UTC · re: Sitaram Chamarty · lore

Re: collapsing commits with rebase

On Wednesday 2009 January 07 22:09:15 Sitaram Chamarty wrote:
>[Haven't tested, but I *think* I understand rebase well
>enough now to say so...]

Probably understand it better than me. I just haven't needed to use it for this that much. This also might not be much better than setting GIT_PAGER to a script, but it seems less fragile to me.

-- 
Boyd Stephen Smith Jr.                     ,= ,-_-. =. 
bss@iguanasuicide.net                     ((_/)o o(\_))
ICQ: 514984 YM/AIM: DaTwinkDaddy           `-'(. .)`-' 
http://iguanasuicide.net/                      \_/     
nadim khemir· Jan 10, 2009, 10:26 UTC · re: Geoff Russell · lore

Re: collapsing commits with rebase

On Thursday 08 January 2009 01.08.44 Geoff Russell wrote:
Show 8 quoted lines
> Dear gits,
>
> I have a series of commits:
>
>     A---B---C---D---E---F
>
> I want to collapse B---C---D into one single commit. git rebase -i B  will
> allow me to do this, but I'm looking for a non-interactive incantation.

Hi Geoff, Could you please share with use the final (tested) solution? I'd be interrested to see how you did implement plan B if you did.

Cheers, Nadim.

← back to recent threads