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
threads / discuss / 11278
Subject: git merge --no-commit <branch>; does commit
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
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.
Re: git merge --no-commit <branch>; does commit
On 13/12/2007, Alex Riesen <raa.lkml@gmail.com> 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. >
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").
Re: git merge --no-commit <branch>; does commit
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.
Cheers, Michael
Re: git merge --no-commit <branch>; does commit
Michael Dressel, Thu, Dec 13, 2007 22:28:30 +0100:
> 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.
Re: git merge --no-commit <branch>; does commit
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? 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
Re: git merge --no-commit <branch>; does commit
On 2007.12.15 19:14:48 +0100, Michael Dressel wrote:
> > > 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.
> 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
Re: git merge --no-commit <branch>; does commit
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 <-- branch1.1. "git merge branch"
1---2---3---A---B---C--M <-- trunk <-- HEAD
\ /
\-a---b---c/ <-- branchM 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_HEADThe 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 <-- HEADRebase 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 <-- branch2. 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 <-- branch2.1. "git merge branch"
1---2---3 /----- trunk <-- HEAD
\ v
\-a---b---c <-- branchFast 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
Re: git merge --no-commit <branch>; does commit
On Sat, 15 Dec 2007, Jakub Narebski wrote:
> 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
Re: git merge --no-commit <branch>; does commit
Michael Dressel <MichaelTiloDressel@t-online.de> writes:
> 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
>> 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 <-- branchwhere *[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
Re: git merge --no-commit <branch>; does commit
On Sat, 15 Dec 2007, Jakub Narebski wrote:
> 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
Re: git merge --no-commit <branch>; does commit
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.
> 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).
Re: git merge --no-commit <branch>; does commit
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.
> >> 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
Re: git merge --no-commit <branch>; does commit
Michael Dressel, Sat, Dec 15, 2007 21:33:20 +0100:
> 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.