git automatically rename merged files

2019-08-11 10:09发布

问题:

I want to create a repository that is the combination of two existing repositories.

The two repo's are largely uncoupled however there are a few meta files that show up in both repos, mainly .gitignore, .gitattributes and README.md.

The following would basically reproduce my situation.

mkdir repoa
cd repoa
git init 
touch .gitignore
touch README.md
mkdir adir
touch adir/afile
git add -A
git commit -m"repoa"

mkdir repob
cd repob
git init 
touch .gitignore
touch README.md
mkdir bdir
touch bdir/bfile
git add -A
git commit -m"repob"

mkdir repoab
cd repoab
git init
git remote add repoa /path/to/repoa
git remote add repob /path/to/repob
git pull repoa master
git pull repob master

At this point we will receive the conflict message.

Is there some way, between the git init for repoab and the git pull's that I can tell repoab to automatically rename the README.md from repoa to READMErepoa.md and the README.md from repob to READMErepob.md.

Further complexity arises with the .gitignore files. Essentially the .gitignore file in repoab should be the combination of repoa/.gitignore with repob/.gitignore as well some rules for repoab. A perfect scenario here would be that I use the same rename strategy as for the README.md files, repoa/.gitignore becomes repoab/.gitignorerepoa, similar for repob. Then if there were some way to include the files in the repoab/.gitignore.

I asked a question yesterday about the possibility of .gitignore folders, containing multiple .gitignore files which I believe would solve this situation but it didn't garner much attention.

Another beast altogether is the .gitattribute's files, I would be looking for a union of the 3 files (repoa/.gitattributes + repob/.gitattributes + repoab/.gitattributes). A .gitattributes folder may be useful here as well.

So the issue is that I have several of these simple conflict resolutions. It's no big deal to merge the files once. However I'm going to end up with the same conflicts every single time I pull from either repo. I'm not sure if I would also end up with problems because committing repoab/.gitignore will put repoab's version of .gitignore ahead of repoa and repob.


Update: An example of where I think this sort of meta-file management could be useful

Suppose I have an application modeled by MVC with the following simple directory tree.

myapplication/
--README.md
--.gitignore
--.gitattributes
--main.p
--model/
----myapplication.m
--view/
----myapplication.v
--control/
----myapplication.c
--plugins/

This application works and does foo but it also allows for plugins to be added.

I've designed myapplication so that you can create a plugin without modifying any of the code for myapplication, when it runs, main.p will grab any plugins it finds in the plugins directory, the plugins will be responsible for their own model/view/control files.

So now I want to start working on my new plugin, plugina. Rather than cloning myapplication and starting to work, I can create a repository for plugina, this repository contains the following.

myapplication/
--README.md
--.gitignore
--.gitattributes
--model/
----plugina.m
--view/
----plugina.v
--control/
----plugina.c
--plugins/
----plugina.p

Now I create a new repository that will be used for developing and testing plugina.

This repository is the merger of myapplication and plugina, created in the same manor as I created repoab above. This is where I have my merge conflicts with .gitignore and README.md

myapplication/
--README.md (CONFLICT with plugina/myapplication)
--.gitignore (CONFLICT with plugina/myapplication)
--.gitattributes
--main.p
--model/
----myapplication.m
----plugina.m
--view/
----myapplication.v
----plugina.v
--control/
----myapplication.c
----plugina.c
--plugins/
----plugina.p

Not a huge problem, I handle the conflict and can continue dev. The conflicts however undoubtedly lower the number of times I commit or update code, knowing that I have that hurdle.

With this technique I can have a large number of plugins and I can create a version of myapplication with any random collection of plugins. Since I'm using repositories rather than copy/pasting plugin code I can have all the benefits of version control for my plugins in any repo that makes use of them, I can keep the plugins up to date, if I find a global issue with the plugin I can push it back to the plugin repo, if a plugin update doesn't work with this repo I can roll it back.

This whole workflow is just held back by the fairly trivial hurdle of these constant merge conflicts.

回答1:

Git isn't built for this sort of thing. You're going to constantly have merge conflicts coming from repos A and B, and even if there were a way to set up the rules you want, it would probably be no more work than a script to perform the renames and concatenations you're describing.

The closest thing you can get is using Git submodules. This lets you put repo A and repo B into subdirectories in repo AB. They remain totally independent in those subdirectories, but repo AB maintains their state - basically, AB tracks which version of each is checked out.