I had a feature branch which was based off of develop
, let's call it feature-1
. At the same point in time I also took another feature branch feature-2
.
feature-1
was a real feature branch that I've had some serious changes going on there. feature-2
was a simple branch for some github workflows breaking up.
I've made one workflow change onto feature-2
and pushed to the remote repository (feature-2
on remote); this change also merged back into develop
. I took another feature branch (out of blue moon for reasons I couldn't even remotely recollect), feature-3
, for some more github workflows changes...
At the same point in time, as I was taking branch feature-3
, I merged the latest develop change (one commit from feature-2
) into feature-1
. feature-3
has made 6 commits since then. I had to admit that I forgot there were 6 commits on the remote develop
, which I thought I had already pulled into local develop
. These 6 commits were merged into develop
from feature-3
.
Above is the relatively untangled part of the graph. During the process (I couldn't figure out exact point in time, I think I need some help here), I did a rebase
from feature-1
, onto develop
; this however caused some conflicts, resulting in duplicate set of merges from feature-1
(typical commit message would be, "merged feature-1
from origin into feature-1
"). IIRC, I did rebase
twice.
Off the top of my head, I'm thinking I'll merge the half-done feature-1
into develop
first, and take a fresh branch from merged develop
for a new start; or I could take a branch right away from develop
, then cherry-pick
commits from feature-1
, and leave the messed-up feature-1
behind for my peace of mind.
Is there, another way to tackle this? Let me be naive but for example gracefully untangle the twins in the graph, or make the tangled threads disappeared somehow?
The best practice, as I vaguely recall, was to only rebase
my local branch which contains local commits only onto a shared main branch; if I have pushed my changes to a remote repository(say my remote equivalent of the local branch), I should not use rebase
. It is true, in my mind, that only if I had shared this branch with other co-workers. In my case they were all just my branches so I carelessly pushed changes to remote repository before I did one of the rebase
(more importantly the first rebase
).
Here's my try at replicating the graph, I've marked with letters the duplicated commits. In the graph you'll see that the rebase
seemed to have happened on feature-1
only, i.e., feature-1
rebased onto feature-1
. This is also something that baffles me.
*---------*----------------------------* [develop]
| /| /
|-------a |-----------*--*--*--*--*--* [feature-2(merged), feature-3(merged)]
| |
|-----*---|-----------------------------a--b--c--d--e----c--d--e--f [feature-1]
| | \ \ /
|-----|-----b--c--d--e--------------------------------f---------- [feature-1,duplicate]
If feature_1
was not pushed, or if you are the only one working on it, do not hesitate to rebase it first locally, before merging it to develop
.
In your case, the key command is git rebase --onto <newbase> parent-commit end-commit
: it allows you to move a range of commits (the ones after parent-commit
all the way to end-commit
included)
At any point (provided your current status is clean), you can do:
git switch develop
git pull
git rebase --onto develop a~ feature-1
# resolve potential merge conflicts
That will give you:
---a--b--c--d--e----c--d--e--f [feature-1]
/
*---------*----------------------------* [develop]
| /| /
|-------a |-----------*--*--*--*--*--* [feature-2(merged), feature-3(merged)]
Then you can merge (git merge --no-ff
if you want a merge commit) to develop.
And then push.