From: Koji Nakamaru Date: Wed, 04 Mar 2026 03:01:54 GMT Subject: Re: Crash on git log with -L and -G on file rename Message-ID: In-Reply-To: On Wed, Mar 4, 2026 at 5:42 AM Matthew Hughes wrote: > > Hi, > > I hit a crash (assertion error) running `git log` with both `-L` and `-G` under > certain conditions. I've created script to reproduce the behaviour in a fresh > git repo: > > #!/usr/bin/env bash > > set -o errexit > > git init . > # Note: example is .rs file, but it should work with anything that -L understands > echo "fn my_func() {}" > file.rs > # 1. file named 'file.rs' > git add file.rs > git commit --message 'Add the file' > > # 2. separate branch with the file renamed > git checkout -b some-branch > git mv file.rs new_file.rs > git commit --message 'Move the file' > > git checkout - > git commit --allow-empty --message 'Some extra commit so we get a merge commit' > # 3. merge: one parent has file.rs, the other has new_file.rs > git merge --no-edit some-branch > > # 4. post merge, move the file back > git mv new_file.rs file.rs > git commit --message 'Move the file back' > > # 5. things go BOOM > git log -L:my_func:file.rs -G '.' > > I'm not sure if _every_ step in that script is necessary, but it's the simplest > setup I could figure out to trigger the crash. Running that script I hit the > error: > > git: line-log.c:1056: process_diff_filepair: Assertion `pair->two->oid_valid' failed. > Aborted (core dumped) git log -L:my_func:file.rs -G '.' > > The backtrace shows that the failed assertion occurs under > `process_ranges_merge_commit`, so maybe there's an issue with the file being > renamed on both sides of the merge? > > The crash requires both flags to trigger, remove either and it will run fine. > > I've tested the above on the `git` from my system package manager on Arch > Linux: git version 2.53.0, and one built from source at > 2cc71917514657b93014134350864f4849edfc83 (the version of 'master' checked out > on my machine at the time). I don't think reproduction relies on any specific > config since I've had it trigger with both `GIT_CONFIG_GLOBAL` and > `GIT_CONFIG_SYSTEM` set to `/dev/null` > > Just for reference, I originally triggered the bug in the `rustfmt` repo[1] > (checked-out at cebab3e99259be82ff069e5ae89e91855d79e534) running: > > git log -G offset_left -L:format_trait:src/items.rs > > Link: github.com/rust-lang/rustfmt [1] > The root cause appears to be that diff_might_be_rename() only checks diff_queued_diff.queue[i]->one. The following change can fix the issue. diff --git a/line-log.c b/line-log.c index eeaf68454e..2da7658ba9 100644 --- a/line-log.c +++ b/line-log.c @@ -834,6 +834,10 @@ static inline int diff_might_be_rename(void) /* fprintf(stderr, "diff_might_be_rename found creation of: %s\n", */ /* diff_queued_diff.queue[i]->two->path); */ return 1; + } else if (!DIFF_FILE_VALID(diff_queued_diff.queue[i]->two)) { + /* fprintf(stderr, "diff_might_be_rename found deletion of: %s\n", */ + /* diff_queued_diff.queue[i]->one->path); */ + return 1; } return 0; } -- Koji Nakamaru