Re: interactive rebase not rebasing

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

 



Stephen Haberman wrote:
Hello,

Per the emails from me last week, I'm working in an environment with
shared topic branches and am trying to find a bullet-proof way for devs
to rebase their local commits after the topic branch has moved.

The easy approach would be to just let `git pull` create merge commits,
and I would have been done with this long ago, but I'm striving to get
rebasing to "just work" and avoid the ugliness of same-branch merge
commits. Cross-branch merge commits are cool, but not same-branch.

So, here's a crazy scenario we've ran into--a new release has hit
stable, with two devs working on the same topic branch, and both of them
merge. One wins, and the other has to rebase. Previously, this was
replaying commits, but with great tips from the list last week, `rebase
-i -p` is handling most scenarios.

However, not this one:

# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|
#     g -- h             <-- topic2

topic2 is a dev that has locally merged stable in g, moved on in h, is
ready to push, but another dev already merged stable in E, and also
committed F.

If we do a `git pull --no-rebase`, the result is:

# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|             \
#     g -- h ------- i   <-- topic2

But i is a same-branch merge, and we'd rather rebase to something like:

# A --C------            <-- origin/stable
#  \         \
#   B -- D -- E -- F     <-- origin/topic2
#                   \
#                    h'  <-- topic2

(...maybe g' in there if g resolved stable conflicts differently
E did them. I'm not sure, I haven't gotten there yet.)

However, currently, `git rebase -i -p origin/topic2` results in:

# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|
#     g -- h             <-- topic2

Nothing has changed. g & h haven't moved...I can keep executing this
operation and the commits never make it on top of origin/topic2's F.
Frustratingly, if I run non-interactive rebase, it works perfectly.

I can imagine. Since you don't want to preserve the merges in this
case, you shouldn't be using the -p flag.

In fact, for this particular scenario (assuming "h" is really the only
commit on topic2), you probably want to just cherry-pick that commit
into origin/topic2:

  git checkout topic2
  git reset --hard origin/topic2
  git cherry-pick ORIG_HEAD

would work nicely for that. If topic2 and topic1 resolved merge
conflicts differently, cherry-picking topic2 will give conflicts again,
so they'll have to be resolved. rebase (without -p) will have the same
effect, ofcourse.

I don't think you can have a single command that does all the things
you want, because the possible differences in input makes it very nearly
impossible to always do "the right thing". For this case, you don't
want to preserve merges, so "git rebase" without -p does the right
thing. For that other case earlier this week, you wanted to preserve
merges, so "git rebase -p" does the right thing there. It's complex
to try to dwim things like that, and complexity will cause very weird
and surprising errors when it *does* fail.

Instead, I think you should give your developers some training in the
more advanced parts of git's integration tools and also look over
your workflow. Frequently merging 'master' into a topic is very rarely
the right thing to do. It's usually better to rebase the topic onto
master or cherry-pick relevant bugfixes from 'master' into the topic.
If two devs need to work on one topic, then that topic probably needs
breaking up into a sub-topic. However, sub-topics should never merge
'master' into them themselves; only 'topic'. Otherwise you'll get
more merges than work done.


But
I've got other cases (see earlier posts) that do need the interactive
rebase. Personally, I could probably make do with trying each and
seeing what happened, but I'm really trying to find a bullet proof
command/alias/script for devs to run and have it "just work".


Or you could sit down and think about what you want to happen and then
run the appropriate command. ;-)

I've attached a test that sets up the DAG as above and currently passes
by asserting the not-desired/unchanged-DAG result. The assert for the
desired result is commented out at the end.


Thanks for this. If all bug-reports had this, bugfixing would be a lot
easier. However, for this particular case, I'm not so sure it's a bug.

Am I correct in asserting this is some sort of bug in the interactive
rebase such that g & h are not ending up on top of F?


Assuming you're passing a correct input file to rebase -i; yes. At the
very least, "h" should be moved to the tip of origin/topic2.

--
Andreas Ericsson                   andreas.ericsson@xxxxxx
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231
--
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]

  Powered by Linux