-1

The Problem

OK, so, I had two branches: main and session

In the main branch I developed the main code, in the session branch I developed code for a new session system.

Occasionally, I merged main into session to keep it up to date. ("Merge branch 'main' into session").

Today I felt the new session system was ready, and merged main into session so that it's on par with main, before merging session into main.

I finally merged session into main, was happy that this long in progress feature is done, and to really feel like I was done, I deleted the session branch.

Now, I didn't notice at the time, but it seems Git did fast-forward (or something like that), and the main branch has essentially become the session branch.

This means instead of having one nice merge commit seeing all the changes from session, they're all spread out, since it's now effectively the session branch. Not only is this terrible for historic purposes, but it also effectively prevents me from undoing this merge if the need arises.

What I tried

Git reflog: There are many sources online that share the trick with git reflog to restore a branch, however this does not seem to work for me, since the main branch has essentially become the session branch.

Undo the latest (merge) commit: This also does not work for me, since the latest commit is now "merge branch 'main' into session", so that too undoes all changes to main.

Further explanation

So, the last commit is not session branch stuff, but rather main branch stuff merged into main branch (since main has been turned into session, apparently).

Again, due to the regular merges and then a fast-forward, I essentially turned the main branch into the session branch. How can I undo this?

Apologies if I'm repeating myself, I'm just trying to describe as best as I can to make the issue clear.

  • I don't know how to explain this better. I could try to shorten it, but I fear it might not give the full picture. Constructive feedback on how to improve this question is very welcome. – iMessedUpGit May 20 '22 at 14:57
  • 1
    "[reflog] does not seem to work for me, since the main branch has essentially become the session branch." That really doesn't make much sense. Find the commit you want to go back to in the reflog (the branch is irrelevant) and reset the current branch to it. – William Pursell May 20 '22 at 14:57
  • @WilliamPursell What I meant by that, is the main branch was fast forwarded into the session branch. The main branch is now the session branch, and the original session branch is no more. Think of a messed up merge in the wrong direction. Does that describe the issue better? – iMessedUpGit May 20 '22 at 15:00
  • A branch is just a reference to a single commit. As humans, we tend to think of a branch as a commit and all its ancestors, but it's really just a single commit. Perhaps "I essentially turned the main branch into the session branch" is just a reflection of the muddle created by constantly merging master back to session rather than rebasing. – William Pursell May 20 '22 at 15:01
  • Find the merge commit where you combined session in to master. One of its parents will be the commit that you want to think of as the session branch. Create a session branch on that commit. Rebase, make a squash commit, and merge. You'll have to tease out any changes made since then. – William Pursell May 20 '22 at 15:05
  • @WilliamPursell Yes, I should have rebased instead (I learned something at least). As for "it's just a single commit", how do I find a commit for a "fast-forward" (if that even exists)? I can undo a normal merge just fine, but in this case, it's fast-forwarded, and I'm at a loss. – iMessedUpGit May 20 '22 at 15:05
  • The commit you want to roll your `main` branch back to is still in its history. Run `git log --oneline --graph main` to view the history, and spot the commit you want to reset to. From waht you describe, that commit is probably `main^2`. Check if `git log --oneline --graph main^2` displays the state you would like to return to. – LeGEC May 20 '22 at 15:07
  • To merge without fast forwarding : use `git merge --no-ff session`. – LeGEC May 20 '22 at 15:08
  • @LeGEC It seems `git log --oneline --graph main^2` shows the state of main as it was before the screwed merge. I did check out the latest commit where I modified session code (ignoring the merge commits that came after) and created a session branch from it. I'm now back on main. Before I mess up further, do I understand correctly that I'd have to do `git reset --hard HEAD^2` to get back to main as it was? And do I also understand correctly that my original changes are now safe in the (new) session branch? – iMessedUpGit May 20 '22 at 15:20
  • @LeGEC I wanted to thank you both for your helpful comments. I managed to "separate" the branches again and posted how I did it in case you're interested. – iMessedUpGit May 20 '22 at 17:13
  • @WilliamPursell CC because I cannot tag more than one person. I just wanted to say thanks. – iMessedUpGit May 20 '22 at 17:14

1 Answers1

0

Since main was now effectively session (fast-forward I think was the reason), I created a branch session from the top commit on main (since we're effectively on an equivalent of session due to the fast-forward).

Then on main I did git reset --hard HEAD^2 to get back to the "original" main branch before the screwed up merge (a fast-forward I believe).

So, main is again main, and session is at "Merge branch 'main' into session" (basically, what main just was before the reset). And this works because the parent commit is still there, just no fast-forward done yet (if I understood correctly).

I'm essentially back to two separate branches before the fast-forward.

Then I did force push main to GitHub, and set up tracking for session and pushed that too.

I do, of course, have all these ugly merge commits (from mainsession) because I did not rebase, but that was an issue before this particular issue already and something I'll have to look into.

I hope this was understandable and will help someone in the same position.

Note: The reason "undo" failed on my first try was because I did git reset HARD~1 which went back just enough to undo all main commits in the merge without undoing the whole merge/fast-forward itself (if I understood correctly). Going back two steps did the trick.

Special thanks to @william-pursell and @LeGEC for the helpful comments.

PS It's difficult for me to put this mess into words, I'd gladly appreciate feedback on how to improve my questioning and answering.

  • 1
    I now also did a squash merge of `session` into `main`, so I don't have all these ugly "merge" commits. Everything seems to be the way it should and worked out in the end. – iMessedUpGit May 20 '22 at 19:15