假设我的设置看起来很像
phd/code/
phd/figures/
phd/thesis/
Run Code Online (Sandbox Code Playgroud)
由于历史原因,这些都有自己的git存储库.但我想将它们合并为一个,以简化一些事情.例如,现在我可能会进行两组更改,并且必须执行类似的操作
cd phd/code
git commit
cd ../figures
git commit
Run Code Online (Sandbox Code Playgroud)
表演(现在)很棒
cd phd
git commit
Run Code Online (Sandbox Code Playgroud)
似乎有几种方法可以使用子模块或从我的子存储库中提取,但这比我正在寻找的要复杂一些.至少,我很高兴
cd phd
git init
git add [[everything that's already in my other repositories]]
Run Code Online (Sandbox Code Playgroud)
但这似乎不是一个单行.有什么git可以帮助我吗?
Min*_*ark 143
这是我在这里给出的解决方案:
首先对您的phd目录进行完整备份:我不想为您失去多年的辛勤工作负责!;-)
$ cp -r phd phd-backup
Run Code Online (Sandbox Code Playgroud)将内容移动phd/code到phd/code/code,并修复历史记录,使其看起来一直存在(这使用git的filter-branch命令):
$ 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
Run Code Online (Sandbox Code Playgroud)对于相同的内容phd/figures和phd/thesis(只需更换code与figures和thesis).
现在您的目录结构应如下所示:
phd
|_code
| |_.git
| |_code
| |_(your code...)
|_figures
| |_.git
| |_figures
| |_(your figures...)
|_thesis
|_.git
|_thesis
|_(your thesis...)
Run Code Online (Sandbox Code Playgroud)然后在根目录中创建一个git存储库,将所有内容放入其中并删除旧存储库:
$ cd phd
$ git init
$ git pull code
$ rm -rf code/code
$ rm -rf code/.git
$ git pull figures --allow-unrelated-histories
$ rm -rf figures/figures
$ rm -rf figures/.git
$ git pull thesis --allow-unrelated-histories
$ rm -rf thesis/thesis
$ rm -rf thesis/.git
Run Code Online (Sandbox Code Playgroud)
最后,你现在应该拥有你想要的东西:
phd
|_.git
|_code
| |_(your code...)
|_figures
| |_(your figures...)
|_thesis
|_(your thesis...)
Run Code Online (Sandbox Code Playgroud)这个过程的一个好处是它将保留非版本化的文件和目录.
希望这可以帮助.
只是一个字的警告不过的:如果你的code目录已经有一个code子目录或文件,事情可能会去非常错误的(同为figures和thesis的课程).如果是这种情况,只需在完成整个过程之前重命名该目录或文件:
$ cd phd/code
$ git mv code code-repository-migration
$ git commit -m "preparing the code directory for migration"
Run Code Online (Sandbox Code Playgroud)
当程序完成后,添加最后一步:
$ cd phd
$ git mv code/code-repository-migration code/code
$ git commit -m "final step for code directory migration"
Run Code Online (Sandbox Code Playgroud)
当然,如果code子目录或文件没有版本化,只需使用mv而不是git mv,并忘记git commits.
Ari*_*zis 76
git-stitch-repo将处理git-fast-export --all --date-order命令行上给出的git存储库的输出,并创建一个适合于此的流git-fast-import将创建一个新的存储库,其中包含一个新的提交树中的所有提交,该提交树尊重所有源存储库的历史记录.
imz*_*hev 20
也许,简单地(类似于之前的答案,但使用更简单的命令)在每个单独的旧存储库中进行提交,将内容移动到适当命名的子目录中,例如:
$ 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"
Run Code Online (Sandbox Code Playgroud)
然后将三个单独的回购合并为一个新的,通过做smth像:
$ cd ../..
$ mkdir phd.all
$ cd phd.all
$ git init
$ git pull ../phd/code
...
Run Code Online (Sandbox Code Playgroud)
然后你将保存你的历史,但将继续一个回购.
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
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您需要从filter-branch中排除初始修订版 - HEAD即将结尾处更改为[SHA of 2nd revision]..HEAD- 请参阅:
http://www.git.code-experiments.com/blog/2010/03/merging-git-repositories.html
@MiniQuark解决方案帮助了我很多,但不幸的是它没有考虑源代码库中的标签(至少在我的情况下).以下是我对@MiniQuark答案的改进.
首先创建包含组合repo和merged repos的目录,为每个合并的目录创建目录.
$ mkdir new_phd
$ mkdir new_phd/code
$ mkdir new_phd/figures
$ mkdir new_phd/thesis
拉动每个存储库并获取所有标记.(仅针对code子目录提供说明)
$ cd new_phd/code
$ git init
$ git pull ../../original_phd/code master
$ git fetch ../../original_phd/code refs/tags/*:refs/tags/*
(这是改进点2 MiniQuark答案)移动的内容new_phd/code来new_phd/code/code,并添加code_每个前prefeix 标签
$ 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 - .* - 代码_& - "'HEAD
这样做之后,标签的数量将是过滤分支之前的两倍.旧标签保留在repo中,并code_添加带前缀的新标签.
$ git tag
mytag1
code_mytag1
手动删除旧标签:
$ ls .git/refs/tags/*| grep -v"/ code_"| xargs rm
对其他子目录重复2,3,4点
现在我们有@MiniQuark anwser point 3中的目录结构.
如同MiniQuark anwser的第4点那样,但是在执行拉动之后和删除.git目录之前,请获取标记:
$ git fetch catalog refs/tags/*:refs/tags/*
继续..
这只是另一种解决方案.希望它对某人有所帮助,它帮助了我:)
来自亚里士多德Pagaltzis的 git-stitch-repo 回答仅适用于具有简单线性历史的存储库.
MiniQuark的答案适用于所有存储库,但它不处理标记和分支.
我创建了一个程序,其工作方式与MiniQuark描述的相同,但它使用一个合并提交(具有N个父项),并且还重新创建所有标记和分支以指向这些合并提交.
有关如何使用它的示例,请参阅git-merge-repos存储库.
您建议的顺序
git init
git add *
git commit -a -m "import everything"
Run Code Online (Sandbox Code Playgroud)
会起作用,但你将失去你的提交历史记录。
| 归档时间: |
|
| 查看次数: |
74671 次 |
| 最近记录: |