
Linus on git rebase and merge (2009) - Brajeshwar
http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html
======
morsch
One of his points is that you should only pull rarely:

    
    
       And, in fact, preferably you don't pull my tree at ALL, since nothing 
       in my tree should be relevant to the development work _you_ do. 
       Sometimes you have to (in order to solve some particularly nasty 
       dependency issue), but it should be a very rare and special thing, and 
       you should think very hard about it.
    

That might work well for the kind of highly decoupled development he's dealing
with, but I'm not sure it'll work for the kind of work I do with my
colleagues. The first thing I do every morning is a _git pull_ (often
surrounded by _git stash [pop]_ and sometimes with a _\--rebase_ appended if I
have outgoing commits), because I might need the stuff a colleague worked on
the past days, or we might work in the same files and generate lots of
conflicts otherwise. Maybe I'm doing it wrong.

~~~
crististm
Linus comments is valid in your case: your colleague's work is relevant to
you, thus you have a reason to pull. Otherwise, pulling on a time base will
give you little benefit besides the occasional breaking of your stuff.

If you review now Linus comment, it makes sense that pulling should be done on
a feature branch: one that has a complete, working solution of something you
need.

~~~
IgorPartola
An alternative that worked really well for me is "do not push broken code".
Linus is saying "If you pull at a random time, you might get cruft in your
local tree". Why is that? There should be no cruft upstream from you. There
may be a conflict between your code and remote, but that is up to _you_ to
resolve as the remote works and your code does not work with it.

His suggestion that in order to keep your git history pristine you should just
email patches until you can get to a working state seems bizarre. git is a
tool that works really well for collaborating on something until it works. In
a small project, who gives a crap if you see a commit that fixes the previous
commit once in a blue moon. Yes, on a large project like the Linux kernel that
might get annoying, but for 99% of people it's irrelevant.

~~~
dan00
> An alternative that worked really well for me is "do not push broken code".
> Linus is saying "If you pull at a random time, you might get cruft in your
> local tree". Why is that?

It's not about pushing broken code, it's about having a very complex code base
and you just can't foresee how each change will behave before it has been
tested by a lot of people on a lot of different machines.

A linux release is a pretty good point in time to get a quite well tested
version and therefore it's a good base for your changes and to be able to test
how your changes - only your changes - behave.

~~~
IgorPartola
Good point. However, that still means that this advice does not apply to most
people in the wild as most people are not working on projects that large.

------
jebblue
I've been teaching myself git on side projects for several months. I've read
through Linux's man page tutorial at least twice, I think I'm starting to get
git. It's revolutionary. It will probably still be in use a half-century from
now. It's almost too much power, I think some of the git commands should use
ASCII art to paint a big picture illustrating the power of the command the
user is about to invoke and double checking with the user, do you really want
to "xyz", rebase, etc.

~~~
6ren
Remember, it's all immutable data structures. So whatever you do locally (i.e.
apart from _git push_ ), the old version is still there - _git reflog_ will
show it.

Git eventually garbage collects old versions (i.e. not accessible from a
branch), but by default only after a month.

Unfortunately... using _git reflog_ to find the old version and undo a command
itself has a learning curve. :\

~~~
jordanthoms
This for me is the one feature of git that I could never give up. The
confidence that, once a state has entered my history, I can always get it back
is really helpful when playing with things.

