Re: Crash on git log with -L and -G on file rename
- From
Koji Nakamaru <koji.nakamaru@gree.net>
- Date
- Mar 4, 2026, 03:01 UTC
- Message-ID
- <CAOTNsDwdS=+4RuAD6pAt-==uE6S4Wq_4cat+0OqmKV2wgoVheQ@mail.gmail.com>
- In-Reply-To
- <aac-QdjY1ohAqgw_@desktop>
On Wed, Mar 4, 2026 at 5:42 AM Matthew Hughes <matthewhughes934@gmail.com> wrote:
Show 62 quoted lines
>
> 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