git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Rebase safely (Re: cherry picking and merge)

From
NWNico Williams <nico@cryptonector.com>
Date
Aug 6, 2014, 19:44 UTC
Message-ID
<20140806194457.GD23449@localhost>
In-Reply-To
<96B703A6-58B0-458A-8A2D-699EA8F1941B@comcast.net>
On Wed, Aug 06, 2014 at 12:11:16PM -0700, Mike Stump wrote:
Show 11 quoted lines
> On Aug 1, 2014, at 4:40 PM, Nico Williams <nico@cryptonector.com> wrote:
> > As for rebase, I still don't understand why it doesn't work for you.
> 
> http://git-scm.com/docs/git-rebase says:
> 
>   Rebasing (or any other form of rewriting) a branch that others have
>   based work on is a bad idea
> 
> If you read stack-overflow, you will discover a ton of people that
> like doing this, and they get hammered because of it.  My use case
> fits exactly (as near as I can tell) the hammer case.
It's not a good idea to rebase a branch in a repo that others pull from.

There's nothing wrong with rebasing your patches on that same branch in your clone as long as the end result is a fast forward merge when you push.

    $ git clone https://..../blah
    $ cd blah
    $ <do some work>
    $ git commit ...
    $ git fetch origin
--->$ git rebase origin/master
    $ git push origin master

There's NOTHING wrong with that rebase. It's perfectly safe because it's only in your *private* clone.

(If later you publish that clone and expect people to track your master branch, then rebase becomes problematic, but that's not something most people ever do with their clones.)

The only use-case I've seen where a rebase-based workflow doesn't work is where you have multiple upstreams that you're following. I.e., the upstream forked and you want to take some commits from one, some from the other, or otherwise keep a merge of both.

(Also, if an upstream is ever rebased you can usually recover on the downstream side by rebasing with the --onto option, so it's not the end of the world.)

> Now, I found the stack-overflow commentary first, and all the horrors
> of it, and all the nuances.  I carefully read what people were doing,
> how what I wanted to related to what they were doing, and it sure felt
> like I was in the, don’t go there camp.

A lot of people rant about rebase. They're wrong. They've distorted your perspective.

> So, I like to know if I’m driving off a cliff, before I do.  I’m the
> [...]
There's just two simple rules to follow and you'll be safe:
1) NEVER git push -f (--force) to a "published" repo/branch.
   The upstream should enforce this with a receive hook.
2) NEVER work directly in a published repo.  Instead work in a private
   clone.  To help make sure of this, never publish a non-bare repo
   (bare == has no workspace; non-bare == has a workspace).

If you ever do a rebase that produces results you're unhappy with you can undo that rebase like so:

 - use git reflog to find the branch's previous HEAD commit
 - reset the branch to point to that commit

It really helps to think of git as a pile of commits arranged in a Merkle has tree. Branches and tags are just symbolic names for specific commits. Rebase builds a new line of commits in the tree then it changes the symbolic branch name's HEAD to point to the head of that new line of commits, BUT NOTHING IS LOST in the pile of commits that is the repo, not until you git-prune(1) to remove commits not reachable from symbolic names (branches and tags).

Show 5 quoted lines
> > The only case where I can imagine not using a
> > rebase-heavy workflow is where I have to track multiple forked
> > upstreams and so I want to merge each into my branch.
> 
> So, sounds like I fit that use case and rebase could be my friend.
Excellent.
Show 6 quoted lines
> How do I square what you said and:
> 
>   Rebasing (or any other form of rewriting) a branch that others have
>   based work on is a bad idea
> 
> ?
See above.
> I want all old refs in old emails to work.  I want all refs in
They will if you stick to the two rules I mention above.
> bugzilla to work.  I want to see the original dates of all the work.
Ditto.
Show 7 quoted lines
> I want git blame to report those artifacts in email and bugzilla.  I
> have coworkers that I push to, pull from (through a single sharing
> point, we call the master tree).  We work on gcc, we pull git gcc down
> to a local copy, then merge it into our tree.  I want to cherry pick
> changes from upstream.  I do work and push to our master, I pull work
> of coworkers from the master, my coworkers do the same.  Isn’t this
> the canonical open source use case?
That means that you have/maintain an intermediate upstream, yes?

