diff options
author | Andreas Gruenbacher <agruen@linbit.com> | 2012-08-02 15:50:49 +0200 |
---|---|---|
committer | Andreas Gruenbacher <agruen@linbit.com> | 2012-08-02 20:38:31 +0200 |
commit | 1e6c0d07abe8833bbb3bc493ed0f969b84d7bf25 (patch) | |
tree | b2b7219e2e4d1803d16fbde8d348e56aecd557d0 | |
parent | cdc94fade38f2b745894c7b724512af506dc803c (diff) | |
download | patch-1e6c0d07abe8833bbb3bc493ed0f969b84d7bf25.tar.gz |
In git-style diffs, create new files immediatetly and only remember files to modify
* src/patch.c (output_file): Create new files immediately. Document why
things are implemented that way.
* tests/concat-git-diff: Fix glitch in test case.
-rw-r--r-- | src/patch.c | 28 | ||||
-rw-r--r-- | tests/concat-git-diff | 1 |
2 files changed, 26 insertions, 3 deletions
diff --git a/src/patch.c b/src/patch.c index 2d6443a..082127b 100644 --- a/src/patch.c +++ b/src/patch.c @@ -1786,9 +1786,31 @@ output_file (char const *from, int *from_needs_removal, const struct stat *to_st, mode_t mode, bool backup) { if (from == NULL) - delete_file_later (to, to_st, backup); - else if (pch_git_diff()) - output_file_later (from, from_needs_removal, from_st, to, mode, backup); + { + /* Remember which files should be deleted and only delete them when the + entire input to patch has been processed. This allows to correctly + determine for which files backup files have already been created. */ + + delete_file_later (to, to_st, backup); + } + else if (pch_git_diff () && pch_says_nonexistent (reverse) != 2) + { + /* In git-style diffs, the "before" state of each patch refers to the initial + state before modifying any files, input files can be referenced more than + once (when creating copies), and output files are modified at most once. + However, the input to GNU patch may consist of multiple concatenated + git-style diffs, which must be processed separately. (The same output + file may go through multiple revisions.) + + To implement this, we remember which files to /modify/ instead of + modifying the files immediately, but we create /new/ output files + immediately. The new output files serve as markers to detect when a + file is modified more than once; this allows to recognize most + concatenated git-style diffs. + */ + + output_file_later (from, from_needs_removal, from_st, to, mode, backup); + } else output_file_now (from, from_needs_removal, from_st, to, mode, backup); } diff --git a/tests/concat-git-diff b/tests/concat-git-diff index a6f1539..445fd97 100644 --- a/tests/concat-git-diff +++ b/tests/concat-git-diff @@ -39,6 +39,7 @@ EOF check 'patch -p1 < concatenated.diff || echo "Status: $?"' <<EOF patching file f patching file f +patching file f EOF check 'cat f' <<EOF |