Replace shebang with following if Nix is installed to automatically pull in dependencies.
#!/usr/bin/env nix-shell
#! nix-shell -i bash -p git fd ripgrep| #!/usr/bin/env bash | |
| # syncthing share. some parent directory | |
| targetShare="$PWD" | |
| while true; do | |
| if [ -d "$targetShare/.stfolder" ]; then break; fi | |
| if [ "$targetShare" == "/" ]; then | |
| echo "Could not find parent Syncthing share" | |
| exit 1; | |
| fi | |
| targetShare=$(realpath "$targetShare/..") | |
| done | |
| # search scope | |
| fdArgs="--no-ignore" | |
| # regex to detect sync conflicts | |
| conflictRegex='\.sync-conflict-[0-9]+-[0-9]{6}-[A-Z0-9]{7}(\..+)?$' | |
| # regex to detect if file is in progress of being merged | |
| mergeRegex='^<<<<<<< .+$\n(.*\n)*^=======$\n(.*\n)*^>>>>>>> .+$\n' | |
| sharePath="${PWD#"$targetShare/"}" | |
| conflicts="$(fd "$conflictRegex" . --type file $fdArgs)" | |
| if [ "$conflicts" == "" ]; then echo "No conflicts, exiting."; exit 0; fi | |
| count=$(echo "%s" "$conflicts" | wc -l) | |
| countLen=$(printf "%d" "$count" | wc -c) | |
| echo "Fixing $count conflict(s) via 3-way merge:"; | |
| echo "$conflicts" | while read -r path; do | |
| i=$((${i:-0} + 1)) | |
| dir=$(dirname "$path") | |
| name=$(basename "$path") | |
| sanitizedName="$(echo "$name" | sed -r "s/$conflictRegex//")" | |
| extension="$(echo "$name" | rev | cut -d. -f1 | rev)" # might be empty | |
| # find paths for 3-way merge | |
| base="$dir/$sanitizedName" | |
| ancestors="$(fd \ | |
| "$(echo "$sanitizedName" | sed -r "s/\.$extension\$//")" \ | |
| "$targetShare/.stversions/$sharePath/$dir" \ | |
| --type file $fdArgs 2>/dev/null)" | |
| other="$path" | |
| printf "[$(printf "%0${countLen}d" "$i")/$count] Merging '%s': " "$(echo "$base" | sed -r 's/^\.\///')" | |
| # pick "latest" ancestor | |
| ancestor="$(echo "$ancestors" | sort -hr | head -1)" | |
| # if no common ancestor, try empty file | |
| ancestor="${ancestor:-/dev/null}" | |
| # check if base even exists | |
| if [ ! -f "$base" ]; then echo "conflict file references non-existant base, skipping."; continue; fi | |
| if rg --quiet --multiline "$mergeRegex" "$base"; then echo "file has pending manual merge, skipping."; continue; fi | |
| # perform actual merge | |
| git merge-file "$base" "$ancestor" "$other" 2>/dev/null | |
| # for documentation on exit codes, see: `man git-merge-file` | |
| mergeStatus="$?" | |
| if [ "$mergeStatus" -eq 255 ]; then echo "can't merge binary files, skipping."; continue; fi | |
| if [ "$mergeStatus" -gt 127 ]; then echo "could not perform merge due to unknown error ($mergeStatus)."; continue; fi | |
| if [ "$mergeStatus" -eq 0 ]; then echo "merged cleanly."; rm "$other"; continue; fi | |
| if [ "$mergeStatus" -lt 0 ]; then echo "could not perform merge due to error ($mergeStatus)."; continue; fi | |
| if [ "$mergeStatus" -gt 0 ]; then echo "needs manual intervention for $mergeStatus merge(s)."; rm "$other"; continue; fi | |
| done |