
Git is an editor, and rebase is the backspace key - ColinWright
http://blog.izs.me/post/37650663670/git-rebase
======
chris_wot
I really recommend that this be a companion piece to Linus Torvald's own
advice, here:

    
    
      People can (and probably should) rebase their _private_ trees (their own 
      work). That's a _cleanup_. But never other peoples code.  
      That's a "destroy history"
    

[http://www.mail-archive.com/dri-
devel@lists.sourceforge.net/...](http://www.mail-archive.com/dri-
devel@lists.sourceforge.net/msg39091.html)

He then gives specific advice.

~~~
tonfa
Evolve for Mercurial (starting to show up in core mercurial) is trying to
cleanly solve this.

It provides (safe) mutable history for local changes (the VCS tracks what is
safe and what isn't), and a way to still be able to collaborate on changes
without "surprising" the people who pull from you.

E.g.: [http://draketo.de/light/english/mercurial/hg-
evolve-2013-01-...](http://draketo.de/light/english/mercurial/hg-
evolve-2013-01-12)

~~~
giulianob
Is there a difference between what he's talking about and phases that have
been in Mercurial for a little while?

~~~
tonfa
The vision was to have phase as the foundation for evolve.

We had some discussions as far back as mid-2010, at the time the feature was
called LiquidHg. The first step was phase (differentiate between changeset
states), and now it's evolve (make it flow).

------
jakub_g
Isaac has some controversial views at times (semicolon discussion anyone? ;)
but here I fully agree with him.

When working on a very long and complicated feature on an unknown terrain, I
commit "wip"s very frequently and rebase from time to time. I also frequently
fork branches (from "foo-wip-1" to "foo-wip-2") before rebasing just in case I
ever wanted to look at my messy history. When everything's done and thoroughly
tested I delete a batch of branches.

This might sound like an overkill but it costs you literally nothing and might
be useful sometimes.

------
mrmaloke
The most valuable feature from rebase to me is, that the one who commits to a
feature branch, also "merges" the branch to the current master. So right after
you finish your work on a branch, you can rebase even before having it
reviewed by another person. When it's good to go, the actual merge is fast-
forward.

~~~
calinet6
That's exactly it. In one sense, it's just a better, less annoying form of
merging. You get to sequence your commits on top of the current upstream
(literally _re-basing_ ) without a merge commit that makes little sense in
context. Then the ff-merge to master is also clean. I don't understand why
anyone would be against this.

~~~
ef4
It's not that anyone is against it _when it's possible to do it cleanly_. But
there are cases when that isn't true. Sometimes the branch is not ephemeral,
so rewriting it becomes messy and risky.

I frequently find myself fixing or extending some open source project that my
own systems depend on. Usually upstream will eventually take the patch,
sometimes they might not. But I can't wait around to find out -- my own
"master" branch gets deployed and lives a life of its own.

When upstream does get around the merging the changes, and I pull from
upstream, the merge is 100% safe and clean because git sees my own commits
coming back again. But if instead the changes were rebased, the chain of
history is broken and git needs to go into conflict resolution mode. If I've
changed other things since, I get a mess.

All of this gets even worse if you have things like continuous integration
servers and git-based deploys. Those systems will happily deal with merges and
break when you go and rebase a branch they've already seen.

------
skrebbel
I'd like to take this post out of context and comment on the HN-submitted
title alone. For me, it perfectly describes what i love about git _and_ what i
hate about git.

Git is indeed an editor, but it's like edlin.

It's not Vim or Textmate or Excel. I want a Git that _works_ like an editor,
not requiring me to keep in my head (or in some shell bells and whistles)
'where i am', and what I can or should do now. Not a UI frontend with buttons
for single-shot editing commands, but a real editor, that makes use of
2-dimensional space, to somehow really edit everything that matters to me
about versions and sharing and changes and all that.

It's a really powerful metaphor. Microsoft did something very right when they
released Windows Explorer with Win95, which treats your harddrive like it's a
document that you're editing (i bet it's a ripoff, but that's not the point
here). Copy, paste, undo, it's all there.

