2025-03-16 09:00:01

组合多个git存储库

假设我有一个这样的设置

phd/code/
phd/figures/
phd/thesis/

由于历史原因,这些都有自己的git存储库。但是我想把它们合并成一个,这样可以简化一些。例如,现在我可能要做两组更改,并且必须做一些类似的事情

cd phd/code
git commit 
cd ../figures
git commit

(现在)只要能表演就好了

cd phd
git commit

似乎有几种方法可以使用子模块或从我的子存储库中提取,但这比我想要的要复杂一些。至少让我满意的

cd phd
git init
git add [[everything that's already in my other repositories]]

但这似乎不是一句俏皮话。git中有什么可以帮助我的吗?


当前回答

也许,简单地(类似于前面的答案,但使用更简单的命令)在每个单独的旧存储库中进行提交,将内容移动到一个适当命名的子目录中,例如:

$ cd phd/code
$ mkdir code
# This won't work literally, because * would also match the new code/ subdir, but you understand what I mean:
$ git mv * code/
$ git commit -m "preparing the code directory for migration"

然后将三个单独的回购合并为一个新的,通过这样做SMTH:

$ cd ../..
$ mkdir phd.all
$ cd phd.all
$ git init
$ git pull ../phd/code
...

然后您将保存历史记录,但将继续进行单个回购。

其他回答

借助IntelliJ IDEA Community Edition中的git集成,我手动将3个git存储库合并为一个。

Create a new repo, add a new commit to the master branch with an empty README.md file. Add three remotes for the new repo, using the name of the 3 repositories and the remote URL of them respectively. Run Git Fetch. Create a new local branch named temp based on the master branch, so we can start over without pollute the master branch. Checkout the temp branch. Select to only show commits of one remote branch(one repository). Select all the commits and right click to Cherry-Pick them. Create directory structure for this repository, then move the files into it and commit. Repeat the step 4 to 6 for the other 2 remote branch(repository). When everything is OK, merge all the changes in the temp branch into master branch.

然后添加主分支的原始远程URL并推送到它。

也许,简单地(类似于前面的答案,但使用更简单的命令)在每个单独的旧存储库中进行提交,将内容移动到一个适当命名的子目录中,例如:

$ cd phd/code
$ mkdir code
# This won't work literally, because * would also match the new code/ subdir, but you understand what I mean:
$ git mv * code/
$ git commit -m "preparing the code directory for migration"

然后将三个单独的回购合并为一个新的,通过这样做SMTH:

$ cd ../..
$ mkdir phd.all
$ cd phd.all
$ git init
$ git pull ../phd/code
...

然后您将保存历史记录,但将继续进行单个回购。

亚里士多德Pagaltzis回答的git-stitch-repo只适用于具有简单线性历史的存储库。

MiniQuark的答案适用于所有存储库,但它不处理标记和分支。

我创建了一个与MiniQuark描述的工作方式相同的程序,但是它使用一个合并提交(有N个父级),并且还重新创建了指向这些合并提交的所有标记和分支。

有关如何使用它的示例,请参阅git-merge-repos存储库。

你可以尝试子树合并策略。它可以让你将回购B合并到回购A。相对于git-filter-branch的优点是它不需要你重写回购A的历史记录(破坏SHA1和)。

git-stitch-repo将在命令行中给出的git存储库上处理git-fast-export——all——date-order的输出,并创建一个适合于git-fast-import的流,该流将创建一个新的存储库,其中包含一个新的提交树中的所有提交,该提交树尊重所有源存储库的历史。