6

Please, observe:

C:\Dayforce\test [master ↓2 +0 ~2 -0 !]> git pull
error: Your local changes to the following files would be overwritten by merge:
        2.txt
Please commit your changes or stash them before you merge.
Aborting
Updating 2dc8bd0..ea343f8
C:\Dayforce\test [master ↓2 +0 ~2 -0 !]>

Does git have a command that can tell me which uncommitted files cause the this error? I can see them displayed by git pull, but I really do not want to parse git pull output.

I am fully aware of pull.rebase and rebase.autostash config options, please do not bring them up.

EDIT 1

It is OK to execute git pull first. In fact, the logic to identify the problematic files will be done after git pull fails with this reason. The way I recognize it in Powershell is:

git pull
# Possible exit codes:
# 1 - either local changes or pull merge conflict (but the merge has not been started yet)
# 128 - a merge is in progress
if ($LASTEXITCODE)
{
    git merge HEAD 2> $null                      # Disambiguate the exit code
    if ($LASTEXITCODE -eq 128)
    {
        # Two options:
        #  - pull merge conflict
        #  - a merge is in progress
        git mergetool
    }
    else
    {
        throw "Cannot pull due to uncommitted changes"
    }
}

So, instead of aborting I would like to identify the problematic files and essentially replicate the rebase.autostash, but without rebase.

EDIT 2

I used to think that git pull outputs something like this in case of clashes with uncommitted changes:

C:\xyz\test [master ↓4 ↑1 +0 ~3 -0 !]> git pull
error: Your local changes to the following files would be overwritten by merge:
        2.txt
        a.txt
Please commit your changes or stash them before you merge.
Aborting
C:\xyz\test [master ↓4 ↑1 +0 ~3 -0 !]>

Which is easy to parse. But today, I got something different:

C:\xyz\test [master ↓4 ↑1 +0 ~2 -0 | +0 ~1 -0 !]> git pull
error: Your local changes to the following files would be overwritten by merge:
  1.txt a.txt
C:\xyz\test [master ↓4 ↑1 +0 ~2 -0 | +0 ~1 -0 !]>

I do not know if this has something to do with my Powershell console having gotten botched somehow or with some recent git update, which I had installed automatically without noticing it.

mark
  • 49,076
  • 65
  • 227
  • 485

1 Answers1

2

I do not know if this has something to do with my Powershell console having gotten botched somehow or with some recent git update

Git 2.19 has recently change how a merge reports this error, with commit 9270239 (Jul. 2018)

This is based on merge-recursive.c#merge_trees, which keeps track of two trees in order to detect common files being overwritten.
The problems are:

  • once the pull command fails, that information is not kept around
  • any Git state parsing should be done through plumbing, not porcelain commands

In your case, since git pull has completed its fetched part, but not its merge part, you could do a git diff -–name-only HEAD origin/yourFetchedBranch in order to compare the working tree with what is fetched.

That should list files which differs, including your 2.txt.

would it not give me all the files that are going to be changed and not just the conflicting ones?

Yes, it would.
For each file, you would still need to check if it is part of the current list of modified (not staged or staged but not committed) files:

git ls-files --other --modified --exclude-standard
git diff --name-only --cached
VonC
  • 1,042,979
  • 435
  • 3,649
  • 4,283
  • When I run `git diff --word-diff=porcelain HEAD origin/master` it outputs the diff between HEAD and origin/master, like the unix style patch content. – mark Dec 27 '18 at 17:42
  • Is there a way to extract the file name in there? – VonC Dec 27 '18 at 17:43
  • I am sure there is, but would it not give me all the files that are going to be changed and not just the conflicting ones? – mark Dec 27 '18 at 18:03
  • @mark I would actually use `git diff --name-only`, and compare it with `git ls-files --other --modified --exclude-standard`: see my edited answer. – VonC Dec 27 '18 at 19:04
  • How does checking if a file is modified not staged help? Any combination is possible - I could have staged file that clashes with the merge and unstaged file that does not. Could you elaborate why it is relevant? – mark Dec 27 '18 at 19:07
  • @mark Because Git does not check for *conflicts*. It only check for a *clean* working tree. If you have a file being modified (not staged) which is involved by your merge, your merge will stop, conflict or not. – VonC Dec 27 '18 at 19:08
  • @mark That is what https://github.com/git/git/blob/92702392cefdbd66ca593fa909540230ef9e005e/merge-recursive.c#L1983 shows: Git is looking for "common objects", not for merge conflitcs. – VonC Dec 27 '18 at 19:09
  • OK and if the file is staged, pull will not abort? – mark Dec 27 '18 at 19:24
  • @mark Yes, it would. I have added the command to list staged files. – VonC Dec 27 '18 at 19:43
  • It will take me some time to test it. Thank you. – mark Dec 27 '18 at 20:35