24

I am writing a bash script to do some automation. Part of the script involves navigating to a local repo, switching to the local master branch, then pulling the remote master to update the local master branch with the latest code.

Does anyone know if there's a way I can programatically determine if the pull resulted in a merge conflict so that I can bail at that point and not execute the rest of the script?

Any help / info is appreciated, thanks!

Jason McKindly
  • 463
  • 1
  • 8
  • 15
  • 1
    Use the `--ff-only` to force `merge`/`pull` to error if they would cause a conflict (or otherwise cannot fast-forward merge)? – Etan Reisner Jan 16 '15 at 19:00
  • 1
    Does --ff-only cause a non-zero return I can check for? I have to catch it so I can bail out of the script and not just the merge. – Jason McKindly Jan 16 '15 at 19:06
  • 1
    Did you check the man page? `--ff-only Refuse to merge and exit with a non-zero status...` – Etan Reisner Jan 16 '15 at 19:08
  • Depending on the situation, I prefer the answer in https://stackoverflow.com/a/30783114/13773246 (check for the existence of `.git/MERGE_HEAD`). In particular `git ls-files -u` will be empty if conflicts are resolved and added to the index but not yet committed, while `MERGE_HEAD` exists until the resolved conflicts are committed. – jmou Dec 25 '22 at 23:23

4 Answers4

28

Based on the answer given by torek, here is a ready-to-use snippet:

CONFLICTS=$(git ls-files -u | wc -l)
if [ "$CONFLICTS" -gt 0 ] ; then
   echo "There is a merge conflict. Aborting"
   git merge --abort
   exit 1
fi
flix
  • 1,821
  • 18
  • 23
26

Use git ls-files -u. It prints unmerged files. If it prints nothing, there are no unmerged files.

However, while that's a direct answer for the question you asked "as asked", using git pull in a script is a bit dicey: pull is a convenience script that runs fetch for you, and then (depending on how you direct it and/or have configured your repo) runs either merge or rebase for you. Given that you are writing a script that has a particular goal in mind, you should most likely be using lower-level commands that do more-specific things. For instance, you might use git fetch followed by (as Etan Reisner suggested in a comment) git merge --ff-only so as to never attempt a merge.

torek
  • 448,244
  • 59
  • 642
  • 775
  • 1
    For what the script does, I don't want to avoid a merge if there's a conflict. I want the merge to occur and then determine if there was a conflict with the merge. – Jason McKindly Jan 16 '15 at 19:09
  • 1
    OK, in that case I'd still suggest doing `git fetch` and a direct `git merge`; you can then inspect the exit status of the merge step. It does not seem to be well-documented and I'm not sure if the `ls-files -u` method might be safer, but `git merge` actually exits 0 on no-conflicts, 1 on conflicts. – torek Jan 16 '15 at 19:17
  • In my experience playing around with it just now for a script I'm writing, `git merge` just encountered a conflict and exited with a 127 code, leaving the repo in merging state – Tom Warner Aug 01 '23 at 18:13
0

This lists files with a merge conflict:

git diff --name-only --diff-filter=U
Michael Schmid
  • 4,601
  • 1
  • 22
  • 22
0

git config --global user.email "Email Id" && git config --global user.name "User Name" && git merge --no-commit --no-ff origin/master && git diff --cached && git merge --abort

This code is combination of multiple steps.

  1. Starting a merge with no-commit and no-ff.
  2. Fetching differences in both branch.
  3. Aborting the merge

When there will be any conflict it will fail at second step and you will get merge conflict error as output , else you will get difference in both branch.

For details you can go to GIT-SCM documentation

Aniket Kumar
  • 165
  • 2
  • 10