diff --git a/quilt.changes b/quilt.changes index 7063c49..a35d82f 100644 --- a/quilt.changes +++ b/quilt.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Wed Jul 29 14:25:16 CEST 2009 - jdelvare@suse.de + +- Fix data loss by quilt revert in some cases. + ------------------------------------------------------------------- Tue Jun 30 11:01:50 CEST 2009 - jdelvare@suse.de diff --git a/quilt.spec b/quilt.spec index ed8c0ae..e3b150f 100644 --- a/quilt.spec +++ b/quilt.spec @@ -24,7 +24,7 @@ Summary: A Tool for Working with Many Patches License: GPL v2 or later Group: Productivity/Text/Utilities Version: 0.48 -Release: 1 +Release: 2 Requires: coreutils diffutils patch gzip bzip2 perl mktemp diffstat %if %{suse_version} > 910 Recommends: procmail @@ -38,6 +38,7 @@ Patch3: patch-wrapper-rpm.diff Patch4: fix-test-create-delete.diff Patch5: hide-git-desc-error.diff Patch6: mail-dont-use-equal-tilde.diff +Patch7: revert-should-not-hard-link.diff Url: http://savannah.nongnu.org/projects/quilt BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -57,7 +58,7 @@ Authors: %prep %setup -q -%patch -p1 -P 1 -P 2 -P 3 -P 4 -P 5 -P 6 +%patch -p1 -P 1 -P 2 -P 3 -P 4 -P 5 -P 6 -P 7 %build autoconf diff --git a/revert-should-not-hard-link.diff b/revert-should-not-hard-link.diff new file mode 100644 index 0000000..1a03beb --- /dev/null +++ b/revert-should-not-hard-link.diff @@ -0,0 +1,74 @@ +From: Jean Delvare +References: http://savannah.nongnu.org/bugs/index.php?25305 + +"quilt revert" accidentally creates a hard link, it shouldn't do that. + +I think the reason is that apply_patch_temporarily() uses backup-files +to create the temporary files, and by default backup-files uses hard +links. For files which are modified by the patch, this isn't a problem +because patch will unlink the file before modifying it. But for files +which are not modified by the patch, the hard link is preserved. + +Then quilt revert also makes a hard link to restore the file, on the +assumption that the temporary copy will be deleted right away. At +this point, files not modified by the patch will have a link count +of 3 (.pc//, d.*/ and ). When the temporary +file is deleted, the link count is still 2 (.pc// and +). + +A simple way to fix this is to always use cp instead of ln when +restoring the files. Performance is not as good, but at least it is +always correct. We could optimize the code to use ln when possible +and cp for the other cases, but honestly I don't think it is worth +the extra complexity. The speed of "quilt revert" is hardly +critical, given how infrequently this command is used. +--- + quilt/revert.in | 1 - + test/nolink.test | 20 ++++++++++++++++++++ + 2 files changed, 20 insertions(+), 1 deletion(-) + +--- quilt-git.orig/test/nolink.test 2009-06-11 08:41:42.000000000 +0200 ++++ quilt-git/test/nolink.test 2009-06-11 09:46:24.000000000 +0200 +@@ -2,6 +2,7 @@ + $ mkdir -p d/patches + $ cd d + ++# quilt should preserve hard links and not create new ones + $ echo foo > foo + $ ln foo foo2 + $ ls -l foo | awk '{ print $2 }' +@@ -53,5 +54,24 @@ + $ ls -l foo | awk '{ print $2 }' + > 2 + ++# quilt revert should not create hard links ++ $ echo bar > bar ++ $ quilt push -q ++ > Applying patch patches/test.diff ++ > Now at patch patches/test.diff ++ ++ $ quilt add bar ++ > File bar added to patch patches/test.diff ++ $ echo "bar changed" > bar ++ $ quilt revert bar ++ > Changes to bar in patch patches/test.diff reverted ++ ++ $ ls -l bar | awk '{ print $2 }' ++ > 1 ++ ++ $ quilt pop -q ++ > Removing patch patches/test.diff ++ > No patches applied ++ + $ cd .. + $ rm -rf d +--- quilt-git.orig/quilt/revert.in 2009-06-11 09:05:27.000000000 +0200 ++++ quilt-git/quilt/revert.in 2009-06-11 09:05:44.000000000 +0200 +@@ -104,7 +104,6 @@ do + fi + + mkdir -p "$(dirname "$file")" +- ln -f "$workdir/$file" "$file" 2>&1 || + cp -p "$workdir/$file" "$file" + else + if [ ! -e "$file" ]