我将应用大约 305 个补丁,我知道会有很多"拒绝"。
在我这样做之前,我想知道如果一个.rej
文件已经存在,patch
会怎么做,因为我完全期望它会存在。
我的替代方案是使用 --merge
,它会创建git
用户非常熟悉的<<<...>>>
标签。(呵呵...但在这种情况下,我担心这些标签的存在,如果有很多,可能会干扰未来的修补。
(关于哪一个可能最好有什么意见吗?
我基本上计划"在for
循环中应用补丁,让他们尽其所能,然后清理。(这注定是一个愉快的下午。我知道我将非常手动地执行此步骤,但我还不知道可能有多少.rej
文件。(但是,我已经可以看到将超过100个。
战争故事受到欢迎。
patch
只是覆盖现有的.rej
文件。但是您可以使用-r
选项将拒绝发送到您选择的文件中:
-r
拒绝文件或--reject-file=
拒绝文件将拒绝放入拒绝文件而不是默认
.rej
文件中。 什么时候 拒绝文件-
,丢弃拒绝。
请注意,在这种情况下,不同文件的拒绝大块都以统一的 diff 格式放入同一个文件中。
因此,您可以编写循环以在每次迭代中使用不同的拒绝文件:
for p in patch*
do
patch -p0 -r "$p".rej <"$p"
done
但是,我的建议是,一旦拒绝了一个大块头,就立即停止修补过程,并在继续之前解决冲突。您可以在修补循环中对该逻辑进行编码,如下所示:
apply_patches
#!/bin/bash
for p in "$@"
do
echo
echo "----------- Applying patch $p ------------"
rejectfile="$p".rej
patch -p0 -r "$rejectfile" <"$p"
if [ -s "$rejectfile" ]
then
echo
echo "Some hunks could not be applied (see $rejectfile)"
read -p "Please address them and then press ENTER "
fi
done
现在记录一下这项工作的结果:
是的,patch
确实会覆盖.rej
文件,Leon 建议的脚本是我非常好的起点。但是,我发现.rej
文件的内容对我来说基本上毫无用处。 重新阅读patch
文档(在Linux上,但在Macintosh OS/X上不是(!),我看到有一个--merge
选项可用,它将对文件产生<<<< ==== >>>>
修改(就像git
例行公事一样......
我使用 git format-patch
命令获取作为单个补丁文件的提交列表,并修改了 Leon 的原始脚本以遍历该目录的内容。
我没有像Leon建议的那样使用-r
选项,而是使用了--merge
选项。由于现在没有要测试的拒绝文件,我将脚本更改为使用 patch
命令的退出代码 ( "$?"
)。(像往常一样,"零等于成功。
如果patch
命令成功(返回零...),我的脚本会将补丁文件mv
到另一个"已应用的补丁"目录中。如果没有,它将打印一条消息并停止。我通过以下方式解决了每个此类事件:
- 一个
接一个地注意补丁中的哪些文件有错误。打开其中每个文件并搜索
<<<<<
标记。通过这种方式,我可以并排查看两个选项,并且逐案进行个人选择和手动更正。然后,将补丁文件
mv
到"已应用的补丁"目录,就像脚本在完全应用补丁而没有错误的情况下所做的那样。扫描(PHP ...)源目录以查找任何语法错误,使用我设计的自定义工具。立即 (!) 解决发现的任何问题。
git commit
变化...以防万一!再次启动脚本...
现在,一个有趣的问题。 。 。
现在,正如我在原始帖子中所说,我正在将这些(数百个......)补丁应用于源代码库,该源代码库已经从中文本复制了好几个月。 (在拆分时,git
存储库甚至不存在。该公司仍在使用SVN。因此,patch
几乎从未能够依赖行号。
在每种情况下,patch
确实发现它已经找到了应用每个补丁的正确位置,与补丁中列出的行号有一些"偏移"。不过我发现在某些情况下,patch
没有(!)正确识别所有内容。有时,它会在现有代码的相同片段前面标记"插入",人类会认识到它根本不是插入。
当然,我现在"焦急地希望"在每种情况下patch
都"认识到自己的不确定性",因此没有一个"成功应用"的补丁(大约三分之二,事实证明......)将被证明存在重复问题。(这是我们不断检查代码库中任何地方的语法错误的主要原因之一,而且碰巧几乎从未发现任何语法错误。