Can't we design something similar for distributed version control? How well
would document-editing metaphors map to git? My underbelly feeling says that
it might be a surprisingly good match, given the right visualization and
editing primitives.

~~~
saraid216
Well, in lieu of a really thoughtful response, let me ask this:

If Git is an editor, the obvious question is... what is it editing?

I'm guessing that the answer is "history", but that's fuzzy to me and I'd have
to think some more for a better answer.

~~~
pekk
The analogy with an editor seems weak to me, since pushed history shouldn't
change. But you are editing something like a tree of patches (changesets).

------
osener
The correct permalink to this post: <http://blog.izs.me/post/37650663670/git-
rebase>

------
mef
I really don't understand the advocacy of git bisect. Using git bisect boils
down to figuring out at which point in the history a change happened that
broke a test or introduced a bug. Having tried git-bisect five or six times,
I've found it's way slower for me than the tried and true method of:

1\. Something's broken. What part of the code is broken? (perhaps 5 minutes
tops?)

2\. git blame <file> (10 seconds)

3\. which lines in the trouble area were changed recently (10 seconds)

4\. git show <commit> to reveal what got changed in that commit and caused the
problem

In 99% of these cases the git blame is just to see what the other programmer
(or often myself) was trying to do at the time they broke the code -- in these
cases it's obvious what's broken, just not why it was changed.

When it's nontrivial to figure out where the code is broken and I have no clue
at which point in the history the code broke, it's still easier just to diff
the broken code to a known good branch or commit and look for significant
differences.

I guess where git bisect slows way down for me is that you have to devise code
that will indicate definitively that the bug exists. It's really never faster
for me than just eyeballing the troublesome code at that revision.

~~~
chriscool
If you work on a small code base, or if you know the code base perfectly, you
might get away with your "tried and true method" most of the time.

But if you are working on a code base with hundreds of commits per month, I
wish you a lot of luck. Your 10s of seconds might easily become days.

On a big codebase you might even want to automate bisecting as much as
possible. See <http://lwn.net/Articles/317154/> where Ingo Molnar says:

>>> for example git-bisect was godsent. I remember that years ago bisection of
a bug was a very [laborious] task so that it was only used as a final, last-
ditch approach for really nasty bugs. Today we can [autonomously] bisect build
bugs via a simple shell command around "git-bisect run", without any human
interaction!

~~~
lotyrin
> If you work on a small code base, or if you know the code base perfectly

Add to that "where bugs are guaranteed to appear in the same code path that
causes them", and it becomes immediately apparent the value of bisect.

------
crazygringo
I wish I could have both. Rebase to stick to single clean commit messages, but
still preserve the history/order of modifications within that, even without
the messages.

I might work on a project for a week, write some code, do an intermediate
commit, realize it's not needed, delete it. Then when I finally merge into
master (rebase), that code I wrote is forever gone. Which I think is fine, but
two months later I realize I could actually use it. But there's no way to get
at it, is there? Or am I missing something?

~~~
base698
_Or am I missing something?_

That you can create arbitrary branches and keep them forever remotely or
locally. If you think you'll need it branch off that point: git checkout -b
branch_i_may_need then checkout the previous branch. a git log
branch_i_may_need will always show the commit you needed at the top and git
cherry-pick `git rev-parse branch_i_may_need` will cherry pick it into
whatever branch you're on. That way you keep the commit and can still keep the
remote repo clean.

~~~
simcop2387
You can also avoid doing the two git checkouts by just doing "git branch
branch_i_may_need" and you'll stay in your current one. I do that all the
time, though i had no clue about git rev-parse. That's a great time saver.

------
baddox
> what does clean and tidy buy besides a sense of satisfaction?

What does _anything_ buy except for a sense of satisfaction?

------
0x0
This is great, this is just the way I try to use git as well, even down to the
--no-ff merges! :)

