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

[PATCH v3 4/7] patch-id: fix patch-id for mode changes

From
Jerry Zhang via GitGitGadget <gitgitgadget@gmail.com>
Date
Oct 14, 2022, 08:56 UTC
Message-ID
<6e07cfd56917db16a281e06118cce312eb39a488.1665737804.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1359.v3.git.1665737804.gitgitgadget@gmail.com>
From: Jerry Zhang <Jerry@skydio.com>

Currently patch-id as used in rebase and cherry-pick does not account for file modes if the file is modified. One consequence of this is that if you have a local patch that changes modes, but upstream has applied an outdated version of the patch that doesn't include that mode change, "git rebase" will drop your local version of the patch along with your mode changes. It also means that internal patch-id doesn't produce the same output as the builtin, which does account for mode changes due to them being part of diff output.

Fix by adding mode to the patch-id if it has changed, in the same format that would be produced by diff, so that it is compatible with builtin patch-id.

Signed-off-by: Jerry Zhang <Jerry@skydio.com>
---
 diff.c                     |  5 +++++
 t/t3419-rebase-patch-id.sh | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)
diff --git a/diff.c b/diff.c
index 199b63dbcc3..0e336c48560 100644
--- a/diff.c
+++ b/diff.c
@@ -6256,6 +6256,11 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
 		} else if (p->two->mode == 0) {
 			patch_id_add_string(&ctx, "deletedfilemode");
 			patch_id_add_mode(&ctx, p->one->mode);
+		} else if (p->one->mode != p->two->mode) {
+			patch_id_add_string(&ctx, "oldmode");
+			patch_id_add_mode(&ctx, p->one->mode);
+			patch_id_add_string(&ctx, "newmode");
+			patch_id_add_mode(&ctx, p->two->mode);
 		}
 
 		if (diff_header_only) {
diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh
index d24e55aac8d..7181f176b81 100755
--- a/t/t3419-rebase-patch-id.sh
+++ b/t/t3419-rebase-patch-id.sh
@@ -48,7 +48,17 @@ test_expect_success 'setup: 500 lines' '
 	git branch -f squashed main &&
 	git checkout -q -f squashed &&
 	git reset -q --soft HEAD~2 &&
-	git commit -q -m squashed
+	git commit -q -m squashed &&
+
+	git branch -f mode main &&
+	git checkout -q -f mode &&
+	test_chmod +x file &&
+	git commit -q -a --amend &&
+
+	git branch -f modeother other &&
+	git checkout -q -f modeother &&
+	test_chmod +x file &&
+	git commit -q -a --amend
 '
 
 test_expect_success 'detect upstream patch' '
@@ -71,6 +81,13 @@ test_expect_success 'detect upstream patch binary' '
 	test_when_finished "rm .gitattributes"
 '
 
+test_expect_success 'detect upstream patch modechange' '
+	git checkout -q modeother^{} &&
+	git rebase mode &&
+	git rev-list mode...HEAD~ >revs &&
+	test_must_be_empty revs
+'
+
 test_expect_success 'do not drop patch' '
 	git checkout -q other^{} &&
 	test_must_fail git rebase squashed &&
@@ -85,4 +102,16 @@ test_expect_success 'do not drop patch binary' '
 	test_when_finished "rm .gitattributes"
 '
 
+test_expect_success 'do not drop patch modechange' '
+	git checkout -q modeother^{} &&
+	git rebase other &&
+	cat >expected <<-\EOF &&
+	diff --git a/file b/file
+	old mode 100644
+	new mode 100755
+	EOF
+	git diff HEAD~ >modediff &&
+	test_cmp expected modediff
+'
+
 test_done
-- 
gitgitgadget
Previous: Junio C HamanoNext: Junio C Hamano
Message 20 of 46 in “update internal patch-id to use "stable" algorithm”
  1. 0/2 update internal patch-id to use "stable" algorithmJerry Zhang via GitGitGadget, Sep 20, 2022
  2. 2/2 patch-id: use stable patch-id for rebasesJerry Zhang via GitGitGadget, Sep 20, 2022
  3. 1/2 patch-id: fix stable patch id for binary / header-onlyJerry Zhang via GitGitGadget, Sep 20, 2022
  4. 0/2 update internal patch-id to use "stable" algorithmJerry Zhang via GitGitGadget, Sep 20, 2022
  5. 1/2 patch-id: fix stable patch id for binary / header-onlyJerry Zhang via GitGitGadget, Sep 20, 2022
  6. 2/2 patch-id: use stable patch-id for rebasesJerry Zhang via GitGitGadget, Sep 20, 2022
  7. 0/7 patch-id fixes and improvementsJerry Zhang via GitGitGadget, Oct 14, 2022
  8. 1/7 patch-id: fix stable patch id for binary / header-onlyJerry Zhang via GitGitGadget, Oct 14, 2022
  9. 2/7 patch-id: use stable patch-id for rebasesJerry Zhang via GitGitGadget, Oct 14, 2022
  10. 3/7 builtin: patch-id: fix patch-id with binary diffsJerry Zhang via GitGitGadget, Oct 14, 2022
  11. Junio C HamanoOct 14, 2022
  12. Jerry ZhangOct 14, 2022
  13. Junio C HamanoOct 14, 2022
  14. Jerry ZhangOct 14, 2022
  15. Junio C HamanoOct 17, 2022
  16. 7/7 documentation: format-patch: clarify requirements for patch-ids to matchJerry Zhang via GitGitGadget, Oct 14, 2022
  17. Junio C HamanoOct 17, 2022
  18. Jerry ZhangOct 18, 2022
  19. Junio C HamanoOct 19, 2022
  20. 4/7 patch-id: fix patch-id for mode changesJerry Zhang via GitGitGadget, Oct 14, 2022
  21. Junio C HamanoOct 14, 2022
  22. 6/7 builtin: patch-id: remove unused diff-tree prefixJerry Zhang via GitGitGadget, Oct 14, 2022
  23. Junio C HamanoOct 14, 2022
  24. 5/7 builtin: patch-id: add --include-whitespace as a command modeJerry Zhang via GitGitGadget, Oct 14, 2022
  25. Junio C HamanoOct 14, 2022
  26. Jerry ZhangOct 14, 2022
  27. Junio C HamanoOct 17, 2022
  28. Jerry ZhangOct 18, 2022
  29. 0/6 patch-id fixes and improvementsJerry Zhang via GitGitGadget, Oct 20, 2022
  30. 1/6 patch-id: fix stable patch id for binary / header-onlyJerry Zhang via GitGitGadget, Oct 20, 2022
  31. 2/6 patch-id: use stable patch-id for rebasesJerry Zhang via GitGitGadget, Oct 20, 2022
  32. 3/6 builtin: patch-id: fix patch-id with binary diffsJerry Zhang via GitGitGadget, Oct 20, 2022
  33. 4/6 patch-id: fix patch-id for mode changesJerry Zhang via GitGitGadget, Oct 20, 2022
  34. 5/6 builtin: patch-id: add --verbatim as a command modeJerry Zhang via GitGitGadget, Oct 20, 2022
  35. 6/6 builtin: patch-id: remove unused diff-tree prefixJerry Zhang via GitGitGadget, Oct 20, 2022
  36. Junio C HamanoOct 21, 2022
  37. 0/6 patch-id fixes and improvementsJerry Zhang via GitGitGadget, Oct 24, 2022
  38. 4/6 patch-id: fix patch-id for mode changesJerry Zhang via GitGitGadget, Oct 24, 2022
  39. 5/6 builtin: patch-id: add --verbatim as a command modeJerry Zhang via GitGitGadget, Oct 24, 2022
  40. 1/6 patch-id: fix stable patch id for binary / header-onlyJerry Zhang via GitGitGadget, Oct 24, 2022
  41. 2/6 patch-id: use stable patch-id for rebasesJerry Zhang via GitGitGadget, Oct 24, 2022
  42. 3/6 builtin: patch-id: fix patch-id with binary diffsJerry Zhang via GitGitGadget, Oct 24, 2022
  43. 6/6 builtin: patch-id: remove unused diff-tree prefixJerry Zhang via GitGitGadget, Oct 24, 2022
  44. Junio C HamanoOct 24, 2022
  45. Junio C HamanoSep 21, 2022
  46. Jerry ZhangSep 21, 2022

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.