On 1 June 2012 20:16, Dirkjan Ochtman <email@example.com> wrote:
> Can you elaborate on why the cleaner history a no-merge policy
> enforces is a good thing? I actually think that seeing merge commits
> might clarify the history; it can be valuable to see that some mistake
> was made in a merge instead, but you can only see that if there's an
> explicit merge commit.
> I should note that I come at this from the Mercurial side, where the
> immutability of (public) history has historically carried more value
> than on the git side (and related to that, rebase-like tools were less
> integrated until relatively recently).
One of the perk of fast-forward only histories is merge problems don't happen.
If a commit sequence isn't fast-fowardable, then the submitter has to
rebase it, and a rebased history is a guaranteed clean merge.
It also puts the onus on making the patch sequence mergable on the
contributor of that patch sequence, by forcing them to resolve
conflicts before they can submit their branch for inclusion, and this
is good, because they understand their own changes best, and are the
best person to decide how to deal with conflicts.
The best example of this is 2 people contribute behaviourally
identical code, with different syntax .
In the case of a merge, the person performing the merge has to decide
which one to take, and they might not be the best person to do so. (
And historically, it can be confusing if you look at the parents of
the merge, and find the 2 competing implementations, of which only 1
is relevant )
If you request that a branch is rebased before it is integrated, then
this problem solves itself in a way.
Whoevers implementation gets in the tree first gets in, and then the
second person rebases their branch on top of that.
In the process of performing the rebase, the second person will
discover the precise commit on their side that introduces a conflict,
and be able to decide if they need to replace the existing code
anyway, or if they need to destroy their own code.
And when they're done, their entire commit series should be sane and
logical as if the first persons code was there in the first place
before the second person even started coding.
Essentially, in this diagram, if d and y are different, but
equivalent, they will cause a collision when merge Z is performed.
By performing a rebase of the second branch, the logical order becomes
And when the rebaser is applying "y", they will notice it is likely
redundant, and the history will become
And in both the merge and rebase examples, z will be the same, just
the cognitive overhead of understanding "what the hell happened" in
the latter case is simpler, as the biggest delta between any 2 commits
will be 1 commit worth, whereas in the merge case, there will be a
huge delta between the commit before the merge, and the commit after
the merge, and looking at the merge itself diff-wise, you'll be
comparing the aggregate result of 2 entire branches worth of commits,
as opposed to only comparing one small and simple commit with another.
perl -e "print substr( \"edrgmaM SPA NOcomil.ic\\@tfrken\", \$_ * 3,
3 ) for ( 9,8,0,7,1,6,5,4,3,2 );"