threads / discuss / 11278

git merge --no-commit <branch>; does commit

Subject: git merge --no-commit <branch>; does commit

## tl;dr

14 messages between Dec 13, 2007 and Dec 16, 2007.

replies: 13people: 4as markdown or json

Michael Dressel· Dec 13, 2007, 21:01 UTC · lore
Hi,

git merge --no-commit <branch> does "create" a commit. At lesat the head and index are moved to the new commit fetched from <branch>. Maybe that is because git was able to do a fast forward?

Cheers, Michael

Alex Riesen· Dec 13, 2007, 21:19 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

On 13/12/2007, Michael Dressel <MichaelTiloDressel@t-online.de> wrote:
> git merge --no-commit <branch> does "create" a commit. At lesat the
> head and index are moved to the new commit fetched from <branch>. Maybe
> that is because git was able to do a fast forward?

Yes. Because fast-forward is what it called: fast-forward. It does not do any commits at all.

Alex Riesen· Dec 13, 2007, 21:23 UTC · re: Alex Riesen · lore

Re: git merge --no-commit <branch>; does commit

On 13/12/2007, Alex Riesen <raa.lkml@gmail.com> wrote:
Show 8 quoted lines
> On 13/12/2007, Michael Dressel <MichaelTiloDressel@t-online.de> wrote:
> > git merge --no-commit <branch> does "create" a commit. At lesat the
> > head and index are moved to the new commit fetched from <branch>. Maybe
> > that is because git was able to do a fast forward?
>
> Yes. Because fast-forward is what it called: fast-forward.
> It does not do any commits at all.
>

If you have a very recent git, you can avoid fast-forward when merging by running with --no-ff. It has it's problems in general case, so it is not default (see the git ml archive for "fast-forward does not commit").

Michael Dressel· Dec 13, 2007, 21:28 UTC · re: Alex Riesen · lore

Re: git merge --no-commit <branch>; does commit

On Thu, 13 Dec 2007, Alex Riesen wrote:
Show 8 quoted lines
> On 13/12/2007, Michael Dressel <MichaelTiloDressel@t-online.de> wrote:
>> git merge --no-commit <branch> does "create" a commit. At lesat the
>> head and index are moved to the new commit fetched from <branch>. Maybe
>> that is because git was able to do a fast forward?
>
> Yes. Because fast-forward is what it called: fast-forward.
> It does not do any commits at all.
>

It looks like I misunderstood the meaning of --no-commit. I have to use --squash in this case.

Cheers, Michael

Alex Riesen· Dec 14, 2007, 07:49 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

Michael Dressel, Thu, Dec 13, 2007 22:28:30 +0100:
Show 13 quoted lines
> On Thu, 13 Dec 2007, Alex Riesen wrote:
>> On 13/12/2007, Michael Dressel <MichaelTiloDressel@t-online.de> wrote:
>>> git merge --no-commit <branch> does "create" a commit. At lesat the
>>> head and index are moved to the new commit fetched from <branch>. Maybe
>>> that is because git was able to do a fast forward?
>>
>> Yes. Because fast-forward is what it called: fast-forward.
>> It does not do any commits at all.
>>
>
> It looks like I misunderstood the meaning of --no-commit. I have to use 
> --squash in this case.
>

Maybe. Or maybe you misunderstood the meaning of --squash, which also is not a merge.

Michael Dressel· Dec 15, 2007, 18:14 UTC · re: Alex Riesen · lore

Re: git merge --no-commit <branch>; does commit

On Fri, 14 Dec 2007, Alex Riesen wrote:
Show 17 quoted lines
> Michael Dressel, Thu, Dec 13, 2007 22:28:30 +0100:
>> On Thu, 13 Dec 2007, Alex Riesen wrote:
>>> On 13/12/2007, Michael Dressel wrote:
>>>> git merge --no-commit <branch> does "create" a commit. At lesat the
>>>> head and index are moved to the new commit fetched from <branch>. Maybe
>>>> that is because git was able to do a fast forward?
>>>
>>> Yes. Because fast-forward is what it called: fast-forward.
>>> It does not do any commits at all.
>>>
>>
>> It looks like I misunderstood the meaning of --no-commit. I have to use
>> --squash in this case.
>>
>
> Maybe. Or maybe you misunderstood the meaning of --squash, which also
> is not a merge.

