Robert Bradshaw <rober...@math.washington.edu> writes:
> Though for a single commit, a rebase is cleaner IMHO than a merge, 

The problem with rebasing is that unless you do it manually, the actual
commits (i.e. snapshots of the codebase) do not necessarily represent code that
anyone has actually looked at. Just because a merge or rebase is
possible to resolve automatically doesn't mean that it the result is
what you intended. With merging, you isolate this badness in the merge
commit, and can commit on top of your merge to fix any incompatibilities
between your original code and the current state of the other branch:

X --------------- Y --- Z
 \                       \
  A --- B --- C --- D --- M --- E

Changes made in A through D do not directly conflict with changes made
in Y and Z, but the changes in Y and Z make the code added in A through
D perform differently from expected. The change in E fixes this. Every
commit here except M represents a state of the codebase that was
considered coherent and correct by whoever authored the commit.

Now in the case of rebasing, you get this:

X --- Y --- Z
 \           \
  \           A'--- B'--- C'--- D' --- E
   \
    A - - B - - C - - D   <- - (these will disappear)

As before, changes made in A through D do not directly conflict with
changes made in Y and Z, so the user rebases A through D to A' through
D' automatically. But now, none of A' through D' represent states of the
codebase that were considered coherent and correct by the people who
made A through D respectively, even though A' through D' bear the names
of those people in their headers.

Furthermore, once any problems in the interaction between Y or Z and A
through D become apparent, they are recorded in E, but these changes are
already several nodes away from Z, and so appear out of their natural
context.

Worse, A through D will either hang around in other people's
repositories, confusing matters, or, if you were wise and didn't share
commits that you later rebased, they have disappeared and, once garbage
collected, are not recoverable.

I think the above is still true when A through D is actually A through A
(i.e. a single commit).

> and
> squashing commits improves the signal-to-noise ratio of the history
> (and it's nice to be able to squash away stuff like typos).

You can `git commit --amend` away stuff like typos, but squashing is bad
for various reasons. The obvious ones are preserving history, observing
developer intent in context, logical breakdown of large code changes,
etc., but another important one is that merges can be done automatically
more easily if commits are small.

If we follow IPython's lead and never commit directly to the master
branch, only merging into it, then `git log --merges` basically gives
you your squashed commits without actually destroying the originals.

-Keshav

----
Join us in #sagemath on irc.freenode.net !

-- 
To post to this group, send an email to sage-devel@googlegroups.com
To unsubscribe from this group, send an email to 
sage-devel+unsubscr...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/sage-devel
URL: http://www.sagemath.org

Reply via email to