On Sat, 15 Dec 2007, Jakub Narebski wrote:
Michael Dressel <MichaelTiloDressel@xxxxxxxxxxx> 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?