Skip to content

Git LFS diffs do not show conflict markers making git diff --check return the wrong status #5990

@DarkDefender

Description

@DarkDefender

Describe the bug
When getting a merge conflict after trying to pop a stash or when using git pull --rebase with autostashing enabled, git diff --check will report no conflicts even if you haven't resolved the conflict.

Git GUIs like VScode and SourceGit uses the git diff --check method to sometimes check if a file has been resolved and then incorrectly displays to the user that the have resolved the conflicts and are ready to commit/stage the conflict file.

The error message you get when you do a git pull --rebase with autostashing is not really that helpful either:

Encountered 1 file that should have been a pointer, but wasn't:
	<path to conflict file>

To Reproduce
Steps to reproduce the behavior:

  1. Have a repo with three commits that has two commits that changes the LFS file test.bin
  2. Go to the first commit that added test.bin and make changes to it.
  3. Stash the changes
  4. Go to the latest commit and pop the stash.
  5. Notice in git status that you have a both modified: status for test.bin
  6. Run cat test.bin and notice that there are conflict markers in the file
  7. Run git diff and notice that they are missing. Run git diff ---check and notice that it doesn't complain about any lingering conflict markers.

Expected behavior
I think that when there are conflict markers in the LFS file, Git LFS should then switch the diff output and fallback to the standard output of git diff as if it was a text file (because that is what the lfs file will be at this point as it is not in a valid state).

If there are conflict markers in the file, instead of printing Encountered 1 file that should have been a pointer, but wasn't: it could probably print that there is a merge conflict in the file and that the user needs to decide which lfs pointer to use (by resolving the conflict)

System environment

OS: Gentoo Linux
Git: tested 2.45.3 and 2.48.1
Git LFS: tested 3.5.1 and 3.6.1

Extra

I tried to see where this filtering of diffs is happening on the git LFS side and I think this is in gitscanner_log.go. But as the comments in the file hints to, I'm guessing they are filtered to make it easier to work with for git LFS.

However I'm wondering if my idea that only falling back to the regular diff printing when there are conflict markers would be OK still as I don't think LFS can do anything useful with the diff output when there are multiple oid and size entries in the file. (But perhaps my assumption is incorrect?)

For the nicer prints when pull rebasing, I'm guessing we could perhaps introduce a new check in commands/command_filter_process.go that checks for conflict markers and if it detects them, it will print an other more specialized message that is a bit more helpful in describing what is going on. (IE that the file contains conflicts so it is not a valid pointer file until they are resolved).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Enhancements

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions