EDIT: AS @Daniel Martin pointed in a comment, the script here written partially relies on a side effect that git stash
had until git 2.22-rc0. As such, using it as is with versions after 2.22 might not behave as intended. Some changes might be necessary in that case (feel free to modify as required and reshare the edited version either editing this question or adding a new answer).
I have been handling this task for a few weeks and I have found a few corner cases that are not correctly handled by this script. Searching around and taking a look at Git sources I have arrived at this script:
#!/bin/bash
# ${1} is the base common file
# ${2} is the file as modified by the base branch, and where the results must be
# ${3} is the file as modified by the incoming branch / stash
# ${4} is the path of the file being merged
# does not support octopus merge.
branch=$(git symbolic-ref --short HEAD || git name-rev --name-only HEAD)
githeadNum=$(env | grep GITHEAD | wc -l) # pathces do not create any GITHEAD var
# get a GITHEAD with message 'Stashed changes'
# if we are applying a stash, it must exist.
# see https://github.com/git/git/blob/2d08f3deb9feb73dc8d21d75bfd367839fc1322c/git-stash.sh#L616
stash=$(env | grep -E 'GITHEAD_[0-9a-f]{40}\b*=\b*Stashed changes' | wc -l) # e.g. GITHEAD_<sha>=Stashed changes
if [ "$stash" -eq "1" ]
then
# we are in a stash
else
if [ "$githeadNum" -eq "0" ]
then
# we are in a patch
else
# normal merge
# only one GITHEAD, merging
gitHeadName=$(env | grep GITHEAD)
source="${gitHeadName##*=}"
fi
fi
exit 1
I recover the destination branch as
$(git symbolic-ref --short HEAD || git name-rev --name-only HEAD)
I found the first part failing for rebase
, so in case of a rebase the second part should work.
For the source, I parse the GITHEAD env variable but check for patches or stash application, since I want to handle those cases differently (and patches do not leave GITHEAD)
For stash apply:
stash=$(env | grep -E 'GITHEAD_[0-9a-f]{40}\b*=\b*Stashed changes' | wc -l)
$stash will be 1 in case we are in a stash, 0 otherwhise
For patches I count number of GITHEAD, which must be zero:
githeadNum=$(env | grep GITHEAD | wc -l)