[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/QuantStack/git2cpp/main/test/test_diff.py [Back]  [Original]

import re
import subprocess

import pytest

from .conftest import strip_ansi_colours


def test_diff_nogit(git2cpp_path, tmp_path):
    cmd = [git2cpp_path, "diff"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode != 0
    assert "repository" in p.stderr.lower() or "not a git" in p.stderr.lower()


def test_diff_working_directory(repo_init_with_commit, git2cpp_path, tmp_path):
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    original_content = initial_file.read_text()
    initial_file.write_text(original_content + "\nNew line added")

    cmd = [git2cpp_path, "diff"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "initial.txt" in p.stdout
    assert "+New line added" in p.stdout


@pytest.mark.parametrize("cached_flag", ["--cached", "--staged"])
def test_diff_cached(repo_init_with_commit, git2cpp_path, tmp_path, cached_flag):
    assert (tmp_path / "initial.txt").exists()

    new_file = tmp_path / "new_file.txt"
    new_file.write_text("Hello, world!")

    cmd_add = [git2cpp_path, "add", "new_file.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_diff = [git2cpp_path, "diff", cached_flag]
    p_diff = subprocess.run(cmd_diff, capture_output=True, cwd=tmp_path, text=True)
    assert p_diff.returncode == 0
    assert "new_file.txt" in p_diff.stdout
    assert "+Hello, world!" in p_diff.stdout


def test_diff_two_commits(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    assert (tmp_path / "initial.txt").exists()

    new_file = tmp_path / "new_file.txt"
    new_file.write_text("Hello, world!")

    cmd_add = [git2cpp_path, "add", "new_file.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "new commit"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    cmd_diff = [git2cpp_path, "diff", "HEAD~1", "HEAD"]
    p_diff = subprocess.run(cmd_diff, capture_output=True, cwd=tmp_path, text=True)
    assert p_diff.returncode == 0
    assert "new_file.txt" in p_diff.stdout
    assert "+Hello, world!" in p_diff.stdout


def test_diff_no_index(git2cpp_path, tmp_path):
    file1 = tmp_path / "file1.txt"
    file2 = tmp_path / "file2.txt"

    file1.write_text("Hello\nWorld\n")
    file2.write_text("Hello\nPython\n")

    cmd = [git2cpp_path, "diff", "--no-index", str(file1), str(file2)]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "-World" in p.stdout
    assert "+Python" in p.stdout


def test_diff_stat(repo_init_with_commit, git2cpp_path, tmp_path):
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    initial_file.write_text("Modified content\n")

    cmd = [git2cpp_path, "diff", "--stat"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0

    p.stdout = strip_ansi_colours(p.stdout)
    assert "initial.txt" in p.stdout
    assert "1 file changed, 1 insertion(+)" in p.stdout
    assert "Modified content" not in p.stdout


def test_diff_shortstat(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with --shortstat (last line of --stat only)"""
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    initial_file.write_text("Modified content\n")

    cmd = [git2cpp_path, "diff", "--shortstat"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "README.md" not in p.stdout
    assert "1 file changed, 1 insertion(+)" in p.stdout
    assert "Modified content" not in p.stdout


def test_diff_numstat(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with --numstat (machine-friendly stat)"""
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    initial_file.write_text("Modified content\n")

    cmd = [git2cpp_path, "diff", "--numstat"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "initial.txt" in p.stdout
    assert bool(re.search("1       [0-9]*", p.stdout))
    assert "Modified content" not in p.stdout


def test_diff_summary(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with --summary"""
    assert (tmp_path / "initial.txt").exists()

    new_file = tmp_path / "newfile.txt"
    new_file.write_text("New content")

    cmd_add = [git2cpp_path, "add", "newfile.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd = [git2cpp_path, "diff", "--cached", "--summary"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    p.stdout = strip_ansi_colours(p.stdout)
    assert "newfile.txt" in p.stdout
    assert "+" not in p.stdout


def test_diff_name_only(repo_init_with_commit, git2cpp_path, tmp_path):
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    initial_file.write_text("Modified")

    cmd = [git2cpp_path, "diff", "--name-only"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)

    assert p.returncode == 0
    p.stdout = strip_ansi_colours(p.stdout)
    assert p.stdout == "initial.txt\n"
    assert "+" not in p.stdout


def test_diff_name_status(repo_init_with_commit, git2cpp_path, tmp_path):
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    initial_file.write_text("Modified")

    cmd = [git2cpp_path, "diff", "--name-status"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    p.stdout = strip_ansi_colours(p.stdout)
    assert p.stdout == "M\tinitial.txt\n"


def test_diff_raw(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with --raw format"""
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    initial_file.write_text("Modified")

    cmd = [git2cpp_path, "diff", "--raw"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    p.stdout = strip_ansi_colours(p.stdout)
    assert "M\tinitial.txt" in p.stdout
    assert bool(re.search(":[0-9]*", p.stdout))


def test_diff_reverse(repo_init_with_commit, git2cpp_path, tmp_path):
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    original = initial_file.read_text()
    initial_file.write_text(original + "\nAdded line")

    cmd_normal = [git2cpp_path, "diff"]
    p_normal = subprocess.run(cmd_normal, capture_output=True, cwd=tmp_path, text=True)
    assert p_normal.returncode == 0
    assert "+Added line" in p_normal.stdout

    cmd_reverse = [git2cpp_path, "diff", "-R"]
    p_reverse = subprocess.run(cmd_reverse, capture_output=True, cwd=tmp_path, text=True)
    assert p_reverse.returncode == 0
    assert "-Added line" in p_reverse.stdout


@pytest.mark.parametrize("text_flag", ["-a", "--text"])
def test_diff_text(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, text_flag):
    """Test diff with -a/--text (treat all files as text)"""
    assert (tmp_path / "initial.txt").exists()

    binary_file = tmp_path / "binary.bin"
    binary_file.write_bytes(b"\x00\x01\x02\x03")

    cmd_add = [git2cpp_path, "add", "binary.bin"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "add binary"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    binary_file.write_bytes(b"\x00\x01\x02\x04")

    cmd_text = [git2cpp_path, "diff", text_flag]
    p = subprocess.run(cmd_text, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "binary.bin" in p.stdout
    assert "@@" in p.stdout


def test_diff_ignore_space_at_eol(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with --ignore-space-at-eol"""
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    original = initial_file.read_text()
    # Add trailing spaces at end of line
    initial_file.write_text(original.rstrip() + "  \n")

    cmd = [git2cpp_path, "diff", "--ignore-space-at-eol"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert p.stdout == ""


@pytest.mark.parametrize("space_change_flag", ["-b", "--ignore-space-change"])
def test_diff_ignore_space_change(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, space_change_flag
):
    """Test diff with -b/--ignore-space-change"""
    assert (tmp_path / "initial.txt").exists()

    test_file = tmp_path / "test.txt"
    test_file.write_text("Hello  world\n")

    cmd_add = [git2cpp_path, "add", "test.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "test"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    # Change spacing
    test_file.write_text("Hello    world\n")

    cmd_diff = [git2cpp_path, "diff", space_change_flag]
    p = subprocess.run(cmd_diff, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert p.stdout == ""


@pytest.mark.parametrize("ignore_space_flag", ["-w", "--ignore-all-space"])
def test_diff_ignore_all_space(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, ignore_space_flag
):
    """Test diff with -w/--ignore-all-space"""
    assert (tmp_path / "initial.txt").exists()

    test_file = tmp_path / "test.txt"
    test_file.write_text("Hello world\n")

    cmd_add = [git2cpp_path, "add", "test.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "test"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    test_file.write_text("Helloworld")

    cmd_diff = [git2cpp_path, "diff", ignore_space_flag]
    p = subprocess.run(cmd_diff, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert p.stdout == ""


@pytest.mark.parametrize(
    "unified_context_flag,context_lines",
    [("-U0", 0), ("-U1", 1), ("-U5", 5), ("--unified=3", 3)],
)
def test_diff_unified_context(
    repo_init_with_commit,
    commit_env_config,
    git2cpp_path,
    tmp_path,
    unified_context_flag,
    context_lines,
):
    """Test diff with -U/--unified for context lines"""
    assert (tmp_path / "initial.txt").exists()

    test_file = tmp_path / "test.txt"
    # Create a file with enough lines to see context differences
    test_file.write_text(
        "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10\n"
    )

    cmd_add = [git2cpp_path, "add", "test.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "test"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    # Modify line 5 (middle of the file)
    test_file.write_text(
        "Line 1\nLine 2\nLine 3\nLine 4\nMODIFIED LINE 5\nLine 6\nLine 7\nLine 8\nLine 9\nLine 10\n"
    )

    # Run diff with the parameterized flag
    cmd = [git2cpp_path, "diff", unified_context_flag]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "test.txt" in p.stdout
    assert "MODIFIED LINE 5" in p.stdout
    assert "@@" in p.stdout  # Hunk header should always be present

    # Verify context lines based on context_lines parameter

    if context_lines >= 1:
        # Should show immediate neighbors
        assert "Line 4" in p.stdout
        assert "Line 6" in p.stdout

    if context_lines >= 3:
        # Should show 3 lines before and after
        assert "Line 2" in p.stdout
        assert "Line 3" in p.stdout
        assert "Line 7" in p.stdout
        assert "Line 8" in p.stdout

    if context_lines >= 5:
        # Should show 5 lines before and after (reaching file boundaries)
        assert "Line 1" in p.stdout
        assert "Line 9" in p.stdout
        assert "Line 10" in p.stdout

    if context_lines == 0:
        # With U0, context lines should not appear (except in headers)
        # Filter out header lines
        output_lines = [
            line
            for line in p.stdout.split("\n")
            if not line.startswith("@@")
            and not line.startswith("---")
            and not line.startswith("+++")
            and not line.startswith("diff ")
            and not line.startswith("index ")
        ]
        output_content = "\n".join(output_lines)

        # Should have the deletion and addition, but minimal other content
        assert "-Line 5" in output_content
        assert "+MODIFIED LINE 5" in output_content

    # Verify that lines too far from the change don't appear with small context
    if context_lines == 1:
        assert "Line 2" not in p.stdout or p.stdout.count("Line 2") == 0
        assert "Line 8" not in p.stdout or p.stdout.count("Line 8") == 0


def test_diff_inter_hunk_context(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test diff with --inter-hunk-context"""
    assert (tmp_path / "initial.txt").exists()

    test_file = tmp_path / "test.txt"
    lines = [f"Line {i}\n" for i in range(1, 31)]
    test_file.write_text("".join(lines))

    cmd_add = [git2cpp_path, "add", "test.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "test"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    # Modify two separate sections
    lines[4] = "Modified Line 5\n"
    lines[19] = "Modified Line 20\n"
    test_file.write_text("".join(lines))

    # Test with small inter-hunk-context (should keep hunks separate)
    cmd_small = [git2cpp_path, "diff", "--inter-hunk-context=1"]
    p_small = subprocess.run(cmd_small, capture_output=True, cwd=tmp_path, text=True)
    assert p_small.returncode == 0
    assert "Modified Line 5" in p_small.stdout
    assert "Modified Line 20" in p_small.stdout
    assert "@@" in p_small.stdout

    # Count hunks in small context output
    hunk_count_small = len(
        [
            line
            for line in p_small.stdout.split("\n")
            if line.startswith("@@") and line.endswith("@@")
        ]
    )

    # Test with large inter-hunk-context (should merge hunks into one)
    cmd_large = [git2cpp_path, "diff", "--inter-hunk-context=15"]
    p_large = subprocess.run(cmd_large, capture_output=True, cwd=tmp_path, text=True)
    assert p_large.returncode == 0
    assert "Modified Line 5" in p_large.stdout
    assert "Modified Line 20" in p_large.stdout
    assert "@@" in p_large.stdout

    # Count hunks in large context output
    hunk_count_large = len(
        [
            line
            for line in p_large.stdout.split("\n")
            if line.startswith("@@") and line.endswith("@@")
        ]
    )

    # Verify both modifications appear in both outputs
    assert "Modified Line 5" in p_small.stdout and "Modified Line 5" in p_large.stdout
    assert "Modified Line 20" in p_small.stdout and "Modified Line 20" in p_large.stdout

    # Large inter-hunk-context should produce fewer or equal hunks (merging effect)
    assert hunk_count_large = hash_len_7, (
            f"Expected abbrev=12 ({hash_len_12}) to be >= abbrev=7 ({hash_len_7})"
        )


# Note: only checking if the output is a diff
def test_diff_patience(repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path):
    """Test diff with --patience algorithm"""
    assert (tmp_path / "initial.txt").exists()

    test_file = tmp_path / "test.txt"
    test_file.write_text("Line 1\nLine 2\nLine 3\n")

    cmd_add = [git2cpp_path, "add", "test.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "test"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    test_file.write_text("Line 1\nNew Line\nLine 2\nLine 3\n")

    cmd = [git2cpp_path, "diff"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "test.txt" in p.stdout
    assert "+New Line" in p.stdout


# Note: only checking if the output is a diff
def test_diff_minimal(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with --minimal (spend extra time to find smallest diff)"""
    initial_file = tmp_path / "initial.txt"
    assert (initial_file).exists()

    original = initial_file.read_text()
    initial_file.write_text(original + "\nExtra line\n")

    cmd = [git2cpp_path, "diff", "--minimal"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "initial.txt" in p.stdout
    assert "+Extra line" in p.stdout


# TODO: Find a way to check the colour
# @pytest.mark.parametrize("colour_flag", ["--color", "--no-color"])
# def test_diff_colour(xtl_clone, git2cpp_path, tmp_path, colour_flag):
#     xtl_path = tmp_path / "xtl"

#     (xtl_path / "README.md").write_text("Modified")

#     cmd = [git2cpp_path, "diff", colour_flag]
#     p = subprocess.run(cmd, capture_output=True, cwd=xtl_path, text=True, shell=True)
#     assert p.returncode == 0
#     # how to check if colour ?

#     ansi_escape = re.compile(r"\x1b\[[0-9;]*m")
#     if colour_flag == "--no-color":
#         assert not bool(re.search(ansi_escape, p.stdout))
#     else:
#         assert bool(re.search(ansi_escape, p.stdout))


@pytest.mark.parametrize("renames_flag", ["-M", "--find-renames"])
def test_diff_find_renames(repo_init_with_commit, git2cpp_path, tmp_path, renames_flag):
    """Test diff with -M/--find-renames"""
    assert (tmp_path / "initial.txt").exists()

    old_file = tmp_path / "old.txt"
    old_file.write_text("Hello\n")

    cmd_add = [git2cpp_path, "add", "old.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "Add file"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    cmd_mv = [git2cpp_path, "mv", "old.txt", "new.txt"]
    subprocess.run(cmd_mv, cwd=tmp_path, check=True)

    cmd = [git2cpp_path, "diff", "--cached", renames_flag]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "similarity index" in p.stdout
    assert "rename from old.txt" in p.stdout
    assert "rename to new.txt" in p.stdout


def test_diff_find_renames_with_threshold(repo_init_with_commit, git2cpp_path, tmp_path):
    """Test diff with -M with threshold value"""
    assert (tmp_path / "initial.txt").exists()

    old_file = tmp_path / "old.txt"
    old_file.write_text("Content\n")

    cmd_add = [git2cpp_path, "add", "old.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "Add file"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    new_file = tmp_path / "new.txt"
    old_file.rename(new_file)

    cmd_add_all = [git2cpp_path, "add", "-A"]
    subprocess.run(cmd_add_all, cwd=tmp_path, check=True)

    cmd = [git2cpp_path, "diff", "--cached", "-M60"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "similarity index" in p.stdout
    assert "rename from old.txt" in p.stdout
    assert "rename to new.txt" in p.stdout


@pytest.mark.parametrize("copies_flag", ["-C", "--find-copies"])
def test_diff_find_copies_from_modified(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, copies_flag
):
    """Test diff with -C/--find-copies when source file is also modified"""
    assert (tmp_path / "initial.txt").exists()

    original_file = tmp_path / "original.txt"
    original_file.write_text("Content to be copied\n")

    cmd_add = [git2cpp_path, "add", "original.txt"]
    subprocess.run(cmd_add, cwd=tmp_path, check=True)

    cmd_commit = [git2cpp_path, "commit", "-m", "add original file"]
    subprocess.run(cmd_commit, cwd=tmp_path, check=True)

    # Modify original.txt (this makes it a candidate for copy detection)
    original_file.write_text("Content to be copied\nExtra line\n")
    subprocess.run([git2cpp_path, "add", "original.txt"], cwd=tmp_path, check=True)

    # Create copy with original content
    copied_file = tmp_path / "copied.txt"
    copied_file.write_text("Content to be copied\n")
    subprocess.run([git2cpp_path, "add", "copied.txt"], cwd=tmp_path, check=True)

    cmd = [git2cpp_path, "diff", "--cached", copies_flag]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)
    assert p.returncode == 0
    assert "similarity index" in p.stdout
    assert "copy from original.txt" in p.stdout
    assert "copy to copied.txt" in p.stdout


@pytest.mark.parametrize("copies_flag", ["-C", "--find-copies"])
def test_diff_find_copies_harder(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, copies_flag
):
    """Test diff with -C/--find-copies and --find-copies-harder for unmodified sources"""
    assert (tmp_path / "initial.txt").exists()

    original_file = tmp_path / "original.txt"
    original_file.write_text("Content to be copied\n")

    subprocess.run([git2cpp_path, "add", "original.txt"], cwd=tmp_path, check=True)
    subprocess.run(
        [git2cpp_path, "commit", "-m", "add original file"],
        cwd=tmp_path,
        check=True,
    )

    # Create identical copy
    copied_file = tmp_path / "copied.txt"
    copied_file.write_text("Content to be copied\n")
    subprocess.run([git2cpp_path, "add", "copied.txt"], cwd=tmp_path, check=True)

    # Use --find-copies-harder to detect copies from unmodified files
    cmd = [git2cpp_path, "diff", "--cached", copies_flag, "--find-copies-harder"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)

    assert p.returncode == 0
    assert "similarity index 100%" in p.stdout
    assert "copy from original.txt" in p.stdout
    assert "copy to copied.txt" in p.stdout


@pytest.mark.parametrize("copies_flag", ["-C50", "--find-copies=50"])
def test_diff_find_copies_with_threshold(
    repo_init_with_commit, commit_env_config, git2cpp_path, tmp_path, copies_flag
):
    """Test diff with -C with custom threshold"""
    assert (tmp_path / "initial.txt").exists()

    original_file = tmp_path / "original.txt"
    original_content = "Line 1\nLine 2\nLine 3\nLine 4\nLine 5\n"
    original_file.write_text(original_content)

    subprocess.run([git2cpp_path, "add", "original.txt"], cwd=tmp_path, check=True)
    subprocess.run(
        [git2cpp_path, "commit", "-m", "add original file"],
        cwd=tmp_path,
        check=True,
    )

    # Create a partial copy (60% similar)
    copied_file = tmp_path / "copied.txt"
    copied_file.write_text("Line 1\nLine 2\nLine 3\nNew line\nAnother line\n")
    subprocess.run([git2cpp_path, "add", "copied.txt"], cwd=tmp_path, check=True)

    # With threshold of 50%, should detect copy
    cmd = [git2cpp_path, "diff", "--cached", copies_flag, "--find-copies-harder"]
    p = subprocess.run(cmd, capture_output=True, cwd=tmp_path, text=True)

    assert p.returncode == 0
    assert "similarity index" in p.stdout
    assert "copy from original.txt" in p.stdout
    assert "copy to copied.txt" in p.stdout


# @pytest.mark.parametrize("break_rewrites_flag", ["-B", "--break-rewrites"])
# def test_diff_break_rewrites(xtl_clone, git2cpp_path, tmp_path, break_rewrites_flag):
#     """Test diff with -B/--break-rewrites"""
#     xtl_path = tmp_path / "xtl"

#     test_file = xtl_path / "test.txt"
#     test_file.write_text("Original content\n")

#     cmd_add = [git2cpp_path, "add", "test.txt"]
#     subprocess.run(cmd_add, cwd=xtl_path, check=True)

#     cmd_commit = [git2cpp_path, "commit", "-m", "test"]
#     subprocess.run(cmd_commit, cwd=xtl_path, check=True)

#     # Completely rewrite the file
#     test_file.write_text("Completely different content\n")

#     cmd = [git2cpp_path, "diff", break_rewrites_flag]
#     p = subprocess.run(cmd, capture_output=True, cwd=xtl_path, text=True)
#     assert p.returncode == 0


def test_diff_refuses_more_than_two_treeish(repo_init_with_commit, git2cpp_path, tmp_path):
    # HEAD exists thanks to repo_init_with_commit
    p = subprocess.run(
        [git2cpp_path, "diff", "HEAD", "HEAD", "HEAD"],
        capture_output=True,
        text=True,
        cwd=tmp_path,
    )
    assert p.returncode != 0
    assert "2 required but received 3" in p.stderr


def test_diff_cached_and_no_index_are_incompatible(git2cpp_path, tmp_path):
    # Create two files to satisfy the --no-index path arguments
    a = tmp_path / "a.txt"
    b = tmp_path / "b.txt"
    a.write_text("hello\n")
    b.write_text("world\n")

    p = subprocess.run(
        [git2cpp_path, "diff", "--cached", "--no-index", str(a), str(b)],
        capture_output=True,
        text=True,
        cwd=tmp_path,
    )

    assert p.returncode != 0
    assert "--cached and --no-index are incompatible" in (p.stderr + p.stdout)

Web Proxy Viewer  |  New URL  |  Original Page