Since "git merge --squash <branch>" does a merge of <branch> into the working tree why would you not call it a merge? Anyway that was what I wanted. Merging <branch> (a topic branch) into my current branch (the main branch) but being able to create commits that are more suitable for keeping in the history of the current branch than the commits I created during developing on <branch>. Would you recommend a different way of doing this?

Thank you, Michael

Björn Steinbrink· Dec 15, 2007, 18:26 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

On 2007.12.15 19:14:48 +0100, Michael Dressel wrote:
Show 24 quoted lines
>
>
> On Fri, 14 Dec 2007, Alex Riesen wrote:
>
>> Michael Dressel, Thu, Dec 13, 2007 22:28:30 +0100:
>>> On Thu, 13 Dec 2007, Alex Riesen wrote:
>>>> On 13/12/2007, Michael Dressel wrote:
>>>>> git merge --no-commit <branch> does "create" a commit. At lesat the
>>>>> head and index are moved to the new commit fetched from <branch>. Maybe
>>>>> that is because git was able to do a fast forward?
>>>>
>>>> Yes. Because fast-forward is what it called: fast-forward.
>>>> It does not do any commits at all.
>>>>
>>>
>>> It looks like I misunderstood the meaning of --no-commit. I have to use
>>> --squash in this case.
>>>
>>
>> Maybe. Or maybe you misunderstood the meaning of --squash, which also
>> is not a merge.
>
> Since "git merge --squash <branch>" does a merge of <branch> into the 
> working tree why would you not call it a merge?

A "real" merge commit has at least two parents, and retains the individual commits of each branch in the history. It just connects two lines of history. --squash just takes all changes and produces a single-parented commit, destroying the individual commits that originally introduced the changes.

Show 5 quoted lines
> Anyway that was what I wanted. Merging <branch> (a topic branch) into my 
> current branch (the main branch) but being able to create commits that are
> more suitable for keeping in the history of the current branch than the
> commits I created during developing on <branch>.
> Would you recommend a different way of doing this?

If you didn't publish your topic branch, use interactive rebasing to re-order/edit your commits.

Björn
Jakub Narebski· Dec 15, 2007, 19:18 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

Michael Dressel <MichaelTiloDressel@t-online.de> writes:
Show 22 quoted lines
> On Fri, 14 Dec 2007, Alex Riesen wrote:
> 
>> Michael Dressel, Thu, Dec 13, 2007 22:28:30 +0100:
>>> On Thu, 13 Dec 2007, Alex Riesen wrote:
>>>> On 13/12/2007, Michael Dressel wrote:
>>>>> git merge --no-commit <branch> does "create" a commit. At lesat the
>>>>> head and index are moved to the new commit fetched from <branch>. Maybe
>>>>> that is because git was able to do a fast forward?
>>>>
>>>> Yes. Because fast-forward is what it called: fast-forward.
>>>> It does not do any commits at all.
>>>>
>>>
>>> It looks like I misunderstood the meaning of --no-commit. I have to use
>>> --squash in this case.
>>>
>>
>> Maybe. Or maybe you misunderstood the meaning of --squash, which also
>> is not a merge.
> 
> Since "git merge --squash <branch>" does a merge of <branch> into the
> working tree why would you not call it a merge?

A few illustrations. Commits A, B, C were made on 'trunk', commits a, b, c were made on 'branch'. You are on 'trunk', running "git merge <options> branch". We assume that there are no conflicts.

1. A non fast-forward case
   1---2---3---A---B---C   <-- trunk    <-- HEAD
            \
             \-a---b---c   <-- branch
1.1. "git merge branch"
   1---2---3---A---B---C--M   <-- trunk  <-- HEAD
            \            /
             \-a---b---c/     <-- branch

M is _merge_ commits, with two parents: C and c. It was created by "git merge branch".

