How to make svn diff produce file that patch would

2019-01-10 05:49发布

问题:

The scenario is:

  1. svn cp or mv some file
  2. modify that file
  3. svn diff > mypatch

On other machine (same working copy, but no changes):

  1. Try to apply mypatch.
  2. Fail -> tries to modify unexistant file.

How can I make svn diff produce patch-appliable patch, or cleanly apply patch produced by svn diff in this case? I can't commit. I would like to preserve mergeinfo (because the obvious workaround is to add the file as totally new, without connection to the previous one).

回答1:

With subversion, you can specify which diff binary to use, and parameters to pass to it. See the manual on svn diff.

You'd want to produce a regular patch file from a svn diff, so you'd want the svn diff to look like a normal diff. Try this:

svn diff --diff-cmd /usr/bin/diff -x "-i -b" > mypatch
...
patch -p0 < mypatch

Proof of concept:

echo "newline" >> README.txt
svn diff --diff-cmd /usr/bin/diff -x "-i -b" > mypatch
cp README.txt README.txt.patched
svn revert README.txt
patch -p0 < mypatch
diff README.txt README.txt.patched

No difference in the two files after patching.



回答2:

If you want to get rid of the svn properties as well in your patches, there is an option for that:

svn diff --patch-compatible > mypatch.diff

svn help diff says:

  --patch-compatible   : generate diff suitable for generic third-party
                         patch tools; currently the same as
                         --show-copies-as-adds --ignore-properties

Patches created this way are supposed to be compatible with the good old plain patch utility.



回答3:

Have you tried the --show-copies-as-adds option mentioned on the svn diff web page and described on the svn options page?.



回答4:

Without understanding the specific scenario you're trying to work upon its hard to identify why you'd want to do this. I get the feeling you're trying to make controlled changes in an isolated environment so to avoid impacting other users/applications.

Could you solve this problem by;

  • Create a branch for your code change
  • Perform your copy/move and changes on the branch
  • Get the other party to switch to this new code branch and carry on sharing this branch

When you've both agreed with the changes merge back into trunk using the --reintegrate argument and rm the branch?

This would * Maintain merge-info * Identify the copy/move and changes in version control * Still isolate changes from other users * Would prevent incomplete changes during step 2 being an issue as you could just add more changes and update