Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git Mess! Commits in the wrong branch

Tags:

git

branch

commit

I just did something terrible on a Git repo and I have no idea how to approach the issue. I don't even know how I got it into such a mess...!

On the repo (hosted on git hub), there are 3 branches I am interested in: master, brancheA, brancheB. brancheA and brancheB are unrelated (touching different files).

Here is how it looks at the moment:

A -- B -- C -- D -- master
     \               \ change_from_B_1..4 -- change_from_A_1+2 -- brancheA 
      \ -- merge_from_master -- change_from_A_1 -- change_from_A_2 -- brancheB

I want to cry :> Yes, change_from_A means "changes that should be in Branche A"! The worst thing is that in branche A, there are 4 commits which USED to be in brancheB (change_from_B_1..4) before I did the merge of master into brancheB. Now, those 4 commits are in brancheA (how??) and no longer in brancheB.

I don't know what I did to get to this situation, here is some extract from my git reflog if that help:

    b8b5db7 HEAD@{0}: checkout: moving from brancheA to brancheB
    015fdc1 HEAD@{1}: checkout: moving from brancheB to brancheA
    b8b5db7 HEAD@{2}: checkout: moving from brancheA to brancheB
    015fdc1 HEAD@{3}: checkout: moving from master to brancheA
    3830ccb HEAD@{4}: checkout: moving from brancheB_tmp to master
    2a9ba60 HEAD@{5}: cherry-pick: change_from_B_1
    3830ccb HEAD@{6}: checkout: moving from 3830cc to brancheB_tmp
    3830ccb HEAD@{7}: pull origin master: Fast-forward
    8ef3368 HEAD@{8}: checkout: moving from brancheB to master
    b8b5db7 HEAD@{9}: pull origin brancheA: Merge made by recursive.
    cc17c2e HEAD@{10}: pull origin brancheB: Fast-forward
    d867eff HEAD@{11}: HEAD^^: updating HEAD
    cc17c2e HEAD@{12}: checkout: moving from brancheA to brancheB
    015fdc1 HEAD@{13}: commit: change_from_B_6?? (lost :<)
    2f650f6 HEAD@{14}: commit: change_from_B_5?? (lost :<)
    9098bfa HEAD@{15}: commit: change_from_A_1+2
    01c7a5e HEAD@{16}: HEAD^^^: updating HEAD
    cc17c2e HEAD@{17}: checkout: moving from brancheB to brancheA
    cc17c2e HEAD@{18}: merge brancheA: Fast-forward
    d867eff HEAD@{19}: checkout: moving from brancheA to brancheB
    cc17c2e HEAD@{20}: commit: change_from_A_2
    3bee54e HEAD@{21}: checkout: moving from brancheB to brancheA
    d867eff HEAD@{22}: checkout: moving from brancheA to brancheB
    3bee54e HEAD@{23}: commit: change_from_A_1
    d867eff HEAD@{24}: checkout: moving from d867eff to brancheA
    d867eff HEAD@{25}: checkout: moving from brancheB to another_branch
    d867eff HEAD@{26}: checkout: moving from another_branch to brancheB
    d867eff HEAD@{27}: checkout: moving from d867eff to another_branch
    d867eff HEAD@{28}: commit (merge): Merge branch 'master' of super_github
    01c7a5e HEAD@{29}: commit: change_from_B_4
    1dbc4e1 HEAD@{30}: commit: change_from_B_3
    52417fa HEAD@{31}: commit: change_from_B_2
    8e5d258 HEAD@{32}: commit: change_from_B_1
    8ef3368 HEAD@{33}: checkout: moving from master to brancheB

To me, everything looks normal until I start introducing brancheA (d867eff HEAD@{24}: checkout: moving from d867eff to brancheA). At the time, I was just coding away and not really caring about git... big mistake. Anyway, I am not sure what created the mess, is it the cc17c2e HEAD@{18}: merge brancheA: Fast-forward? I don't remember asking for that...! The rest is probably what turned the mess into something even worse, and I am quite ashamed to put it here but at this point, I feel really helpless.

I have considered restarting from scratch and regenerating all the commits from master, but I'd lose all the comments on github from the code reviewer, which would be a bigloss.

What I'd like to do:

  • delete the change_from_A_1 / change_from_A_2 in brancheB
  • move back the commits in brancheA that should be in brancheB before the merge from master

To get to something like that:

A -- B -- C -- D -- master
     \               \  -- change_from_A_1+2 -- brancheA 
      \ change_from_B_1..4 -- merge_from_master -- brancheB

Do you have any suggestions? Thank you!!

like image 548
Enders Avatar asked Mar 28 '26 02:03

Enders


1 Answers

You can always fix these kind of problem.

  1. Create oldBranchA and oldBranchB at branchA and branchB, respectively.
  2. Reset branchA to master, branchB to B
  3. Checkout branchA
  4. cherry-pick change_from_A_1+2
  5. Checkout branchB
  6. cherry-pick change_from_B_1..4, then merge_from_master
  7. remove oldBranchA and oldBranchB
  8. To push back to origin, do git push -f branchA:branchA. But think 10 times before doing this, because what you are trying to do is to overwrite released history!!
like image 158
Yasushi Shoji Avatar answered Mar 29 '26 18:03

Yasushi Shoji