使用 diff 和 patch 强制一个本地代码库看起来像另一个
当我使用 diff 和 patch 来强制一个代码库与另一个代码库相同时,我注意到了 diff 和 patch 的这种奇怪行为。假设我想更新 update_me 使其看起来与leave_unchanged 相同。我去update_me。我运行了从leave_unchanged 到update_me 的差异。然后我将差异修补到 update_me 中。如果leave_unchanged中有新文件,patch会询问我的patch是否被撤销!如果我回答“是”,它将删除leave_unchanged中的新文件。然后,如果我简单地重新运行补丁,它就会正确地修补 update_me。
为什么patch尝试同时修改leave_unchanged和update_me?
执行此操作的正确方法是什么?我发现了一种奇怪的方法,即将所有 +++ 行替换为无意义的路径,这样补丁就找不到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
...
I've noticed this strange behavior of diff and patch when I've used them to force one code base to be identical to another. Let's say I want to update update_me to look identical to leave_unchanged. I go to update_me. I run a diff from leave_unchanged to update_me. Then I patch the diff into update_me. If there are new files in leave_unchanged, patch asks me if my patch was reversed! If I answer yes, it deletes the new files in leave_unchanged. Then, if I simply re-run the patch, it correctly patches update_me.
Why does patch try to modify both leave_unchanged and update_me?
What's the proper way to do this? I found a hacky way which is to replace all +++ lines with nonsense paths so patch can't find leave_unchanged. Then it works fine. It's such an ugly solution though.
$ 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
Edit
I noticed that Mercurial avoids this problem by pre-pending "a" and "b" directories.
$ 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
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我相信这里的答案是在父目录中执行差异。然后使用 patch -p1 删除第一段。我相信这就是为什么 patch 的 strip 选项实际上默认为 1 而不是 0。例如,使用上面的示例与
您的示例的唯一区别是我已经从父目录执行了 diff,以便被比较的目录是处于同一水平。
I believe the answer here is to execute your diff at the parent directory. Then use patch -p1 to strip this first segment. I believe this is why the strip option of patch actually defaults to 1 rather than 0. E.g. to use your example from above
The only difference from your example is that I've executed the diff from the parent directory so that the directories being compared are at the same level.