git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
DSDaniel Sommermann <dcsommer@gmail.com>
Date
Mar 24, 2020, 16:00 UTC
Message-ID
<20200324160054.1535824-1-dcsommer@gmail.com>

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
Next: Jeff King
Message 1 of 3 in “git-apply: Permit change of file mode when filename does not change”
  1. git-apply: Permit change of file mode when filename does not changeDaniel Sommermann, Mar 24, 2020
  2. Jeff KingMar 25, 2020
  3. Junio C HamanoMar 25, 2020

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.