I find myself running into a workflow where I do the following:
foo
") off of our develop
("master") branchfoo
bar
") off of my previous foo
branchdevelop
+ I can't wait for reviews -- they sometimes take over a weekbar
foo
and merge it into develop
bar
, there are comments, maybe bar
is even approved by nowbar
as follows:git checkout bar
git rebase --onto develop foo
git push --force origin bar
bar
if not already approved by now, and merge it into develop
This works as expected, but it re-writes history, and is frowned upon because people have already been looking at bar
, and there's no way to really know what I did when I force-pushed.
If I try to merge without rebasing, I get all kinds of merge conflicts. It's like develop
is trying to "undo" my changes in bar
.
My question is:
Is there an equivalent git merge
workflow to git rebase --onto
??? Something like:
git checkout bar
git merge ??? develop ??? foo
Is there some trick like... maybe I merge foo
back onto bar
, or some trick with setting the upstream? I'm fishing here...
Thanks!
EDIT: Another thing... even this process can be a PITA if I have multiple commits in bar
. I'll usually merge-in foo
to bar
at the end, so there's definitely no conflicts between them. But there might be a conflict between an early commit in bar
and the latest foo
. So I have to do a git rebase -i bar
on bar
and squash it down to one commit before I do the git rebase --onto develop foo
... Not great for preserving history... because now I'm squashing out comment commits, and such. So sometimes I use another alternative:
git checkout bar
git reset foo
git add stuff
git commit -m "One commit of foo-bar delta"
Again, grimy -- all the comment commit history is lost...
Here's what I went with...:
git merge -X ours develop
And then since git is sometimes not-so-smart about the options it gives when there's a merge conflict, I verified the result with:
diff <(git diff Foo origin/Bar) <(git diff develop Bar)
Luckily, I hadn't pruned (I rarely do). If there's a better way, I'm still open to other answers - going to keep this unanswered for a bit.
It would be nice if there were a solution that preserved the history of Bar
, did not show the commit history for Foo
(like git rebase --onto
does), and required no intervention on merging the individual commits in Bar
as they're re-played onto develop
... But the more I think about it, I'm not sure that's theoretically possible. So I think I can live with having the extraneous commits in Foo
shown in Bar
's history. The above meets all the other requirements.
EDIT: Haven't had an opportunity to try it yet, but I think this is what rerere
is for.
This works as expected, but it re-writes history, and is frowned upon because people have already been looking at bar, and there's no way to really know what I did when I force-pushed.
GitHub would clearly mark the previous commits referenced in the PR page as obsolete, but you are correct: it is cumbersome to detect the changes you had to make during your rebase onto develop
before force pushing bar
.
I would consider and pushing it as "bar2
", and make a new PR from bar2
, with a reference to the original bar
PR.
That would allow a reviewer to compare those two PR branches and quickly determine if anything significant has changed between:
bar
PR, which was already approvedbar2
PR, which has to be rebased onto develop in order to facilitate its PR merge to develop.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With