summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Gruenbacher <agruen@suse.de>2010-04-29 15:48:57 +0200
committerAndreas Gruenbacher <agruen@suse.de>2010-05-02 11:44:03 +0200
commit9e39d9c9950076e319d1dbbeeb7b8bd268b465f3 (patch)
treeab56377de82e2d484cc093023ce89077e0ea7526
parent502d77b81b692ec1f3e03c2cce621df85cf110f2 (diff)
downloadpatch-9e39d9c9950076e319d1dbbeeb7b8bd268b465f3.tar.gz
git diffs: Support file copies and renames
* src/patch.c (main): Support git diffs which copy or rename files. * tests/copy-rename: New test case. * tests/Makefile.am (TESTS): Add test case.
-rw-r--r--ChangeLog4
-rw-r--r--src/patch.c19
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/copy-rename135
4 files changed, 157 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index fff4368..5b709bc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2009-04-29 Andreas Gruenbacher <agruen@suse.de>
+ * src/patch.c (main): Support git diffs which copy or rename files.
+ * tests/copy-rename: New test case.
+ * tests/Makefile.am (TESTS): Add test case.
+
* src/patch.c (main): Convert outname into a char const *.
* src/util.ch (create_backup, move_file, removedirs): Take char const *
filenames.
diff --git a/src/patch.c b/src/patch.c
index 74c7767..be76f68 100644
--- a/src/patch.c
+++ b/src/patch.c
@@ -194,7 +194,13 @@ main (int argc, char **argv)
if (! skip_rest_of_patch)
{
- outname = outfile ? outfile : inname;
+ if (outfile)
+ outname = outfile;
+ else if (pch_copy () || pch_rename ())
+ outname = pch_name (! strcmp (inname, pch_name (OLD)));
+ else
+ outname = inname;
+
if (! get_input_file (inname, outname, file_type))
{
skip_rest_of_patch = true;
@@ -411,7 +417,8 @@ main (int argc, char **argv)
bool set_mode = new_mode && old_mode != new_mode;
/* Avoid replacing files when nothing has changed. */
- if (failed < hunk || diff_type == ED_DIFF || set_mode)
+ if (failed < hunk || diff_type == ED_DIFF || set_mode
+ || pch_copy () || pch_rename ())
{
enum file_attributes attr = FA_IDS | FA_MODE;
struct timespec new_time = pch_timestamp (! reverse);
@@ -443,6 +450,14 @@ main (int argc, char **argv)
if (! inerrno)
set_file_attributes (outname, attr, &instat, mode, &new_time);
+
+ if (pch_rename ())
+ {
+ if (backup)
+ create_backup (inname, 0, 0, false);
+ else if (unlink (inname))
+ pfatal ("Can't remove file %s", quotearg (inname));
+ }
}
else if (backup)
create_backup (outname, 0, 0, true);
diff --git a/tests/Makefile.am b/tests/Makefile.am
index af30156..3498cc1 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -19,6 +19,7 @@
TESTS = \
asymmetric-hunks \
backup-prefix-suffix \
+ copy-rename \
corrupt-reject-files \
create-delete \
crlf-handling \
diff --git a/tests/copy-rename b/tests/copy-rename
new file mode 100644
index 0000000..a875ae6
--- /dev/null
+++ b/tests/copy-rename
@@ -0,0 +1,135 @@
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# Copying and distribution of this file, with or without modification,
+# in any medium, are permitted without royalty provided the copyright
+# notice and this notice are preserved.
+
+# git diffs: copy and rename tests
+
+. $srcdir/test-lib.sh
+
+require_cat
+require_diff
+use_local_patch
+use_tmpdir
+
+# ==============================================================
+# Normal copy and rename patches
+
+echo old > f
+
+cat > copy.diff <<EOF
+diff --git a/f b/g
+copy from f
+copy to g
+--- a/f
++++ b/g
+@@ -1 +1 @@
+-old
++new
+EOF
+
+# FIXME: the message is confusing ...
+check 'patch -p1 < copy.diff || echo "Status: $?"' <<EOF
+patching file f
+EOF
+
+check 'cat f' <<EOF
+old
+EOF
+
+check 'cat g' <<EOF
+new
+EOF
+
+cat > rename.diff <<EOF
+diff --git a/f b/h
+rename from f
+rename to h
+--- a/f
++++ b/h
+@@ -1 +1 @@
+-old
++new
+EOF
+
+# FIXME: the message is confusing ...
+check 'patch -p1 < rename.diff || echo "Status: $?"' <<EOF
+patching file f
+EOF
+
+ncheck 'test ! -e f'
+
+check 'cat h' <<EOF
+new
+EOF
+
+# --------------------------------------------------------------
+# Patches with no hunks
+
+echo old > f
+rm -f g h
+
+cat > copy.diff <<EOF
+diff --git a/f a/g
+copy from f
+copy to g
+EOF
+
+# FIXME: the message is confusing ...
+check 'patch -p1 < copy.diff || echo "Status: $?"' <<EOF
+patching file f
+EOF
+
+check 'cat f' <<EOF
+old
+EOF
+
+check 'cat g' <<EOF
+old
+EOF
+
+cat > rename.diff <<EOF
+diff --git a/f a/h
+rename from f
+rename to h
+EOF
+
+# FIXME: the message is confusing ...
+check 'patch -p1 < rename.diff || echo "Status: $?"' <<EOF
+patching file f
+EOF
+
+ncheck 'test ! -e f'
+
+check 'cat h' <<EOF
+old
+EOF
+
+# --------------------------------------------------------------
+# Backup file tests
+
+echo old > f
+rm -f g h
+
+# FIXME: the message is confusing ...
+check 'patch -p1 --backup < copy.diff || echo "Status: $?"' <<EOF
+patching file f
+EOF
+
+ncheck 'test ! -e f.orig'
+
+ncheck 'cat g.orig'
+
+rm -f f.orig g.orig
+
+# FIXME: the message is confusing ...
+check 'patch -p1 --backup < rename.diff || echo "Status: $?"' <<EOF
+patching file f
+EOF
+
+check 'cat f.orig' <<EOF
+old
+EOF
+
+ncheck 'cat h.orig'