I am experiencing a wild issue. I have my entire project in the master branch. Earlier, one guy was working on this project, but it was in SVN. He made some changes and I need to integrate those changes with mine. Both projects have the same folder structure, the only difference is the type of VCS used. I did the following
At this stage, If I run git status command, I can see the changes(files are marked as modified) I need to integrate with my master branch. Then,
The result was that my code in the master branch overwritten with the code in the "code_to_integrate" branch. I lost my entire modifications. The HEAD is at c2 and I can see c1 as well. If I use
git reset --hard c1,
I will get back my changes. Right now, its like using the command
git merge -s theirs
I got the entire changes from the merging branch(code_to_integrate) and lost changes in merged branch(master). Whats happening?. This should be really straight forward right?. Any help will be appreciated. Thanks in advance
Merging Branches. Once you've completed work on your branch, it is time to merge it into the main branch. Merging takes your branch changes and implements them into the main branch. Depending on the commit history, Git performs merges two ways: fast-forward and three-way merge.
No, merging does only affect one branch.
Let's go into merging in more detail. When you perform a merge, you effectively merge one branch into another—typically a feature branch or bug fix branch into a main branch such as master or develop. Not only will the code changes get merged in, but also all the commits that went into the feature branch.
To do a merge (locally), git checkout the branch you want to merge INTO. Then type git merge <branch> where <branch> is the branch you want to merge FROM. Because the history of master and the history of make_function share common ancestors and don't have any divergence descendents, we get a "fast-forward" merge.
The problem is that you created the code_to_integrate
branch on top of you master
branch. So things looked like this:
... -> oldercommit -> oldcommit -> c1 (master, code_to_integrate)
When you then committed the other guy's 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 detected that c2
is just newer than c1 and did a so called fast forward merge, which basically means only changing the commit
that master
points to to c2
. Imagine code_to_integrate
was just a quick branch you yourself made to do some work on, e.g. fix a bug. Once you are done you would have the exact same history and a fast forward merge would be precisely what you want.
In order to fix you problem you need to tell git which of you old commits is the newest common ancestor of your and the other guy's work. Basically you need to tell git at which point in time the other guy branched off your master
. You so that by checking which is newest commit that both you and the other guy have in your history and then starting the code_to_integrate
branch there. Assuming that the other guy branched off at oldercommit
, you would do a git checkout oldercommit
followed by a git checkout -b code_to_integrate
and should get something like this.
... -> oldercommit (code_to_integrate) -> oldcommit -> c1 (master)
Once you commit the other guy's version you get:
-> c2 (code_to_integrate)
/
... -> oldercommit -> oldcommit -> c1 (master)
When you now merge code_to_integrate
into master
, git will see that there is a divergent history and do a three-way merge (where oldercommit
is the mergebase), prompting you to resolve any conflicts that might arise, etc. This is what you want!
So in summary you simply started your code_to_integrate
branch from the wrong commit. There is no way git or any other version control system can do a merge without knowing what the mergebase is.
EDIT: If you did not share any changes with the other guy since you put the code into 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 out the oldest commit in your history, which is the last one that you and the SVN guy have in common. The 2nd command creates the code_to_integrate
branch at your oldest commit and switches to it. Then you throw the other guys code into your working directory and commit it to the code_to_integrate
branch. Finally you switch back to your master
branch and merge the other branch in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With