假设我有一个这样的设置
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中有什么可以帮助我的吗?
合并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-filter-branch解决方案工作得很好,但请注意,如果你的git repo来自SVN导入,它可能会失败,并发出如下消息:
Rewrite 422a38a0e9d2c61098b98e6c56213ac83b7bacc2 (1/42)mv: cannot stat `/home/.../wikis/nodows/.git-rewrite/t/../index.new': No such file or directory
在这种情况下,你需要从过滤器分支中排除最初的修订——即将最后的HEAD更改为[SHA of second revision]。头部-见:
http://www.git.code-experiments.com/blog/2010/03/merging-git-repositories.html
也许,简单地(类似于前面的答案,但使用更简单的命令)在每个单独的旧存储库中进行提交,将内容移动到一个适当命名的子目录中,例如:
$ 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
...
然后您将保存历史记录,但将继续进行单个回购。
下面是我给出的一个解决方案:
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的提交。