1.2. "git merge --no-commit branch"
                        /-------- trunk  <-- HEAD
                       v
   1---2---3---A---B---C--*
            \            /
             \-a---b---c/     <-- branch
                       ^                           
                        \-------- MERGE_HEAD

The merge commit '*' is prepared, but not yet committed, just as if there were merge conflict during merge. "git commit" would commit a merge (and would tell you that it does a merge commit).

1.3. "git merge --no-commit --no-ff branch"
Like in 1.2, because it is non fast-forward case.
1.4. "git merge --squash branch"
   1---2---3---A---B---C--[abc]'   <-- trunk <-- HEAD
            \
             \-a---b---c           <-- branch

"[abc]'" is a _single parent_ commit (it is not a merge commit!) which incorporates changes made on branch as if it were made in a single, large (!) commit.

1.5. "git rebase trunk branch" (or "git pull --rebase branch")
   1---2---3---A---B---C              <-- trunk    
                        \
                         \-a'--b'--c' <-- branch  <-- HEAD

Rebase is step-by-step process, replying commits a, b, c on top of trunk, trying for the same _changes_. a', b', c' are newly created commits, introducing the same changes as a, b, c if there were no rebase conflicts.

I think that "git pull --rebase branch" goes a step further and actually does after-rebase fast-forward merge, and does not change branch, but I might be mistaken.

   1---2---3---A---B---C---a'--b'--c'  <-- trunk <-- HEAD
            \
             \-a---b---c               <-- branch
2. Fast forward case; there are no commits A, B, C, and we
start from the following situation:
   1---2---3               <-- trunk    <-- HEAD
            \
             \-a---b---c   <-- branch
2.1. "git merge branch"
   1---2---3            /----- trunk    <-- HEAD
            \          v
             \-a---b---c   <-- branch

Fast forward results in simply moving the head of trunk. It does not create a commit, hence:

2.2. "git merge --no-commit branch"
Like in 2.1, because fast-forwarding does not create a commit.
2.3. "git merge --no-commit --no-ff branch"
   1---2---3               <-- trunk    <-- HEAD
            \
             \-a---b---c   <-- branch
(probably with some error message).

Test of understanding the concepts: what does "git merge --squash --no-commit" does?

-- 
Jakub Narebski
Poland
ShadeHawk on #git
Michael Dressel· Dec 15, 2007, 20:22 UTC · re: Jakub Narebski · lore

Re: git merge --no-commit <branch>; does commit

