大约五个月前,我们开始了一个项目,对大型PHP-4/5应用程序进行大修和升级,将其转移到PHP-7(以及许多其他方面)。该应用程序包含2,700多个文件,并对几乎所有文件进行了大量更改。
与此同时,遗留应用程序继续为客户提供支持,迄今已进行了大约250次更改。我有(并且可以制作......)git
补丁来表示这些变化。我当前的问题是,他们中的大多数都没有git apply
。
当然,很容易理解为什么:补丁中表达的“行号”非常无用。虽然在大多数情况下,正在查找的源代码是,但它可能已移动了一段距离。
我目前的想法(基于对大约30个补丁文件的检查)是有用的 - 很多情况下要修补的文字源代码是仍然在源文件中逐字存在,而不是在预期的位置。
虽然我现实足以知道许多这些补丁必须手工分析和制作,但我想最大限度地减少这一点,无论是为了时间还是为了准确。我希望那些将会这样做的人......包括我(!)......能够尽可能地利用自动化工具,因为他们知道他们必须检查每个补丁的工作。我没有幻想,我可能会立即自动执行所有这些文件,“Shazam。”
因此,谁在那里处理过类似的情况?你有什么建议我这样做?一个建议是使用带有patch
选项的fuzz
命令,但需要注意的是,或可能会导致应用错误的补丁。
(我们计划在任何情况下一次做一个补丁:“补丁,git commit
,冲洗并重复。”这样我们就可以git diff
检查每个改变理智。)
“战争故事”要求。感谢。
答案 0 :(得分:0)
我有类似的经历。我们的团队正在开发谷歌不同芯片组和不同版本的Android代码库。所谓的通用颁发或功能从一个代码库移植或重用到另一个代码库。
如果它从Android M到Android M,它会更容易。但是我们遇到了从Android L到Android M或Android N的问题。一些补丁(通常是几百个)很难直接应用。并且git补丁是++ - diff,它们不够清晰或不够简单,当我们必须手动应用它们时,它们让我们很生气。
代码库由400多个git repos组成。因此,我们为每个仓库制作按日期排序的提交列表。我们为每个提交制作一个前后补丁。前后补丁是并排补丁。左边是更改前的文件,右边是更改后的文件。补丁文件夹结构类似于<commit>/before
,<commit>/after
。因此,我们可以轻松使用“超越比较”等工具。以更友好的方式看待变化。
我们有一个脚本来制作前后补丁。它基本上是这样的:
#!/bin/bash
#takes one parameter, the commit
commit=$1
#copy the modified files after the change
git checkout -f $commit
git log -1 $commit --name-only --pretty=%h | tail -n +3 | while read line
do
mkdir -p ~/backup/$commit/after/$(dirname $line)
cp -v $line ~/backup/$commit/after/$line
done
#copy the same files before the change
git checkout -f $commit^
git log -1 $commit --name-only --pretty=%h | tail -n +3 | while read line
do
mkdir -p ~/backup/$commit/before/$(dirname $line)
cp -v $line ~/backup/$commit/before/$line
done
然后,差异补丁和之前的补丁和列表都会传递给团队成员。如果无法自动应用git diff补丁,我们只需按照之前的补丁手动应用它。虽然工作量很大,但还是要完成。
答案 1 :(得分:0)
git apply
提供了几个选项,可用于试探性地或半手动地应用补丁,git-apply(1)
手册页中对此进行了详细描述:
-C
可以减少为了成功修补必须在块中匹配的上下文行的数量。
-C<n>
- 确保每次更改前后至少有
<n>
行周围上下文匹配。当周围环境的行数减少时,它们都必须匹配。默认情况下,不会忽略任何上下文。
--recount
将忽略行号。
--recount
- 不要相信块头中的行数,而是通过检查补丁来推断它们(例如,在编辑补丁后未适当调整块头)。
--reject
会像.rej
一样在patch
文件中留下无法应用的块。然后,您可以检查这些文件并手动应用更改。
--reject
- 对于原子性,默认情况下,
git apply
会使整个补丁失效,并且当某些块不适用时不会触及工作树。此选项使它可以应用补丁的适用部分,并将被拒绝的块保留在相应的* .rej文件中。
--3way
将尝试三向合并,假设补丁最初是由git生成的。
-3
--3way
- 当补丁不能完全应用时,如果该补丁记录了它应该应用于blob的标识,并且这些blob在本地可用,可能会将冲突标记保留在工作树的文件中,以供用户解决。此选项暗含
--index
选项,并且与--reject
和--cached
选项不兼容。
我个人使用git apply -C1 --recount
成功地将被子补丁转换为git commits。
或者,您可以简单地使用patch
实用程序来应用补丁,而根本不使用git apply
命令。默认情况下,patch
将模糊地应用块,而将块完全无法应用于.rej
文件中;如果指定了--merge
选项,则失败的大块将改为生成冲突标记。