假设我有一个这样的设置
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中有什么可以帮助我的吗?
@MiniQuark解决方案帮助了我很多,但不幸的是,它没有考虑到源存储库中的标记(至少在我的情况下)。以下是我对@ mini夸克答案的改进。
First create directory which will contain composed repo and merged repos, create directory for each merged one.
$ mkdir new_phd
$ mkdir new_phd/code
$ mkdir new_phd/figures
$ mkdir new_phd/thesis
Do a pull of each repository and fetch all tags. (Presenting instructions only for code sub-directory)
$ cd new_phd/code
$ git init
$ git pull ../../original_phd/code master
$ git fetch ../../original_phd/code refs/tags/*:refs/tags/*
(This is improvement to point 2 in MiniQuark answer) Move the content of new_phd/code to new_phd/code/code and add code_ prefeix before each tag
$ 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' --tag-name-filter 'sed "s-.*-code_&-"' HEAD
After doing so there will be twice as many tags as it was before doing filter-branch. Old tags remain in repo and new tags with code_ prefix are added.
$ git tag
mytag1
code_mytag1
Remove old tags manually:
$ ls .git/refs/tags/* | grep -v "/code_" | xargs rm
Repeat point 2,3,4 for other subdirectories
Now we have structure of directories as in @MiniQuark anwser point 3.
Do as in point 4 of MiniQuark anwser, but after doing a pull and before removing .git dir, fetch tags:
$ git fetch catalog refs/tags/*:refs/tags/*
Continue..
这是另一个解。希望它能帮助别人,它帮助了我:)
也许,简单地(类似于前面的答案,但使用更简单的命令)在每个单独的旧存储库中进行提交,将内容移动到一个适当命名的子目录中,例如:
$ 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
...
然后您将保存历史记录,但将继续进行单个回购。
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