This is a bit trickier since once in a while that intermediate upstream and everyone downstream of it has to catch up with the real upstream.

Here you have two options:
 - the intermediate diverges from the real upstream, and then you
   merge/cherry-pick from the upstream as needed
   
   The intermediate's maintainer must still merge/rebase/cherry-pick
   from the intermediate branch and onto a branch of the upstream in
   order to push to the upstream.
or
 - the intermediate occasionally rebases onto the upstream, and then the
   repos downstream of the intermediate must also rebase with --onto.
   In this case the intermediate's maintainer must tell the downstreams
   what rebase command to execute.
   This makes it easier to push from the intermediate to the upstream:
   the intermediate's commits should always be on top of the upstream
   (at rebase time) so it's easy to push them.

The latter is the workflow we used at Sun for decades for large projects. We followed that workflow long before git, first with Teamware, then later with Mercurial (even though Mercurial technically had no support for rebasing at that time; we just made it work).

(We always left symbolic names for the pre-rebase branch HEADs, mind you, to make life easier for everyone.)

Show 6 quoted lines
> > (I find that many users are allergic to rebasing.  Many people have
> > told me that rebase is lying, that history must be immutable, and so
> > on, all ignoring that: git users don't rebase published branches,
> 
> So, when I push, and someone else pulls, is that published?  I thought
> it was.
Yes.  You shouldn't push -f.  As long as you don't there's no problem.
Nico
Previous: Mike StumpNext: Nico Williams
Message 14 of 43 in “cherry picking and merge”
  1. Mike StumpAug 1, 2014
  2. brian m. carlsonAug 1, 2014
  3. Jakub NarębskiAug 1, 2014
  4. Mike StumpAug 1, 2014
  5. Philip OakleyAug 1, 2014
  6. Mike StumpAug 1, 2014
  7. Philip OakleyAug 2, 2014
  8. Philip OakleyAug 2, 2014
  9. Sam VilainAug 1, 2014
  10. Mike StumpAug 1, 2014
  11. Nico WilliamsAug 1, 2014
  12. Alex DavidsonAug 2, 2014
  13. Mike StumpAug 6, 2014
  14. Rebase safely (Re: cherry picking and merge)Nico Williams, Aug 6, 2014
  15. Nico WilliamsAug 6, 2014
  16. Mike StumpAug 1, 2014
  17. Keller, Jacob EAug 21, 2014
  18. Keller, Jacob EAug 21, 2014
  19. Nico WilliamsAug 1, 2014
  20. Mike StumpAug 1, 2014
  21. Nico WilliamsAug 1, 2014
  22. Jonathan NiederAug 1, 2014
  23. Jonathan NiederAug 1, 2014
  24. Nico WilliamsAug 1, 2014
  25. Junio C HamanoAug 1, 2014
  26. Nico WilliamsAug 1, 2014
  27. Junio C HamanoAug 1, 2014
  28. Jakub NarębskiAug 6, 2014
  29. Nico WilliamsAug 6, 2014
  30. Junio C HamanoAug 6, 2014
  31. Junio C HamanoAug 6, 2014
  32. Mike StumpAug 1, 2014
  33. Mike StumpAug 1, 2014
  34. Jonathan NiederAug 1, 2014
  35. Fwd: cherry picking and mergeJakub Narębski, Aug 1, 2014
  36. Mike StumpAug 1, 2014
  37. Philip OakleyAug 2, 2014
  38. Jakub NarębskiAug 6, 2014
  39. Mike StumpAug 6, 2014
  40. Nico WilliamsAug 7, 2014
  41. Mike StumpAug 8, 2014
  42. Nico WilliamsAug 8, 2014
  43. Fwd: Rebase safely (Re: cherry picking and merge)Mike Stump, Aug 8, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.