------
martius
(2009)
[http://news.ycombinator.com/item?id=655005](http://news.ycombinator.com/item?id=655005)
[http://news.ycombinator.com/item?id=4612331](http://news.ycombinator.com/item?id=4612331)

~~~
develop7
Yup, instead of pushing git core devs into adopting at least mercurial
"phases" concept or thinking on another way to solve this problem, reposting
"do not handle it this way" guidelines is preferred.

------
picomancer
The main reason you don't want to rebase published code is to avoid
inconveniencing other people. But that doesn't imply that code that's under
heavy development and may need rebased should always be hidden from the world
and kept totally private.

One workflow I've seen other projects use -- that I've also adopted for my own
projects -- is to have a separate (non-private) branch called "pu" (pending
updates) or "wip" (work in progress). With warnings in the developer docs that
this branch may be rebased at any time.

In short, keep code that you're willing to rebase clearly delineated from the
code you're not, tell other people that it may be rebased in the future, and
let _them_ decide whether the benefit of pulling the code today outweighs the
drawback of potentially being inconvenienced by a rebase tomorrow.

------
oelmekki
I'm not sure to understand the point about rebase destroying the history. Does
he speak specifically about `git rebase -i` ?

I very often run `git rebase master` in my feature branches to avoid having
many conflicts to resolve just before my pull request to master. Once merged
in master, initial commits I rebased from master did not seem to have changed.
Am I missing something, here ?

~~~
Supermighty
You're not missing anything. Rebasing off master is the same as a fastforward
only merge. It is -i that can actually change the history.

~~~
fr0sty
Rebasing and fast-forward merging are two very different things.

whenever you rebase you create _brand new commits_ based off another part of
the project history which bear a strong resemblance to the original commits
but are nonetheless different.

adding -i allows you to do further modification of commit contents
(reordering, squashing, dropping, etc. but a vanilla rebase is still changing
history.

Linus addresses this in his mail early on: "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" "

~~~
Supermighty
Are you saying when I rebase off of upstream on my private branch does that
change the sha1 of the upstream commits?

That hasn't been my experience. As far as I can tell.

Edit: OK, I did a test and I can see that it is changing the sha1 for my
commits on my private branch after I rebase from upstream master. So at least
the way I'm doing it I'm not changing public comit hashes.

------
VladRussian2
Linus emails archive for software engineering is like Feynman's lectures for
QM. Very clear delivery of the right stuff without dumbing down.

------
alexchamberlain
Polite, yet still extremely useful. Is Linus getting old?

~~~
derefr
This is linus 99% of the time. As with crime and natural disasters, the 1%
makes the news.

~~~
simonh
Since we have no evidence of Linus being a criminal, I think I'll have to go
with Force of Nature.

------
tsenkov
I think this mail is an anthem of the "proper" and paradox-free TimeTravel -
"never-ever-ever destroy other people's history". :)

------
frosas
How this applies if I want to share my branch to accept changes from other
developers (think pair programming, handovers of half-done features, ...)?

------
vadivlkumar
It's fun to read Linus writings. It's rude and on the face. Git is exactly
him, rude and on the face. Does wonders!

------
jheriko
or just don't use git... :)

~~~
octo_t
i agree, on my team we manage code by just having project_name_YYMMDD_RELEASE
in a big folder /code. Works fine for us!

/s

~~~
webwarrior
I think parent meant using Mercurial or other DVCS that doesn't have such
silly thing as "history rewriting". Leave that to politicians :-)

~~~
npsimons
Mercurial will eventually have history re-writing; I say this as an outsider
who has watched Mercurial slowly catch up to git by adding features that git
has already had for a while. They will have to add it sooner or later to
remain relevant and competitive.

The article explains why it makes sense to rewrite history - it's so as not to
push garbage out on the world. One of the big niceties of distributed,
disconnected repositories is that you can muck about, try things out, make
mistakes, correct them, clean things up, and _then_ push that out to a public
repo. The difference with git is that you don't have to make a separate patch,
roll things back (possibly restarting with a clean repo from master), then
apply the patch and make a "clean" commit - you simply rebase the commits in
git.

When I'm maintaining code, I don't care about every little twiddle of bits
that happened; I care about discrete, human-level, bug or feature related
patches, and sometimes development in progress doesn't match up with that.
Being able to rewrite history means being able to have not just maintainable
code, but a coherent change history.

~~~
alayne
hg already has a rebase extension
[http://mercurial.selenic.com/wiki/RebaseExtension](http://mercurial.selenic.com/wiki/RebaseExtension)

~~~
giulianob
And it uses "phases" to know when something is public and should no longer be
rewritten.

