@FlaksterCarlos Jose Santamaria Bernal
Learning lover and team work oriented computer sciences engineer
Imagine that you need to merge your development branch with the main branch of a Github repository, but when you try to do it, a message shows up telling you that the two branches have entirely different histories and they are unable to merge.
One simple way to reenact such a situation is the following: you are assigned to a developing project, and as the first step, you decide to start a new repository in Github which only contains the main branch with the README.md, License and, .gitignore files, which have been created in the initial commit. That is the official repository of your project. Then you locally run something like the rails new command, which creates its own Git repository, and you add to it the remote origin (with git add remote origin) that you had already created. Then, following the Git flow rules, you start a new development branch, and one more branch for each of the main features of your project. Whenever you finish each feature, you merge that feature branch with the development one, but when finally you try to merge the development branch with the main one, the scary message appears and then you realize that you made a mistake at the very beginning of your project and now you can’t show the results of all your effort.
When this happened to me, I asked a couple of colleagues for help and both of them told me not to worry because the problem seemed pretty straightforward to solve, but no one gave me a clear path to follow in order to be able to update the main branch
Then I started googling for a tutorial to follow, but it seems like the problem is “so easy” that no one has taken the time to write down the steps you need to take to solve it. Unfortunately, at that moment time was running out, my deadline was too close, and the monster of panic was breathing down my neck.
To prevent me or anyone else from suffering that pain again, I decided to write what I think is the right course of action in this situation.
In this case, there are two different stories and one of them needs to be deleted. In our example, the almost empty main branch is the obvious selection as the branch to remove, so we need to replace that old disconnected main branch with a new one that shares the starting point of our development branch. Then we need to go to the first commit of the development branch. This can be achieved by typing:
We will see a list of commits in reverse chronological order, i.e., the first at the very end of the list. Then we can make a checkout to that commit by using its Sha-1 checksum this way:
$ git checkout 1b818420ddc74563a3616921986d6fd9eaff5fa0
A note will appear:
Note: checking out '1b818420ddc74563a3616921986d6fd9eaff5fa0'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at 1b81842 First commit
From this point, we can create our new main branch as the note suggests:
$ git checkout -b main
Now we can try to push this new branch into our Github repository:
$ git push origin main
Github will complain:
To https://github.com/Flakster/Rails-Project ! [rejected] main -> main (fetch first) error: failed to push some refs to 'https://github.com/Flakster/Rails-Project' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Of course, there are things in the old main branch that do not exist in the local new main branch, but at this point, we are not concerned about the contents of the old main branch, so we can either delete it or plainly force the push:
$ git push origin --force main
We have achieved our goal. At this moment both branches have the same starting point and could be merged.
Note: Forcing the last push could seem a bit harsh, but less so than using the allow-unrelated-histories switch.
Create your free account to unlock your custom reading experience.