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中有什么可以帮助我的吗?


当前回答

下面是我给出的一个解决方案:

First do a complete backup of your phd directory: I don't want to be held responsible for your losing years of hard work! ;-) $ cp -r phd phd-backup Move the content of phd/code to phd/code/code, and fix the history so that it looks like it has always been there (this uses git's filter-branch command): $ cd phd/code $ git filter-branch --index-filter \ 'git ls-files -s | sed "s#\t#&code/#" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD Same for the content of phd/figures and phd/thesis (just replace code with figures and thesis).

现在你的目录结构应该是这样的:

    phd
      |_code
      |    |_.git
      |    |_code
      |         |_(your code...)
      |_figures
      |    |_.git
      |    |_figures
      |         |_(your figures...)
      |_thesis
           |_.git
           |_thesis
                |_(your thesis...)

然后在根目录中创建一个git存储库,将所有内容都拉到其中,并删除旧的存储库: $ CD博士 $ git init $ git拉码 $ rm -rf code/code $ rm -rf代码/.git $ git拉数据-允许不相关的历史 $ rm -rf figures/数字 $ rm -rf数字/.git $ git拉论文-允许不相关的历史 $ rm -rf thesis/thesis $ rm -rf thesis/.git

最后,你现在应该得到你想要的:

    phd
      |_.git
      |_code
      |    |_(your code...)
      |_figures
      |    |_(your figures...)
      |_thesis
           |_(your thesis...)

这个过程的一个优点是,它将保留不受版本控制的文件和目录。


不过,只有一个警告:如果您的代码目录已经有一个代码子目录或文件,情况可能会非常糟糕(当然,对于图表和论文也是如此)。如果是这种情况,在执行整个过程之前,只需重命名该目录或文件:

$ cd phd/code
$ git mv code code-repository-migration
$ git commit -m "preparing the code directory for migration"

当程序完成后,添加最后一步:

$ cd phd
$ git mv code/code-repository-migration code/code
$ git commit -m "final step for code directory migration"

当然,如果代码子目录或文件没有版本控制,只需使用mv而不是git mv,忘记git的提交。

其他回答

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

你建议的顺序

git init
git add *
git commit -a -m "import everything"

将工作,但您将丢失提交历史。

合并mainProject中的secondProject:

A)在第二个项目中

git fast-export --all --date-order > /tmp/secondProjectExport

B)在主项目中:

git checkout -b secondProject
git fast-import --force < /tmp/secondProjectExport

在这个分支中完成你需要做的所有繁重的转换并提交它们。

C)然后回到主分支和两个分支之间的经典合并:

git checkout master
git merge secondProject

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

下面是我给出的一个解决方案:

First do a complete backup of your phd directory: I don't want to be held responsible for your losing years of hard work! ;-) $ cp -r phd phd-backup Move the content of phd/code to phd/code/code, and fix the history so that it looks like it has always been there (this uses git's filter-branch command): $ cd phd/code $ git filter-branch --index-filter \ 'git ls-files -s | sed "s#\t#&code/#" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD Same for the content of phd/figures and phd/thesis (just replace code with figures and thesis).

现在你的目录结构应该是这样的:

    phd
      |_code
      |    |_.git
      |    |_code
      |         |_(your code...)
      |_figures
      |    |_.git
      |    |_figures
      |         |_(your figures...)
      |_thesis
           |_.git
           |_thesis
                |_(your thesis...)

然后在根目录中创建一个git存储库,将所有内容都拉到其中,并删除旧的存储库: $ CD博士 $ git init $ git拉码 $ rm -rf code/code $ rm -rf代码/.git $ git拉数据-允许不相关的历史 $ rm -rf figures/数字 $ rm -rf数字/.git $ git拉论文-允许不相关的历史 $ rm -rf thesis/thesis $ rm -rf thesis/.git

最后,你现在应该得到你想要的:

    phd
      |_.git
      |_code
      |    |_(your code...)
      |_figures
      |    |_(your figures...)
      |_thesis
           |_(your thesis...)

这个过程的一个优点是,它将保留不受版本控制的文件和目录。


不过,只有一个警告:如果您的代码目录已经有一个代码子目录或文件,情况可能会非常糟糕(当然,对于图表和论文也是如此)。如果是这种情况,在执行整个过程之前,只需重命名该目录或文件:

$ cd phd/code
$ git mv code code-repository-migration
$ git commit -m "preparing the code directory for migration"

当程序完成后,添加最后一步:

$ cd phd
$ git mv code/code-repository-migration code/code
$ git commit -m "final step for code directory migration"

当然,如果代码子目录或文件没有版本控制,只需使用mv而不是git mv,忘记git的提交。