Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix diff parsing to support mnemonicPrefix configuration#2092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
MirrorDNA-Reflection-Protocol wants to merge3 commits intogitpython-developers:main
base:main
Choose a base branch
Loading
fromMirrorDNA-Reflection-Protocol:fix-mnemonic-prefix-diff
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletionsgit/diff.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -113,7 +113,10 @@ def decode_path(path: bytes, has_ab_prefix: bool = True) -> Optional[bytes]:
path = _octal_byte_re.sub(_octal_repl, path)

if has_ab_prefix:
assert path.startswith(b"a/") or path.startswith(b"b/")
# Support standard (a/b) and mnemonicPrefix (c/w/i/o/h) prefixes
# See git-config diff.mnemonicPrefix documentation
valid_prefixes = (b"a/", b"b/", b"c/", b"w/", b"i/", b"o/", b"h/")
assert any(path.startswith(p) for p in valid_prefixes), f"Unexpected path prefix: {path[:10]!r}"
path = path[2:]

return path
Expand DownExpand Up@@ -367,10 +370,12 @@ class Diff:
"""

# Precompiled regex.
# Note: The path prefixes support both default (a/b) and mnemonicPrefix mode
# which can use prefixes like c/ (commit), w/ (worktree), i/ (index), o/ (object), and h/ (HEAD)
re_header = re.compile(
rb"""
^diff[ ]--git
[ ](?P<a_path_fallback>"?[ab]/.+?"?)[ ](?P<b_path_fallback>"?[ab]/.+?"?)\n
[ ](?P<a_path_fallback>"?[abciwoh]/.+?"?)[ ](?P<b_path_fallback>"?[abciwoh]/.+?"?)\n
(?:^old[ ]mode[ ](?P<old_mode>\d+)\n
^new[ ]mode[ ](?P<new_mode>\d+)(?:\n|$))?
(?:^similarity[ ]index[ ]\d+%\n
Expand Down
46 changes: 46 additions & 0 deletionstest/test_diff.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -281,6 +281,52 @@ def test_diff_unsafe_paths(self):
self.assertEqual(res[13].a_path, 'a/"with-quotes"')
self.assertEqual(res[13].b_path, 'b/"with even more quotes"')

def test_diff_mnemonic_prefix(self):
"""Test that diff parsing works with mnemonicPrefix enabled.

When diff.mnemonicPrefix=true is set in git config, git uses different
prefixes for diff paths:
- c/ for commit
- w/ for worktree
- i/ for index
- o/ for object
Copy link

CopilotAIDec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

The docstring is missing theh/ prefix for HEAD. According to the PR description and Git documentation,h/ is also a valid mnemonicPrefix. The comment should list all supported prefixes: c/ (commit), w/ (worktree), i/ (index), o/ (object), and h/ (HEAD).

Suggested change
-o/forobject
-o/forobject
-h/forHEAD

Copilot uses AI. Check for mistakes.
- h/ for HEAD

This addresses issue #2013 where the regex only matched [ab]/ prefixes.
"""
# Test all mnemonicPrefix combinations
# Each tuple is (a_prefix, b_prefix) representing different comparison types
prefix_pairs = [
(b"c/", b"w/"), # commit vs worktree
(b"c/", b"i/"), # commit vs index
(b"i/", b"w/"), # index vs worktree
(b"o/", b"w/"), # object vs worktree
(b"h/", b"i/"), # HEAD vs index
(b"h/", b"w/"), # HEAD vs worktree
]

for a_prefix, b_prefix in prefix_pairs:
with self.subTest(a_prefix=a_prefix, b_prefix=b_prefix):
diff_mnemonic = (
b"diff --git " + a_prefix + b".vscode/launch.json " + b_prefix + b".vscode/launch.json\n"
b"index 1234567890abcdef1234567890abcdef12345678.."
b"abcdef1234567890abcdef1234567890abcdef12 100644\n"
b"--- " + a_prefix + b".vscode/launch.json\n"
b"+++ " + b_prefix + b".vscode/launch.json\n"
b"@@ -1,3 +1,3 @@\n"
b"-old content\n"
b"+new content\n"
)
diff_proc = StringProcessAdapter(diff_mnemonic)
diffs = Diff._index_from_patch_format(self.rorepo, diff_proc)

# Should parse successfully (previously would fail or return empty)
self.assertEqual(len(diffs), 1)
diff = diffs[0]
# The path should be extracted correctly (without the prefix)
self.assertEqual(diff.a_path, ".vscode/launch.json")
self.assertEqual(diff.b_path, ".vscode/launch.json")

def test_diff_patch_format(self):
# Test all of the 'old' format diffs for completeness - it should at least be
# able to deal with it.
Expand Down
Loading

[8]ページ先頭

©2009-2026 Movatter.jp