On 2021-01-09 at 19:14:13, Alan Mackenzie wrote: > 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? git stash doesn't consider there being nothing to stash to be an error, so it doesn't set a nonzero error code. Think of it as, "I want a clean working tree," not, "I want to create a stash." In that sense, what you wanted is already done, so it's not an error. You are, however, not the only person who's been unhappy with this behavior. A --force option may be a useful option to have if someone wanted to create it. > 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. Using "git status --porcelain" before and after the stash is an easy way to find out whether there was anything to stash. If there's a difference, then a stash was created. > 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. In the chart, the options in the first section are "normal" cases that occur without a merge conflict. The second section is things that happen when there's a conflict (the "unmerged" states). So what you're looking for to find conflicts is something maybe a little like this: git status --porcelain | grep -E '^(AA|DD|[AUD]U|U[AUD])' If you believe that you're likely to need to handle names with newlines, then of course you'll need -z as well. I do agree that this is a little unclear; I went ahead and simulated a merge conflict to verify. I'll try to send a patch making the documentation reflect what I mentioned about the chart above. -- brian m. carlson (he/him or they/them) Houston, Texas, US