Migrating commits to open branch

I recently had the problem that I was accidentally working on a local branch that was tracking a protected remote branch. In simple words: I was working on the main branch but was not allowed to push to origin/main. This is a good thing because I see the main branch as stable and I would not want anyone to push directly to main for obvious reasons. So when I started working, not realizing, that I am on the main branch, it looked like this:

So now I have added some code (on my local main branch) and created a new commit:

Until this point everything was fine but when I tried

git push origin main

I got the message

PS C:\my.repo.name> git add --all
PS C:\my.repo.name> git commit -m "Doing stuff."
PS C:\my.repo.name> git push
...
 ! [remote rejected] main -> main (TF402455: Pushes to this branch are not permitted; you must use a pull request to update this branch.)
error: failed to push some refs to 'ssh://my.devops.server:22/MyCollection/MyProject/_git/my.repo.name'

Well shit. Now I have my local branch one commit further than my remote and I can’t push them to the remote repository directly. One possibility is to ask the project leader if he would allow me to push to main. Probably he will not. But I found another solution, that worked for me that consists of two steps:

  1. “Export” the unpushable commit to a new branch and push this branch to integrate afterwards via pull|merge request.
  2. Reset the main branch to the same level as the remote branch.

The first one is quite easy. Find the commit id with “git log” and create a new branch:

PS C:\my.repo.name> git log
commit E (HEAD -> main)
Author: AndreasGottardi <andreas@goa.systems>
Date:   Fri Jun 17 10:39:16 2022 +0200

    Adding comment.

I have shortened the output. The commit id I used in the example is simply “E” and a real id would look something like “997f11ca98a823aed198df5410f97b769b0b8338”.

With the found id you can create a new branch with

git checkout -b "my/new/branch" E

So basically it looks like this now:

So now you have exported your commit into a pushable branch and you can push it to remote with

git push origin "my/new/branch"

From there on it is the regular procedure of creating a pull request and going through the defined review process to integrate it into “main”.

The last step is to checkout main and reset it to the previous commit. Find the ID with “git log” and then reset it with

git reset --hard D

Now your local branch “main” is back in sync with the remote branch and as soon as the pull|merge request is through you can pull your changes from the remote branch “main” via

git pull origin main