On Sat, 15 Dec 2007, Jakub Narebski wrote:
Show 121 quoted lines
> Michael Dressel <MichaelTiloDressel@t-online.de> writes:
>
>> On Fri, 14 Dec 2007, Alex Riesen wrote:
>>
>>> Michael Dressel, Thu, Dec 13, 2007 22:28:30 +0100:
>>>> On Thu, 13 Dec 2007, Alex Riesen wrote:
>>>>> On 13/12/2007, Michael Dressel wrote:
>>>>>> git merge --no-commit <branch> does "create" a commit. At lesat the
>>>>>> head and index are moved to the new commit fetched from <branch>. Maybe
>>>>>> that is because git was able to do a fast forward?
>>>>>
>>>>> Yes. Because fast-forward is what it called: fast-forward.
>>>>> It does not do any commits at all.
>>>>>
>>>>
>>>> It looks like I misunderstood the meaning of --no-commit. I have to use
>>>> --squash in this case.
>>>>
>>>
>>> Maybe. Or maybe you misunderstood the meaning of --squash, which also
>>> is not a merge.
>>
>> Since "git merge --squash <branch>" does a merge of <branch> into the
>> working tree why would you not call it a merge?
>
> A few illustrations. Commits A, B, C were made on 'trunk', commits
> a, b, c were made on 'branch'. You are on 'trunk', running
> "git merge <options> branch". We assume that there are no conflicts.
>
> 1. A non fast-forward case
>
>   1---2---3---A---B---C   <-- trunk    <-- HEAD
>            \
>             \-a---b---c   <-- branch
>
> 1.1. "git merge branch"
>
>   1---2---3---A---B---C--M   <-- trunk  <-- HEAD
>            \            /
>             \-a---b---c/     <-- branch
>
> M is _merge_ commits, with two parents: C and c. It was created
> by "git merge branch".
>
> 1.2. "git merge --no-commit branch"
>
>                        /-------- trunk  <-- HEAD
>                       v
>   1---2---3---A---B---C--*
>            \            /
>             \-a---b---c/     <-- branch
>                       ^
>                        \-------- MERGE_HEAD
>
> The merge commit '*' is prepared, but not yet committed, just
> as if there were merge conflict during merge. "git commit"
> would commit a merge (and would tell you that it does a merge
> commit).
>
> 1.3. "git merge --no-commit --no-ff branch"
>
> Like in 1.2, because it is non fast-forward case.
>
> 1.4. "git merge --squash branch"
>
>   1---2---3---A---B---C--[abc]'   <-- trunk <-- HEAD
>            \
>             \-a---b---c           <-- branch
>
> "[abc]'" is a _single parent_ commit (it is not a merge commit!)
> which incorporates changes made on branch as if it were made in
> a single, large (!) commit.
>
> 1.5. "git rebase trunk branch" (or "git pull --rebase branch")
>
>   1---2---3---A---B---C              <-- trunk
>                        \
>                         \-a'--b'--c' <-- branch  <-- HEAD
>
> Rebase is step-by-step process, replying commits a, b, c on top
> of trunk, trying for the same _changes_. a', b', c' are newly
> created commits, introducing the same changes as a, b, c if there
> were no rebase conflicts.
>
> I think that "git pull --rebase branch" goes a step further and
> actually does after-rebase fast-forward merge, and does not change
> branch, but I might be mistaken.
>
>   1---2---3---A---B---C---a'--b'--c'  <-- trunk <-- HEAD
>            \
>             \-a---b---c               <-- branch
>
>
> 2. Fast forward case; there are no commits A, B, C, and we
> start from the following situation:
>
>   1---2---3               <-- trunk    <-- HEAD
>            \
>             \-a---b---c   <-- branch
>
> 2.1. "git merge branch"
>
>   1---2---3            /----- trunk    <-- HEAD
>            \          v
>             \-a---b---c   <-- branch
>
> Fast forward results in simply moving the head of trunk.
> It does not create a commit, hence:
>
> 2.2. "git merge --no-commit branch"
>
> Like in 2.1, because fast-forwarding does not create a commit.
>
> 2.3. "git merge --no-commit --no-ff branch"
>
>   1---2---3               <-- trunk    <-- HEAD
>            \
>             \-a---b---c   <-- branch
>
> (probably with some error message).
>
Thanks alot for the elaborate explanations.
>
> Test of understanding the concepts: what does
> "git merge --squash --no-commit" does?
>
>From the man page it sounds "git merge --squash --no-commit" would do the 

same as "git merge --squash". So in the example 1.4 [abc] should not be a commit.

Cheers, Michael

Jakub Narebski· Dec 15, 2007, 20:57 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

Michael Dressel <MichaelTiloDressel@t-online.de> writes:
Show 15 quoted lines
> On Sat, 15 Dec 2007, Jakub Narebski wrote:
>> Michael Dressel <MichaelTiloDressel@t-online.de> writes:
>>>
>>> Since "git merge --squash <branch>" does a merge of <branch> into the
>>> working tree why would you not call it a merge?
>>
>> A few illustrations. Commits A, B, C were made on 'trunk', commits
>> a, b, c were made on 'branch'. You are on 'trunk', running
>> "git merge <options> branch". We assume that there are no conflicts.
>>
>> 1. A non fast-forward case
>>
>>   1---2---3---A---B---C   <-- trunk    <-- HEAD
>>            \
>>             \-a---b---c   <-- branch
Show 14 quoted lines
>> 1.2. "git merge --no-commit branch"
>>
>>                        /-------- trunk  <-- HEAD
>>                       v
>>   1---2---3---A---B---C--*
>>            \            /
>>             \-a---b---c/     <-- branch
>>                       ^
>>                        \-------- MERGE_HEAD
>>
>> The merge commit '*' is prepared, but not yet committed, just
>> as if there were merge conflict during merge. "git commit"
>> would commit a merge (and would tell you that it does a merge
>> commit).
Show 11 quoted lines
>> 1.4. "git merge --squash branch"
>>
>>   1---2---3---A---B---C--[abc]'   <-- trunk <-- HEAD
>>            \
>>             \-a---b---c           <-- branch
>>
>> "[abc]'" is a _single parent_ commit (it is not a merge commit!)
>> which incorporates changes made on branch as if it were made in
>> a single, large (!) commit.
> 
> Thanks alot for the elaborate explanations.
You are welcome
 
