使用diff和patch强制一个本地代码库看起来像另一个

时间:2010-03-15 21:37:41

标签: diff patch

当我使用它们强制一个代码库与另一个代码库完全相同时,我注意到了diff和patch的奇怪行为。假设我想将update_me更新为与leave_unchanged相同。我去update_me。我从leave_unchanged运行diff到update_me。然后我将diff修补到update_me。如果leave_unchanged中有新文件,补丁会询问我补丁是否被撤消了!如果我回答是,它将删除leave_unchanged中的新文件。然后,如果我只是重新运行补丁,它会正确修补update_me。

为什么补丁尝试修改leave_unchanged和update_me?

这样做的正确方法是什么?我找到了一种hacky方法,即用无意义路径替换所有+++行,因此patch无法找到leave_unchanged。然后它工作正常。这是一个如此丑陋的解决方案。

$ mkdir copyfrom
$ mkdir copyto
$ echo "Hello world" > copyfrom/myFile.txt
$ cd copyto
$ diff -Naur . ../copyfrom > my.diff
$ less my.diff

diff -Naur ./myFile.txt ../copyfrom/myFile.txt
--- ./myFile.txt        1969-12-31 19:00:00.000000000 -0500
+++ ../copyfrom/myFile.txt      2010-03-15 17:21:22.000000000 -0400
@@ -0,0 +1 @@
+Hello world

$ patch -p0 < my.diff

The next patch would create the file ../copyfrom/myFile.txt,
which already exists!  Assume -R? [n] yes
patching file ../copyfrom/myFile.txt

$ patch -p0 < my.diff
patching file ./myFile.txt

修改

我注意到Mercurial通过预先挂起的“a”和“b”目录来避免这个问题。

$ hg diff
--- a/crowdsourcing/models.py   Mon Jun 14 17:18:46 2010 -0400
+++ b/crowdsourcing/models.py   Thu Jun 17 11:08:42 2010 -0400
...

1 个答案:

答案 0 :(得分:2)

我相信这里的答案是在父目录中执行你的差异。然后使用patch -p1去除第一个段。我相信这就是为什么补丁的strip选项实际上默认为1而不是0。使用上面的例子

$ mkdir copyfrom
$ mkdir copyto
$ echo "Hello world" > copyfrom/myFile.txt
$ diff -Naur copyto copyfrom > my.diff
$ less my.diff

diff -Naur copyto/myFile.txt copyfrom/myFile.txt
--- copyto/myFile.txt    1970-01-01 12:00:00.000000000 +1200
+++ copyfrom/myFile.txt    2010-10-19 10:03:43.000000000 +1300
@@ -0,0 +1 @@
+Hello world

$ cd copyto
$ patch -p1 < ../my.diff

与你的例子的唯一区别是我从父目录执行了diff,因此被比较的目录处于同一级别。