我想将两个文件从一个存储库移动到另一个存储库。这些文件最初添加为:
/src/init/Price.cs
/tests/init/PriceTests.cs
这两个文件后来被重命名为:
/src/init/PriceValue.cs
/tests/init/PriceValueTests.cs
然后转到:
/src/moved/PriceValue.cs
/tests/moved/PriceValueTests.cs
我试图通过this description为这些文件创建一组补丁,但我不确定如何传递文件存在的六种不同路径。
我设法找到影响PriceValue.cs
的所有提交ID(跨重命名和移动),但将这些ID传递给Git失败,并显示以下错误消息:
$ git format-patch -o /tmp/pricevaluepatches $(git log --all dfeeb 6966b 9f882 …)
-bash: /usr/local/bin/git: Argument list too long
那么,我如何为此创建一组补丁,其中只包含对上述文件的更改,但是在每个文件的一次重命名和一次移动中包含它?
答案 0 :(得分:6)
您可以使用
获取一些特定文件的补丁但不早于提交sha1
git format-patch sha1 -- file1 file2 ...
任何文件都可以是旧文件(重命名之前)或现有文件。
如果您希望所有提交,直到提交sha1
,您可以使用
git format-patch --root sha1 -- file1 file2 ...
所以在你的情况下,你的六个文件的所有提交到现在(HEAD
):
git format-patch --root HEAD -- /src/init/Price.cs /src/init/PriceValue.cs /src/moved/PriceValue.cs /src/init/PriceTests.cs /src/init/PriceValueTests.cs /src/moved/PriceValueTests.cs
答案 1 :(得分:1)
嗯.....假设我想保留补丁文件的方式,我会做的是将补丁文件应用到分支上,以便我可以在正确的分支上挑选它。 / p>
所以,假设我的master分支上有一个名为/tests/moved/PriceValueTests.cs的文件,我想在其上应用一个名为/tests/init/PriceTests.cs的补丁。假设我不想要破解补丁文件,我会做的是:
这样,git可以跟踪名称更改并能够成功应用它。我已多次完成它并且git的文件重命名算法倾向于使其正确。
答案 2 :(得分:1)
要通过合并来实现问题的目标(而不是像问题那样通过格式补丁移动单个补丁),可以删除新提交中的所有其他文件,然后将该提交跨存储库合并到目标存储库中(改编自https://stackoverflow.com/a/10548919/7496656):
cd path/to/project-a
git checkout -b for-b master # or whichever branch you want to merge from
git rm -r .
git checkout HEAD -- src/moved/PriceValue.cs tests/moved/PriceValueTests.cs
git commit
cd path/to/project-b
git remote add project-a path/to/project-a
git fetch project-a
git merge --allow-unrelated-histories project-a/for-b
git remote remove project-a
cd path/to/project-a
git branch -D for-b
这样做的好处是所有历史记录都存在,提交ID保持不变,并且不需要处理单个提交或找不到它们。这可能有一个缺点,即线性视图(如git log
)而不是图形视图(如gitk
)可能会变得更加混乱,因为无关的提交数量会变得更大。
还可以在合并之前过滤存储库project-a
,以隐藏不相关的文件或提交。然而,其缺点是:如果您跨存储库合并多次执行此操作(可能也在另一个方向),则会使历史记录不那么干净,因为常见历史记录只会多次出现(每次合并一次)。这也会使这个解决方案比您最初尝试的解决方案更难。这也有一个缺点,即提交ID不会保持不变,因此在存储库中找到相同的提交并不容易。