Rich Freeman on 21 Dec 2018 15:10:09 -0800


[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]

Re: [PLUG] Git: net time gain or loss?


On Fri, Dec 21, 2018 at 5:02 PM Fred Stluka <fred@bristle.com> wrote:
>
> On 12/20/18 9:23 PM, Aaron Mulder wrote:
> > But those merge commits are dang ugly, and rebase seems to be a clever
> > option to avoid that... granted one that can be a big headache to
> > understand and adjusts the history a bit and could be completely
> > unnecessary if not for the distributed nature of the thing.
>
> Merge commits are fine, I think.  Merge conflicts are a pain, but
> are you saying that all merge commits are ugly.  Why?
>
> Also, how does rebase help?  A couple people have said that now,
> so I must be missing something.  Enlighten me?
>

So, this is a somewhat religious topic.

When using rebase you get a linear-ized history, as if every commit
was made against the one coming before.  When using a merge you get a
branching history, whether those branches were explicit or implicit.

Let me give an example from Gentoo, formatted using tig.  Here is our
main development repository where almost all commits are rebased:
2018-12-20 22:56 Matthew Thode                             o [master]
{origin/master} {github/master} {origin/HEAD} app-admin/puppet:
4.10.12 stable amd64 and x86 with cleanup
2018-12-20 22:55 Matthew Thode                             o
www-apps/icingaweb2: 2.6.2 stable amd64 and x86
2018-12-20 20:16 Georgy Yakovlev                           o
app-shells/mcfly: fix typo in postinst message
2018-12-20 20:11 Georgy Yakovlev                           o
dev-python/pyTenable: drop old
2018-12-20 20:10 Georgy Yakovlev                           o
dev-python/pyTenable: bump to 0.3.7
2018-12-20 21:17 Anthony G. Basile                         o
net-vpn/tor: remove older stable version
2018-12-20 21:16 Anthony G. Basile                         o
net-vpn/tor: remove older alphas
2018-12-20 21:15 Anthony G. Basile                         o
net-vpn/tor: version bump to 0.3.5.6_rc
2018-12-20 17:41 Patrick McLean                            o
virtual/cargo: Version bump to 1.31.1
2018-12-20 17:41 Patrick McLean                            o
virtual/rust: Version bump to 1.31.1

Now, here is a similar repository after it goes through a layer of CI
that does some QA to ensure only passing commits end up on time.  It
fetches and merges groups of commits, adding some extra stuff and
signatures to the history:
2018-12-21 05:04 Repository mirror & CI                    o [stable]
{origin/stable} {origin/HEAD} 2018-12-21 05:04:21 UTC
2018-12-21 05:04 Repository mirror & CI                    M─┐ Merge
updates from master
2018-12-20 22:56 Matthew Thode                             │ o
app-admin/puppet: 4.10.12 stable amd64 and x86 with cleanup
2018-12-20 22:55 Matthew Thode                             │ o
www-apps/icingaweb2: 2.6.2 stable amd64 and x86
2018-12-21 04:24 Repository mirror & CI                    o │
2018-12-21 04:24:16 UTC
2018-12-21 04:23 Repository mirror & CI                    M─│─┐ Merge
updates from master
2018-12-20 20:16 Georgy Yakovlev                           │ o─┘
app-shells/mcfly: fix typo in postinst message
2018-12-20 20:11 Georgy Yakovlev                           │ o
dev-python/pyTenable: drop old
2018-12-20 20:10 Georgy Yakovlev                           │ o
dev-python/pyTenable: bump to 0.3.7
2018-12-21 02:24 Repository mirror & CI                    o │
2018-12-21 02:24:18 UTC
2018-12-21 02:24 Repository mirror & CI                    M─│─┐ Merge
updates from master
2018-12-20 21:17 Anthony G. Basile                         │ o─┘
net-vpn/tor: remove older stable version
2018-12-20 21:16 Anthony G. Basile                         │ o
net-vpn/tor: remove older alphas
2018-12-20 21:15 Anthony G. Basile                         │ o
net-vpn/tor: version bump to 0.3.5.6_rc
2018-12-21 02:04 Repository mirror & CI                    o │
2018-12-21 02:04:24 UTC

(you'll want to use a monospaced font to view all that)

What starts out as a completely linear history gets turned into these
two dovetailing merged histories which are harder to follow.

When there really is parallel development going on then the merges
capture information about the actual history of the repository.
However, when you really have a linear flow with just one-off commits
happening in parallel you get these merge commits everywhere that
makes it harder to traverse the history.

If you want to do an automated traversal of the repository commit
history this is trivial with rebasing, and more complex with merges.
Which parent is the "real" one?

Gentoo discussed this at length and documented its policy as follows
(which I think is pretty typical):
https://www.gentoo.org/glep/glep-0066.html#merge-commits

> The use of merge commits in the Gentoo repository is strongly
> discouraged. Usually it is preferable to rebase instead. However, the
> developers are allowed to use merge commits in justified cases. Merge
> commits can be only used to merge additional branches, the use of
> implicit git pull merges is entirely forbidden.
>
> In a merge commit that is committed straight to the Gentoo repository,
> the first parent is expected to reference an actual Gentoo commit
> preceding the merge, while the remaining parents can be used to
> reference commits originating from external repositories. The commits
> on the ancestry path of the first parent (up to the next merge
> commit) are required to conform to this specification. The commits on
> remaining ancestry paths can use relaxed rules.

In the case of a genuine branching workflow, where you create a
feature branch, QA it, and then merge it, the merge commit is
completely appropriate and clearly reflects the actual development
history.

Now, one thing people dislike about rebasing is that it "rewrites
history."  This isn't to say that it actually CHANGES history - git
history is completely immutable.  It creates a new copy of history,
distinct from the old one, which might still continue to exist.
Indeed, if you're using gpg signatures in your repository then these
signatures will be lost in the new history, or substituted with new
ones (which obviously requires the appropriate signing key).  Commit
2914c180223 will always be what it always was - it just may or may not
end up in the branch that actually gets further used.

Strictly speaking though there is nothing wrong with merge commits.
It is a matter of opinion as to whether the additional information
they preserve is actually useful, or clutter.

-- 
Rich
___________________________________________________________________________
Philadelphia Linux Users Group         --        http://www.phillylinux.org
Announcements - http://lists.phillylinux.org/mailman/listinfo/plug-announce
General Discussion  --   http://lists.phillylinux.org/mailman/listinfo/plug