Show 7 quoted lines
>> Test of understanding the concepts: what does
>> "git merge --squash --no-commit" does?
>>
> 
> From the man page it sounds "git merge --squash --no-commit" would do
> the same as "git merge --squash". So in the example 1.4 [abc] should
> not be a commit.
                       /---------\
                       v          \
   1---2---3---A---B---C--*[abc]'  \-- trunk <-- HEAD
            \
             \-a---b---c           <-- branch

where *[abc]' is prepared state (staged but not committed changes) squashing achanges into commits a, b, c into trunk.

Note that using "git rebase --interactive" you can squash, reorder and edit commits; if you rather work in this way, reordering, editing etc. "on the go" you perhaps should consider patch-management interfaces like StGIT (Stacked GIT) or Guilt (formerly gq).

BTW. in practice [abc]' in squash case is the same as M in normal case, only M has two parents recorded, and [abc]' does not.

-- 
Jakub Narebski
Poland
ShadeHawk on #git
Michael Dressel· Dec 15, 2007, 21:15 UTC · re: Jakub Narebski · lore

Re: git merge --no-commit <branch>; does commit

On Sat, 15 Dec 2007, Jakub Narebski wrote:
Show 70 quoted lines
> Michael Dressel writes:
>> On Sat, 15 Dec 2007, Jakub Narebski wrote:
>>> Michael Dressel writes:
>>>>
>>>> Since "git merge --squash <branch>" does a merge of <branch> into the
>>>> working tree why would you not call it a merge?
>>>
>>> A few illustrations. Commits A, B, C were made on 'trunk', commits
>>> a, b, c were made on 'branch'. You are on 'trunk', running
>>> "git merge <options> branch". We assume that there are no conflicts.
>>>
>>> 1. A non fast-forward case
>>>
>>>   1---2---3---A---B---C   <-- trunk    <-- HEAD
>>>            \
>>>             \-a---b---c   <-- branch
>
>>> 1.2. "git merge --no-commit branch"
>>>
>>>                        /-------- trunk  <-- HEAD
>>>                       v
>>>   1---2---3---A---B---C--*
>>>            \            /
>>>             \-a---b---c/     <-- branch
>>>                       ^
>>>                        \-------- MERGE_HEAD
>>>
>>> The merge commit '*' is prepared, but not yet committed, just
>>> as if there were merge conflict during merge. "git commit"
>>> would commit a merge (and would tell you that it does a merge
>>> commit).
>
>>> 1.4. "git merge --squash branch"
>>>
>>>   1---2---3---A---B---C--[abc]'   <-- trunk <-- HEAD
>>>            \
>>>             \-a---b---c           <-- branch
>>>
>>> "[abc]'" is a _single parent_ commit (it is not a merge commit!)
>>> which incorporates changes made on branch as if it were made in
>>> a single, large (!) commit.
>>
>> Thanks alot for the elaborate explanations.
>
> You are welcome
>
>>> Test of understanding the concepts: what does
>>> "git merge --squash --no-commit" does?
>>>
>>
>> From the man page it sounds "git merge --squash --no-commit" would do
>> the same as "git merge --squash". So in the example 1.4 [abc] should
>> not be a commit.
>
>                       /---------\
>                       v          \
>   1---2---3---A---B---C--*[abc]'  \-- trunk <-- HEAD
>            \
>             \-a---b---c           <-- branch
>
> where *[abc]' is prepared state (staged but not committed changes)
> squashing achanges into commits a, b, c into trunk.
>
> Note that using "git rebase --interactive" you can squash, reorder
> and edit commits; if you rather work in this way, reordering, editing
> etc. "on the go" you perhaps should consider patch-management
> interfaces like StGIT (Stacked GIT) or Guilt (formerly gq).
>
> BTW. in practice [abc]' in squash case is the same as M in normal
> case, only M has two parents recorded, and [abc]' does not.
Thanks again. There is a lot for me to practice now.

