diff --git a/git/diff.py b/git/diff.py index aba1a108..e5db4a8f 100644 --- a/git/diff.py +++ b/git/diff.py @@ -8,6 +8,7 @@ import re from git.cmd import handle_process_output from git.compat import defenc from git.util import finalize_process, hex_to_bin +from git.exc import GitCommandError from .objects.blob import Blob from .objects.util import mode_str_to_int @@ -154,6 +155,10 @@ class Diffable: args.append("-M") if create_patch: + # When creating patches, we need to bypass external diff settings + # as external diff tools don't produce the unified diff format we can parse + args.append("-c") + args.append("diff.external=") # Override to empty string to disable external diff args.append("-p") else: args.append("--raw") diff --git a/reproduce_issue.py b/reproduce_issue.py new file mode 100644 index 00000000..1b459e77 --- /dev/null +++ b/reproduce_issue.py @@ -0,0 +1,75 @@ +from git import Repo +import tempfile +import os + +# Create a temporary repo +repo_dir = tempfile.mkdtemp() +print(f"Using repo dir: {repo_dir}") +os.chdir(repo_dir) + +# Initialize repo +repo = Repo.init(repo_dir) + +# Create a test file +test_file = os.path.join(repo_dir, "test.txt") +with open(test_file, "w") as f: + f.write("hello world\n") + +# Add and commit +repo.git.add(test_file) +repo.index.commit("initial commit") + +# Modify the file +with open(test_file, "w") as f: + f.write("hello world\nmodified line\n") + +print("Without create_patch:") +print(repo.index.diff("HEAD")) +print(repo.index.diff(None)) + +print("\nWith create_patch:") +print("HEAD vs HEAD^:", repo.head.commit.diff("HEAD^", create_patch=True)) # tree vs tree +print("index vs HEAD:", repo.index.diff("HEAD", create_patch=True)) # index vs tree +print("index vs working:", repo.index.diff(None, create_patch=True)) # index vs working tree +print("working tree vs HEAD:", repo.head.commit.diff(None, create_patch=True)) # working tree vs tree + +# Set external diff +with repo.config_writer(config_level="repository") as writer: + writer.set_value("diff", "external", "bogus_diff_engine") + +print("\n=== WITH EXTERNAL DIFF ===") +print("Without create_patch:") +try: + print("HEAD vs HEAD^:", repo.head.commit.diff("HEAD^")) # tree vs tree +except Exception as e: + print("HEAD vs HEAD^: ERROR -", e) +try: + print("index vs HEAD:", repo.index.diff("HEAD")) # index vs tree +except Exception as e: + print("index vs HEAD: ERROR -", e) +try: + print("index vs working:", repo.index.diff(None)) # index vs working tree +except Exception as e: + print("index vs working: ERROR -", e) +try: + print("working tree vs HEAD:", repo.head.commit.diff(None)) # working tree vs tree +except Exception as e: + print("working tree vs HEAD: ERROR -", e) + +print("\nWith create_patch:") +try: + print("HEAD vs HEAD^:", repo.head.commit.diff("HEAD^", create_patch=True)) # tree vs tree +except Exception as e: + print("HEAD vs HEAD^: ERROR -", e) +try: + print("index vs HEAD:", repo.index.diff("HEAD", create_patch=True)) # index vs tree +except Exception as e: + print("index vs HEAD: ERROR -", e) +try: + print("index vs working:", repo.index.diff(None, create_patch=True)) # index vs working tree +except Exception as e: + print("index vs working: ERROR -", e) +try: + print("working tree vs HEAD:", repo.head.commit.diff(None, create_patch=True)) # working tree vs tree +except Exception as e: + print("working tree vs HEAD: ERROR -", e) \ No newline at end of file