Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a clean way to handle two original git repositories that started with the same content?

Tags:

git

Say I have two repositories that were created from the same initial content. For example, if I were using git to manage my apache config files in /etc/apache2 and I ran git init on machine-a and machine-b separately.

I've since made some configuration changes to machine-b that I would like to apply to the configuration on machine-a without overwriting un-common things like hostnames, etc.

If I do this:

machine-a% remote add machine-b ssh://...
machine-a% git fetch machine-b

I get all the commits on machine-b and GitX shows a wholy disconnected set of commits, as I would expect.

However, if I try to merge any of machine-b's changes I get conflicts on all modified lines.

For my purposes, this is good enough, but I wonder, is there a cleaner solution?

like image 314
Otto Avatar asked Dec 27 '08 04:12

Otto


People also ask

How do I merge two GitHub repositories?

To combine two separate Git repositories into one, add the repository to merge in as a remote to the repository to merge into. Then, combine their histories by merging while using the --allow-unrelated-histories command line option.

Can you have two Git repositories in the same folder?

Yes, it is possible to have two git repositories in one directory. I'm assuming that one remote repository is in GitHub and the other in GitLab. I'm also using two different SSH keys to connect to these remote repositories.

How do I update multiple Git repositories?

to automatically update all git repositories in that directory. You can mix and match bookmarks and command arguments: gitup --add ~/repos/foo ~/repos/bar gitup ~/repos/baz # update 'baz' only gitup # update 'foo' and 'bar' only gitup ~/repos/baz --update # update all three!


1 Answers

You might want to look at git grafts. Some information is available here: http://git-scm.com/docs/git-filter-branch

basically, what you want to do is to fake an ancestry.

You did an initial commit on both machines -- let's call them 'baseA' and 'baseB'. Then, you created a second commit on top of that on both sides -- 'secondA' and 'secondB'. What you want to do is tell git that 'secondB' does not have 'baseB' as ancestor, but instead has 'baseA' as parent.

You can this by using grafts. For example, put this in your .git/info/grafts file:

secondB baseA

(but then using the real SHA's). Now, if you look in GitX, you will see that the histories are connected. To make the change permanent, you need to run git filter-branch.

Update from the comments

I'm not sure what you did is 'correct', though it will work. If you do what you did, you will get as history:

 BaseA --- SecondA -- .. - ..  - Merge
   \ BaseB --- SecondB ... - .. /

Which will work (and the merge will succeed without problems). However, what's a bit nicer is this:

 BaseA --- SecondA -- .. - ..  - Merge
   \ SecondB ... - .. /

which basically drops "BaseA" as commit and sets "BaseA" as the parent for SecondB. This should be possible using the graft rule I told you.

To demonstrate this, I created a small repository you can download here.

If you look at the history in GitX ("gitx master second_master"), you will see that the histories are disconnected. If you move the .git/info/_grafts file to .git/info/grafts, you will get the second, nice-looking history.

I also added a .git/info/wrong_grafts file. If you use that one, you will get the history you created.

If you look at the SHA's in the grafts file, you'll see that the _grafts file basically has this:

SecondB BaseA

and the wrong_grafts file has this:

BaseB BaseA
like image 110
Pieter Avatar answered Sep 30 '22 12:09

Pieter