Fwd: Rebase safely (Re: cherry picking and merge)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



[ sorry for the dup ]

Begin forwarded message:

On Aug 6, 2014, at 12:44 PM, Nico Williams <nico@xxxxxxxxxxxxxxxx> wrote:
> It's not a good idea to rebase a branch in a repo that others pull from.

Well, so rebase is then out, as I don’t want to rebase _my_ tree, I want to rebase _the_ tree.  Recall, I don’t want to cherry pick for my tree, I want to cherry pick for the tree.

[ reads rest of email ]

Oh, wait, maybe I have misunderstood the prohibition.  I have:

       upstream  <—— fsf
           |
            \
             |
             v
Me  <—>   master  <—> coworker.

Me is a git clone of master, coworker is a git clone of master.  Master is a bare repo on a shared server where we put all of our work.  upstream is a bare git repo of the fsf git tree for gcc.  fsf is a box owned by other that hosts the gcc git repository.  I do a git pull fsf in upstream from time to time, and a corresponding git merge fsf in Me from time to time.  When I like my work I do a git push (to master exclusively).  To go to upstream, we submit patches by hand, git is not really involved.  I never pull into master from upstream (don’t even think that’s possible since they are both bare).

I read the prohibition as don’t rebase my branch called master on Me and push it to master on master as others then pull master from master.  Did I misunderstand?  Instead, the prohibition is you can use push/pull freely and you can have as many coworkers as you want, just don’t use push -f and don’t let anyone push/pull from your own private clone.

I had envisions that the rebase of master on Me once pushed to master and then pull from master to coworker is the exact case that would screw us.

> The only use-case I've seen where a rebase-based workflow doesn't work

Well, and now mine, which I claim is a the canonical open source use case.  Can't use source, unless you import the source,  can’t be real unless you can change the source, once you do that, you then need to merge in newer sources, and if the company has or will have more than a single individual and these folks are ever to work together, then they need to share the source between them.

I’m trying to envision how anyone could ever use rebase.  If you can’t share your work, it isn’t work.

> is where you have multiple upstreams that you're following.

I only have a single (for this repo) upstream.

>> 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.

What I saw were the people that screwed their world and were trying to recover.  It was a question, how do I recover, and what did I do wrong.  There was no rant.  Or, at least, I’m impervious to rants and don’t actually see them.  I deal in the cold hard facts and transform the rant into what happened, what they did wrong, and how to avoid doing it myself.

No, you’ve set my perspective, let me quote you:

  It's not a good idea to rebase a branch in a repo that others pull from.

this matches the doc, matches the experience of users on stack overflow and matches what what I think is true.  You are free to correct that if I am wrong.

I don’t know why you think my perspective is distorted.  Either, I can rebase all my patches, all my coworkers patches, and push those up to master and have all my coworkers pull from master and develop (meaning branches off master as well as patches to master) as normal, or I can’t.

> There's just two simple rules to follow and you'll be safe:
> 
> 1) NEVER git push -f (--force) to a "published" repo/branch.

I can never use push -f.  That seems trivial.  git config --system receive.denyNonFastForwards true seems to be exactly what I would do to my master to enforce this rule.  This then seems to permanently be a non-issue.

> 2) NEVER work directly in a published repo.  Instead work in a private
>   clone.

I only ever work in a private to me clone, so I’m safe.  The only published repo is a bare repo, which can’t be worked in by design, so, again, I think I’m perfectly safe.

So, if that is true, why do others write such things as (from http://ctoinsights.wordpress.com/2012/06/29/git-flow-with-rebase/):

> The way to get the best of both worlds is to be explicit about when to use one versus the other. For us the simple rules to follow are:
> 	• Rebase feature branches.
> 	• Never rebase develop or master branch. (Always merge into develop and master.)
> 	• Never rebase public branches.
master is public, I want to rebase master.  This violates rule 3 above, but not any of your rules?

I develop on master, thus violating rule 2.  This does’t violate any of your rules?

I want to rebase master, thus, violating rule 1.  This doesn’t violate any of your rules?

I violate every single rule, by his standard, I am screwed.

http://blog.experimentalworks.net/2009/03/merge-vs-rebase-a-deep-dive-into-the-mysteries-of-revision-control/ says:

> Never rebase branches or trees that you pulled. Only rebase local branches. 

I violate that.  This doesn’t violate ant of your rules?  I pull master rebase it, then push it.  master is not a local branch, or, more correctly, I have a local branch called master that is push to and pull from a bare repo that I’m calling master to/from a branch called master.  git diff origin/master master shows our work.

To me, a local branch is one call b, that doesn’t push or pull to any remote repo.

Linus in https://www.mail-archive.com/dri-devel@xxxxxxxxxxxxxxxxxxxxx/msg39091.html said:

But never other peoples code. That's a "destroy 
history"

Thus violating his rule.  Recall why rebase was suggested.  I want to merge the upstream fsf tree into our tree (or our tree into a copy of the fsf tree) and instead of using merge, it was suggested to use rebase.  But I operate on our entire tree.  He further says:

- You must never EVER destroy other peoples history. You must not rebase 
   commits other people did.

I want to exactly rebase either the entire fsf tree onto mine, or mine on to the fsf tree.  Either result I am rebasing code I didn’t write, commits other than mine.  This violates his rule, not your?

He states:

- Minor clarification to the rule: once you've published your history in 
   some public site, other people may be using it, and so now it's clearly 
   not your _private_ history any more.

And I violate this rule, but it doesn’t violate any of your rules?

>  To help make sure of this, never publish a non-bare repo
>   (bare == has no workspace; non-bare == has a workspace).

We only have a bare repo (our master) and we only ever push/pull from it, so I’m safe.

> 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).

Wrong, let me introduce you to git gc:

       --prune=<date>
           Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable
           gc.pruneExpire). --prune=all prunes loose objects regardless of their age. --prune is on by default.

which, I run every now and then as we work on stuff that is more than 5 lines long.  I bring in 60,000 changes, I push, I git gc on the bare repo.

>>> 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.

I’m optimistic.

>> 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.

So, rebasing will always work just fine, one just needs to never, ever use push -f and never ever share ones own private clone.  Sharing a bare repo that everyone works on (push/pull) is fine.  rebasing and pushing into it and others pulling from it will always just work fine.

Gosh, could you get the documentation to say that.  I’ve certainly been scared off even trying rebase.

Rebase should just say it always works perfectly (remove the warning entirely) and then burry into push -f, this option will destroy your world and put into it, the entire how it will screw it, how to recover from it, and then say in the clone documentation, you should never clone a none bare repo, because if you do, your world will end when you rebase.  In fact, I’ve make if a clone -f operation, and then fail the default is non-base, and then under clone -f explain this is a ver bad idea.

Articles like http://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions:

Reason #2: With rebase, there is no undo!

makes me nervous.

>> 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.

Ah, excellent.

>> bugzilla to work.  I want to see the original dates of all the work.
> 
> Ditto.

Ah, nice.

>> 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?

Yes.  I have upstream which is a virgin copy of the fsf in a bare repo.

Our master only ever pulls from the upstream.

> 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

Virgin copy, it only can ever lag in time, no other way.  We can only pull or get work from our virgin copy, no other way.  To get a patch that just went in, I would like to pull from fsf into upstream, cherry-pick upstream into Me, push into master.  When I merge I same thing except I do a merge upstream.

>   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.

It never pushes up, it is unidirectional.  The only direction down is pull the entire bare repo, everything, or nothing, that’s it.

> (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.

So, you would like to withdraw your statement, git users don't rebase published branches, and instead say, git users can rebase published branches and it all works flawlessly well, provided they stay away from non-bare shared repos and stay away from push -f?  The later statement doesn’t make be nervous at all.  Though, I would like an option like receive.denyNonFastForwards to turn off the ability to push/pull from a non-bare repo.


So, thinking about it some more, would references to the fsf git repo from the fsf bugzilla work in our tree once I rebase the fsf work on ours?  Remember, I do want those to work.--
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




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]