GIT :: Merging 2 branches rewrites content in one branch with another

I am experiencing a wild problem. I have the whole project in the master branch. Previously, one guy worked on this project, but he was on SVN. He made some changes, and I need to integrate these changes with mine. Both projects have the same folder structure, the only difference is the type of VCS used. I did the following

  • We downloaded its code and deleted the .svn folder
  • Created and switched to a new branch "code_to_integrate" (points to my main branch)
  • I copied the downloaded code and replaced my project folder with it. (git folder is stored as such)

At this point, if I run the git status command, I can see the changes (files are marked as changed). I need to integrate with my main branch. Then,

  • The changes introduced there. Allow it commit id c2
  • Checked on my main branch (commit id c1)
  • Merge with the code_to_integrate branch.

As a result, my code in the main branch was overwritten with code in the "code_to_integrate" branch. I lost all my modifications. HEAD is in c2, and I also see c1. If i use

git reset --hard c1,

I will bring my changes back. Right now, for example, using the command

git merge -s theirs

I got all the changes from the merge (code_to_integrate) and lost the changes in the merged branch (master). What's happening?. Should this be true? Any help would be appreciated. thanks in advance

+6
source share
1 answer

The problem is that you created the code_to_integrate branch on top of the master branch. So, it looked like this:

 ... -> oldercommit -> oldcommit -> c1 (master, code_to_integrate) 

When you then passed another guy code to this branch, you get a linear history:

 ... -> oldercommit -> oldcommit -> c1 (master) -> c2 (code_to_integrate) 

When you now merged code_to_integrate into master git, you found that c2 only newer than c1, and did the so-called fast merge switch, which basically only means a commit change that master points to c2 . Imagine that code_to_integrate was just a fast branch that you yourself did to do some work, for example. Correct mistake. Once you're done, you will have the same story, and a quick merge will be exactly what you want.

To fix your problem, you need to tell git which of your old commits is the newest common ancestor of your and the other guy. Basically, you need to tell git at what point the other guy forked your master . You are in such a way that, having checked what is the latest, record that you and the other guy in your history, and then run the code_to_integrate branch. Assuming the other guy forks into oldercommit , you would do git checkout oldercommit and then git checkout -b code_to_integrate and should get something like this.

 ... -> oldercommit (code_to_integrate) -> oldcommit -> c1 (master) 

As soon as you transfer the version of the other guy, you will receive:

  -> c2 (code_to_integrate) / ... -> oldercommit -> oldcommit -> c1 (master) 

When you now merge code_to_integrate into master , git will see that there is a diverging history and a three-way merge is performed (where oldercommit is mergebase), offering to resolve any conflicts that may arise, etc. Is this what you want!

So, you just ran the code_to_integrate branch from the wrong commit. There is no way git or any other version control system can perform a merge without knowing what mergebase is.

EDIT: If you have not shared the changes with another guy, since you entered the code in git, then your mergebase is the oldest commit in your history. The following should do what you want:

 git checkout $(git rev-list --all | tail -n 1) git checkout -b code_to_integrate [ ... put the other guys code into your working directory and commit it ... ] git checkout master git merge code_to_integrate 

The first command checks the oldest commit in your story, which is the last one that you and the SVN guy have together. The second command creates the code_to_integrate branch in your oldest commit and switches to it. Then you throw the code of the other guys into your working directory and pass it to the code_to_integrate branch. Finally, you will return to the master branch and merge another branch.

+1
source

Source: https://habr.com/ru/post/971531/


All Articles