

A Simple Explanation for Git Rebase - bradrobertson
http://infinitemonkeys.influitive.com/a-simple-explanation-for-git-rebase/

======
golergka
I tended to use git rebase constantly before pushing, until I realized how
toxic it really is.

In the original commit before rebase everything seemed to be working; but
someone changed something else in the code you were relying on without
creating a direct conflict, and now all your rebased commits crash and burn.
What's worse, you discover it much later, when original commits are long gone,
and instead of one merge commit being the easy traceable breaking point, you
now don't even quite remember which exact commits were rebased and have to
check EVERYTHING.

Or, and with merge commit you could've easily just check it right there with
simple tests before committing — no such convenient option for rebase.

The thing is, it's a leaky abstraction. Rebase workflow tries to present
things simpler then they really are, and you end up paying a price for it.

~~~
jambo
If you have a reasonably good+fast test suite and you integrate often, this
isn't a huge deal. Just run your tests after using rebase.

If you have a failure, having a straight-line history makes it easier to do a
bisect with your failing test and find the point of failure.

Unrelated to your issue with git rebase, but addressing another common
complaint, git rerere allows git to remember and reuse previous conflict
resolution so you don't get into resolution hell.

~~~
golergka
Unfortunately, I work on a project that (due to a various reasons) doesn't
have any kind of automated testing, and it would be pretty hard to implement
it. (But possible, and we definitely should do it in the future).

But thanks for git rerere! I've never heard about it.

------
tunesmith
I just never find rebase very relevant because we'll have team members
collaborate on the same branch. If you want to collaborate on an in-progress
story that has its own branch, you have to push your commits. You might be
able to rebase on any commits you push into the branch, but when it comes time
to merge the branch into the main line (which might have received several
commits in the meantime), you have to stick with the timeline of those pushes,
so you lose much of the benefit of rebase.

Not sure why the author says that is weird - I can't think of an alternative
if people are truly collaborating or pairing on a feature.

~~~
dcadenas
That's true but using branches is not always a good idea specially if you want
to collaborate in big projects and have strong communication with your team.

Master can be used as a chat room (substitute english with code) and leave
branches for very specific cases when that doesn't work. That's basically
doing continuous integration. If you prefer, you can think of it as if you are
still having branches with one commit each ;).

The important thing for CI is being sure that each commit is either hidden
(through a feature toggle maybe?) or it doesn't break anything.

------
azinman2
Thank you! I've always found this confusing and avoided it in my workflow.
Assuming this explanation is correct, it makes a lot of sense and gives me a
better workflow!

Are there any other useful ways to use git for a small team outside of pull
and rebase? One thing that's bugged me is undoing (possibly partially)
previous pushed commits while keeping everything past.

~~~
csense
Rebase throws away your commits and replaces them with different commits. OP
is using rebase to simply change the parent pointer, but git's interactive
mode is much more powerful. To enter interactive mode with e.g. the last five
commits, try this command on your favorite repository:

    
    
        git rebase -i HEAD~5
    

With this command, you can re-order commits. This is useful because often you
will write several commits for A, realize A depends on another feature B,
write several commits for B, then write several more commits for A. The
history would be easier to read if B was developed first, then A was developed
on top of it. Re-ordering the commits so all B commits are first accomplishes
this.

You can also use the same command to squash multiple commits into one. This is
useful when you write a commit, then have several commits gradually adding
temporary debugging statements and unit tests, then more commits to fix any
problems uncovered, then more commits to remove extensive print statements and
other temporary debugging code.

Assuming you get the code working, most of these commits will be totally
irrelevant to future development efforts. With the "squash" feature of git
rebase -i, you can condense all these commits into a single commit containing
only working code and unit tests, springing fully formed in a single commit,
like Athena from the head of Zeus.

The git rebase -i command will also let you re-word or edit commits; the
utility of those functions should be obvious.

~~~
richsinn
Nice explanation. When I was first learning git, the most intuitive
explanation of git rebase were these three links (if read in order... these
links were once published on Hacker News many moons ago):

(1) [http://gitready.com/intermediate/2009/01/31/intro-to-
rebase....](http://gitready.com/intermediate/2009/01/31/intro-to-rebase.html)

(2) [http://gitready.com/advanced/2009/02/11/pull-with-
rebase.htm...](http://gitready.com/advanced/2009/02/11/pull-with-rebase.html)

(3) [http://gitready.com/advanced/2009/03/20/reorder-commits-
with...](http://gitready.com/advanced/2009/03/20/reorder-commits-with-
rebase.html) <~ talks about "interactive mode" with the -i option

------
klochner
simple but unenlightening - I guess you hope no one asks you what's really
happening and just give up if you get a conflict.

It's not that complicated - rebase applies your commits to another branch as
if they were patches. Interactive rebase gives you the option of re-
ordering/removing/editing those patches before they're applied.

~~~
bradrobertson
Good call I'll update the post to mention resolving commits. This was not
intended to enlighten those who already know how rebase works.

------
middleclick
Can anyone document a simple workflow with three branches: main (public),
development (public) and feature (private).

~~~
zufallsheld
For three branches you can use the git-flow model.[0] Create a public repo,
pull it on your local development machine and only push the main and
development branch back to the public git repo. On github it is not possible
to have private branches. [0][http://danielkummer.github.io/git-flow-
cheatsheet/](http://danielkummer.github.io/git-flow-cheatsheet/)

