Bug 12023 - svn-create-patch and friends should handle moved/copied files
Summary: svn-create-patch and friends should handle moved/copied files
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Tools / Tests (show other bugs)
Version: 420+
Hardware: Mac OS X 10.4
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks: 14590
  Show dependency treegraph
 
Reported: 2006-12-28 19:06 PST by David Kilzer (:ddkilzer)
Modified: 2018-09-03 04:33 PDT (History)
1 user (show)

See Also:


Attachments
First pass at changes to svn-create-patch (6.13 KB, patch)
2006-12-28 19:09 PST, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v2 (12.59 KB, patch)
2006-12-31 21:08 PST, David Kilzer (:ddkilzer)
no flags Details | Formatted Diff | Diff
Patch v3 (12.44 KB, patch)
2007-01-01 17:59 PST, David Kilzer (:ddkilzer)
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description David Kilzer (:ddkilzer) 2006-12-28 19:06:33 PST
When creating (svn-create-patch), applying (svn-apply) and unapplying (svn-unapply) patches, moved and copied files should be handled properly on working copies (trees) other than the one they were originally created in.

Note that in svn, a "move" is the same thing as "copy" then "delete", so as long as you handle a "copy" (before "delete"), you solve both "move" and "copy".

The other challenge is a "move" or "copy" followed by changes to the file after the change.  The best solution here is to separate the "copy" from the changes, since combining them could cause changes to be lost if only the whole version from the patch is applied.  This means that a moved/copied file with changes will be split up into two patches within a diff, but as long as they appear in the correct order, the end result is the same.
Comment 1 David Kilzer (:ddkilzer) 2006-12-28 19:09:47 PST
Created attachment 12097 [details]
First pass at changes to svn-create-patch

This is a first pass at changes to svn-create-patch to make it work with moved/copied files.  The only thing left out is property changes for the moved/changed files.

We also need changes to svn-apply and svn-unapply to handle the (subtle) changes in the patches created.
Comment 2 David Kilzer (:ddkilzer) 2006-12-30 08:21:27 PST
(In reply to comment #1)
> Created an attachment (id=12097) [edit]
> First pass at changes to svn-create-patch
> 
> This is a first pass at changes to svn-create-patch to make it work with
> moved/copied files.  The only thing left out is property changes for the
> moved/changed files.
> 
> We also need changes to svn-apply and svn-unapply to handle the (subtle)
> changes in the patches created.

Hmm...this patch also doesn't include removed files in the diff!

Comment 3 David Kilzer (:ddkilzer) 2006-12-31 21:08:20 PST
Created attachment 12139 [details]
Patch v2

This patch includes changes for svn-apply and svn-unapply, and fixes the issue of missing removed file patches mentioned in Comment #2.

Theory of operation:

In subversion, a moved (or renamed) file is identical to a copy and a delete, so the modified patch only needs to identify the special case when an added file was copied from an existing file.

The subtle difference introduced to identify copied files is a modified "from" line (the patch line that starts with "--- ") that references the original path and revision number instead of the new path.

Thus an svn copy will generate up to two patches:  one for the copy and one for any changes made after the copy.  An svn move (or svn rename) will generate up to three patches:  one for the delete, one for the copy, and one for any post-copy changes.

Compatibility issues with plain old patch(1):

- In POSIX mode, patch(1) determines the file name to patch by checking for the existence of the first path in this list:  old ("--- " line), new ("+++ " line) and index ("Index: " line).  Because svn-create-patch now modifies the old line to point to the original file, patch(1) wants to patch the wrong file (and ends up doing nothing because that file already exists).  In "normal" mode (-n), patch(1) completely ignores a patch formatted this way.

- If changes are made after a file is copied or moved, svn-create-patch will create two patches:  one to represent the copy and one to represent post-copy changes.  When using patch(1) to reverse the change, these patches must be applied in the reverse order as well (although I don't think patch(1) applies the patches in a file in reverse order).  Assuming the previous issue was resolved, this issue would still remain.
Comment 4 David Kilzer (:ddkilzer) 2006-12-31 21:14:53 PST
After typing up Comment #3, I've almost convinced myself that I need another way to add a hint to the patch to describe copied files.  This is what svn-create-patch from Patch v2 will generate (from Bug 12036):

Index: JavaScriptCore/pcre/pcre_printint.src
===================================================================
--- JavaScriptCore/pcre/pcre_printint.c (revision 18482)
+++ JavaScriptCore/pcre/pcre_printint.src       (working copy)

Perhaps a better approach would be to add another set of parenthesis on the "old" line describing the original source like this (will probably wrap poorly):

Index: JavaScriptCore/pcre/pcre_printint.src
===================================================================
--- JavaScriptCore/pcre/pcre_printint.src (revision 18482) (JavaScriptCore/pcre/pcre_printint.c@18482)
+++ JavaScriptCore/pcre/pcre_printint.src       (working copy)

I need to do some testing, but that may be more acceptable to patch(1) than changing the "old" line.

Comments?

Comment 5 David Kilzer (:ddkilzer) 2007-01-01 04:28:45 PST
Another possible format would be to mimic what "svn log -v" does with copied files:

Index: JavaScriptCore/pcre/pcre_printint.src
===================================================================
--- JavaScriptCore/pcre/pcre_printint.src (revision 18482) (from JavaScriptCore/pcre/pcre_printint.c:18482)
+++ JavaScriptCore/pcre/pcre_printint.src       (working copy)

Comment 6 David Kilzer (:ddkilzer) 2007-01-01 17:59:47 PST
Created attachment 12152 [details]
Patch v3

Implement format from Comment #5.  This addresses the first issue in Comment #3.  (The second issue still exists since we don't want any changes to the copied file to be lost if the originally copied file changes between the time the patch is made and the time it is applied.)
Comment 7 Darin Adler 2007-01-01 19:35:25 PST
Comment on attachment 12152 [details]
Patch v3

Looks great! r=me
Comment 8 David Kilzer (:ddkilzer) 2007-01-01 20:29:24 PST
Committed revision 18513.