Cheers, Michael

Alex Riesen· Dec 15, 2007, 19:37 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

Michael Dressel, Sat, Dec 15, 2007 19:14:48 +0100:
Show 5 quoted lines
>> Maybe. Or maybe you misunderstood the meaning of --squash, which also
>> is not a merge.
>
> Since "git merge --squash <branch>" does a merge of <branch> into the 
> working tree why would you not call it a merge?

Because merge, in Git language, means connection histories. That one just mixes the text. That's different operation, kind of editing a file.

Show 5 quoted lines
> Anyway that was what I wanted. Merging <branch> (a topic branch) into my 
> current branch (the main branch) but being able to create commits that are
> more suitable for keeping in the history of the current branch than the
> commits I created during developing on <branch>.
> Would you recommend a different way of doing this?

I would not recommend doing it at all. If I must, I'd rather use git-rebase -i (interactive rebase).

Michael Dressel· Dec 15, 2007, 20:33 UTC · re: Alex Riesen · lore

Re: git merge --no-commit <branch>; does commit

On Sat, 15 Dec 2007, Alex Riesen wrote:
Show 10 quoted lines
> Michael Dressel, Sat, Dec 15, 2007 19:14:48 +0100:
>>> Maybe. Or maybe you misunderstood the meaning of --squash, which also
>>> is not a merge.
>>
>> Since "git merge --squash <branch>" does a merge of <branch> into the
>> working tree why would you not call it a merge?
>
> Because merge, in Git language, means connection histories. That one
> just mixes the text. That's different operation, kind of editing a
> file.

That's a nice clarification. In my case I wanted that "just mixes the text" thing because I did aggressively do commits during development trying out slightly different approaches and being able to go back to compare them. These different games are not interesting to keep in the history once a good solution has been found.

Show 11 quoted lines
>
>> Anyway that was what I wanted. Merging <branch> (a topic branch) into my
>> current branch (the main branch) but being able to create commits that are
>> more suitable for keeping in the history of the current branch than the
>> commits I created during developing on <branch>.
>> Would you recommend a different way of doing this?
>
> I would not recommend doing it at all. If I must, I'd rather use
> git-rebase -i (interactive rebase).
>
>
Yes I didn't use rebase sofar. I should consider it sometimes.

Cheers, Michael

Alex Riesen· Dec 16, 2007, 10:53 UTC · re: Michael Dressel · lore

Re: git merge --no-commit <branch>; does commit

Michael Dressel, Sat, Dec 15, 2007 21:33:20 +0100:
Show 17 quoted lines
> On Sat, 15 Dec 2007, Alex Riesen wrote:
>> Michael Dressel, Sat, Dec 15, 2007 19:14:48 +0100:
>>>> Maybe. Or maybe you misunderstood the meaning of --squash, which also
>>>> is not a merge.
>>>
>>> Since "git merge --squash <branch>" does a merge of <branch> into the
>>> working tree why would you not call it a merge?
>>
>> Because merge, in Git language, means connection histories. That one
>> just mixes the text. That's different operation, kind of editing a
>> file.
>
> That's a nice clarification. In my case I wanted that "just mixes the text" 
> thing because I did aggressively do commits during development trying out 
> slightly different approaches and being able to go back to compare them. 
> These different games are not interesting to keep in the history once a 
> good solution has been found.

In this case --squash is almost right. "rebase -i" (interactive rebase) still better: it'll allow you rebuild the development history in a more fine-grained way. It can reorder commits, "mix" them together, edit commit messages or just delete them altogether. Try it, by the look of your situation you'll like it. Actually, it is exactly why Johannes wrote it.

← back to recent threads