Subject: Difficulties of scripting git

From: Alan Mackenzie <[email-masked]>
Date: Sat, 9 Jan 2021 19:14:13 +0000

Hello, git.

I want to write a bash script (more precisely, correct an existing
script) which uses git, and it is DIFFICULT!!!

I need a git pull in the script.  Fine, but how does the script know if
it's worked or not?  I couldn't find any description of a return code in
the git-pull man page (or in the git-merge man page).

The big problem is when I have modified, uncommitted files in the target
repo, and those same files are to be updated in commits coming from the
source repo.  Sadly, git is unable to merge these changes.  It just
fails, putting an error message onto stderr, but doesn't tell the
calling script in any way that I can see.

One idea would be always to call git stash before doing the pull, then
git stash pop afterwards.  Trouble is, git stash is unreliable - it
doesn't always add a new stash entry, so the stash pop at the end would
sometimes/often pop off an entry it shouldn't.  git stash doesn't have a
--force argument.  git stash doesn't set a result code, either, that I
can see.  One way around this would be to do

    $ git stash list | wc -l

both before and after the git stash and compare the answers, but really?

So, next idea, feed the output from git status --porcelain through grep
before and after the git pull, so as to find out whether there are any
modified files before the git pull (thus making a stash necessary) and
any files with conflicts after the git stash pop.  Shouldn't be too
difficult.

Except, how does one recognise a file with conflicts from this git
status output?  The man page says that

    "   For paths with merge conflicts, `X' and `Y' show the modification
    states of each side of the merge.  For paths that do not have merge
    conflicts, `X' shows the status of the index, and `Y' shows the status
    of the work tree.  For untracked paths, `XY' are `??'.  Other status
    codes can be interpreted as follows:  ...."

I've spent nearly an hour trying to make sense of this bit of man page.
How is one meant to distinguish an XY of a merge conflict from the XY of
an index/work tree entry?  I can't find that key bit of information
anywhere.

What am I missing?  Why does writing scripts using git have to be so
hard?

-- 
Alan Mackenzie (Nuremberg, Germany).