On Wed, Aug 06, 2014 at 12:11:16PM -0700, Mike Stump wrote: > On Aug 1, 2014, at 4:40 PM, Nico Williams <nico@xxxxxxxxxxxxxxxx> 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). > > 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. > 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. > 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.) > > (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 -- -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html