简体   繁体   中英

GIT merging unrelated histories

I am merging two unrelated histories. Three-way merge does not work as there is no "base" commit (or files) to compare. So every file is conflicting (as it wants to merge whole files form both). Is there anyway to create a "dummy" ancestor to have this base commit for the actual merge (only the lines which differ to be merged or conflict

I have two repos. Unfortunately one was just copied from the another one and developer was working on it for a quite a long tine. They are very similar. Now I want to merge them. Because they do not have (from the git point of view) common history. when I merge them there is no base file to merge so all files conflict, git wants to merge both files (all lines). I cant explain it better.

Is there anyway to create a "dummy" ancestor to have this base commit for the actual merge (only the lines which differ to be merged or conflict ...

Not easily.

You can use git replace --graft to insert a dummy ancestor for the duration of the merge. But you must come up with the content for that dummy commit manually. Unless you have to do this merge repeatedly, you might as well just run git merge --allow-unrelated-histories and manually fix up the result, as coming up with the base file for each add/add conflict is just as much work as resolving each add/add conflict.

Let's say you have written a program or script to come up with a base file from the two add/add conflict inputs by taking common lines. You can still proceed this way. What you can do is:

git merge --allow-unrelated-histories <commit-specifier>

for file in $(cat list-of-add-add-conflict-files); do
    git show :2:$file > file.ours
    git show :3:$file > file.theirs
    program_or_script file.ours file.theirs > file.base
    git merge-file file.ours file.base file.theirs
    mv file.ours $file; rm file.theirs file.base # this rm can be deferred
done

This uses the git merge-file command to merge three individual files. The three files in this case are:

  • file.ours : the copy from slot 2 of the index, ie, from HEAD ;
  • file.theirs : the copy from slot 3 of the index, ie, from their tip commit;
  • file.base : the file your program or script came up with

The git merge-file command is the same low-level merge driver that Git uses by default, extracted into a separate program that you can run. So this produces the same result you would get, had you run this program on every file-pair and made a dummy ancestor, committed it, and used git replace --graft to insert it. But you didn't have to run git commit to make a dummy commit and then graft it, so you have saved several steps.

试试这个命令,它可能会有所帮助

git pull --allow-unrelated-histories

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM