[RFC PATCH] git-apply: Permit change of file mode when filename does not change

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The documentation for git's diff format does not expressly disallow
changing the mode of a file without splitting it into a delete and
create. Mercurial's `hg diff --git` in fact produces git diffs with such
format. When applying such patches in Git, this assert can be hit. The check
preventing this type of diff has been around since 2005 in
3cca928d4aae691572ef9a73dcc29a04f66900a1.

Simply deleting the check that prevents changing the mode when not
renaming allows such diffs to work out of the box, as the attached test
case shows.
---
 apply.c                  | 18 ------------------
 t/t4115-apply-symlink.sh | 23 +++++++++++++++++++++++
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/apply.c b/apply.c
index bdc008fae2..1b9d315771 100644
--- a/apply.c
+++ b/apply.c
@@ -3950,24 +3950,6 @@ static int check_patch(struct apply_state *state, struct patch *patch)
 		}
 	}
 
-	if (new_name && old_name) {
-		int same = !strcmp(old_name, new_name);
-		if (!patch->new_mode)
-			patch->new_mode = patch->old_mode;
-		if ((patch->old_mode ^ patch->new_mode) & S_IFMT) {
-			if (same)
-				return error(_("new mode (%o) of %s does not "
-					       "match old mode (%o)"),
-					patch->new_mode, new_name,
-					patch->old_mode);
-			else
-				return error(_("new mode (%o) of %s does not "
-					       "match old mode (%o) of %s"),
-					patch->new_mode, new_name,
-					patch->old_mode, old_name);
-		}
-	}
-
 	if (!state->unsafe_paths && check_unsafe_path(patch))
 		return -128;
 
diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh
index 872fcda6cb..593e6142b4 100755
--- a/t/t4115-apply-symlink.sh
+++ b/t/t4115-apply-symlink.sh
@@ -44,4 +44,27 @@ test_expect_success 'apply --index symlink patch' '
 
 '
 
+cat >move_patch <<\EOF
+diff --git a/file_to_be_link b/file_to_be_link
+old mode 100644
+new mode 120000
+--- a/file_to_be_link
++++ b/file_to_be_link
+@@ -0,0 +1,1 @@
++target
+\ No newline at end of file
+EOF
+
+test_expect_success 'apply file-to-symlink patch' '
+
+	git checkout -f master &&
+	touch file_to_be_link &&
+	git add file_to_be_link &&
+	git commit -m initial &&
+
+	git apply move_patch &&
+	test target = $(readlink file_to_be_link)
+
+'
+
 test_done
-- 
2.25.1




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux