8

我想将两个文件从一个存储库移动到另一个。这些文件最初添加为:

  1. /src/init/Price.cs
  2. /tests/init/PriceTests.cs

这两个文件后来被重命名为:

  1. /src/init/PriceValue.cs
  2. /tests/init/PriceValueTests.cs

然后移动到:

  1. /src/moved/PriceValue.cs
  2. /tests/moved/PriceValueTests.cs

我试图通过这个描述为这些文件创建一组补丁,但我不确定如何传递文件存在的六个不同路径。

我设法找到了所有影响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

那么,我如何为此创建一组补丁,其中仅包含对上述文件的更改,但在每个文件的一次重命名和一次移动中包含它?

4

3 回答 3

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
于 2017-05-03T05:28:35.123 回答
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 保持不变,无需处理单个提交或找到它们。这可能有一个缺点,即线性化视图(like git log)与图形视图(like gitk)相反,随着不相关提交的数量越来越多,可能会变得更加混乱。

project-a还可以在合并之前过滤存储库,以隐藏不相关的文件或提交。但是,这样做的缺点是:如果您在存储库合并中多次执行此操作,也可能在另一个方向上,它会使历史记录不那么干净,因为公共历史记录只会出现多次(每次合并一次)。这也会使该解决方案比您最初尝试的解决方案更加困难。这也有一个缺点,即提交 ID 不会保持不变,因此很难找到跨存储库的相同提交。

于 2017-05-14T14:55:26.817 回答
1

嗯.....假设我想保持补丁文件的原样,我要做的就是将补丁文件应用到一个分支上,这样我就可以在正确的分支上挑选它。

所以,假设我的主分支上有一个名为 /tests/moved/PriceValueTests.cs 的文件,我想在它上面应用一个名为 /tests/init/PriceTests.cs 的补丁。假设我不想破解补丁文件,我会做的是:

  • 从我的主人创建一个临时分支
  • 结帐临时分支
  • 将文件重命名为与补丁文件相同的路径(当然还有提交)
  • 在临时分支上应用补丁文件(现在应该可以工作,因为文件路径有一个匹配的文件)
  • 在临时分支上提交
  • 结帐大师
  • 从临时分支中挑选最后一个修订版

这样 git 可以跟踪名称更改并能够成功应用它。我已经做过很多次了,git 的文件重命名算法往往是正确的。

于 2017-05-02T18:45:54.250 回答