1*90c8c64dSAndroid Build Coastguard Worker#!/bin/bash 2*90c8c64dSAndroid Build Coastguard Worker 3*90c8c64dSAndroid Build Coastguard Workerusage() { 4*90c8c64dSAndroid Build Coastguard Worker cat <<EOF 5*90c8c64dSAndroid Build Coastguard WorkerUsage: 6*90c8c64dSAndroid Build Coastguard Worker ${0} Remerge all files with conflict markers in the git working tree 7*90c8c64dSAndroid Build Coastguard Worker ${0} [FILE...] Remerge the given files 8*90c8c64dSAndroid Build Coastguard Worker 9*90c8c64dSAndroid Build Coastguard WorkerOptions: 10*90c8c64dSAndroid Build Coastguard Worker -t, --tool {bcompare,meld,vimdiff} 11*90c8c64dSAndroid Build Coastguard Worker Use the specified merge tool. 12*90c8c64dSAndroid Build Coastguard WorkerEOF 13*90c8c64dSAndroid Build Coastguard Worker} 14*90c8c64dSAndroid Build Coastguard Worker 15*90c8c64dSAndroid Build Coastguard Worker# shellcheck disable=SC2155 16*90c8c64dSAndroid Build Coastguard Workerreadonly BIN_DIR=$(dirname "${BASH_SOURCE[0]}") 17*90c8c64dSAndroid Build Coastguard Workerreadonly SPLIT3="${BIN_DIR}/split3.awk" 18*90c8c64dSAndroid Build Coastguard Workerreadonly CONFLICT_MARKER_BEGIN='^<{7}( .+)?$' 19*90c8c64dSAndroid Build Coastguard Workerreadonly CONFLICT_MARKER_BASE='^\|{7}( .+)?$' 20*90c8c64dSAndroid Build Coastguard Worker 21*90c8c64dSAndroid Build Coastguard WorkerTEMP_FILES=() 22*90c8c64dSAndroid Build Coastguard Workercleanup() { 23*90c8c64dSAndroid Build Coastguard Worker rm -rf "${TEMP_FILES[@]}" 24*90c8c64dSAndroid Build Coastguard Worker} 25*90c8c64dSAndroid Build Coastguard Workertrap cleanup EXIT 26*90c8c64dSAndroid Build Coastguard Worker 27*90c8c64dSAndroid Build Coastguard Workerxtrace() { 28*90c8c64dSAndroid Build Coastguard Worker ( 29*90c8c64dSAndroid Build Coastguard Worker set -x 30*90c8c64dSAndroid Build Coastguard Worker "${@}" 31*90c8c64dSAndroid Build Coastguard Worker ) 32*90c8c64dSAndroid Build Coastguard Worker} 33*90c8c64dSAndroid Build Coastguard Worker 34*90c8c64dSAndroid Build Coastguard Workermergetool() { 35*90c8c64dSAndroid Build Coastguard Worker local file="${1}" 36*90c8c64dSAndroid Build Coastguard Worker local MERGED="$file" 37*90c8c64dSAndroid Build Coastguard Worker local BASE="${file}:BASE" 38*90c8c64dSAndroid Build Coastguard Worker local LOCAL="${file}:LOCAL" 39*90c8c64dSAndroid Build Coastguard Worker local REMOTE="${file}:REMOTE" 40*90c8c64dSAndroid Build Coastguard Worker TEMP_FILES+=("$BASE" "$LOCAL" "$REMOTE") 41*90c8c64dSAndroid Build Coastguard Worker 42*90c8c64dSAndroid Build Coastguard Worker local has_base=false 43*90c8c64dSAndroid Build Coastguard Worker if grep -qE "${CONFLICT_MARKER_BASE}" "$file"; then 44*90c8c64dSAndroid Build Coastguard Worker has_base=true 45*90c8c64dSAndroid Build Coastguard Worker fi 46*90c8c64dSAndroid Build Coastguard Worker 47*90c8c64dSAndroid Build Coastguard Worker $has_base && awk -f "$SPLIT3" -v TARGET=BASE <"$file" >"$BASE" 48*90c8c64dSAndroid Build Coastguard Worker awk -f "$SPLIT3" -v TARGET=LOCAL <"$file" >"$LOCAL" 49*90c8c64dSAndroid Build Coastguard Worker awk -f "$SPLIT3" -v TARGET=REMOTE <"$file" >"$REMOTE" 50*90c8c64dSAndroid Build Coastguard Worker 51*90c8c64dSAndroid Build Coastguard Worker case "$MERGETOOL" in 52*90c8c64dSAndroid Build Coastguard Worker bc*) 53*90c8c64dSAndroid Build Coastguard Worker if $has_base; then 54*90c8c64dSAndroid Build Coastguard Worker xtrace bcompare "$LOCAL" "$REMOTE" "$BASE" -mergeoutput="$MERGED" 55*90c8c64dSAndroid Build Coastguard Worker else 56*90c8c64dSAndroid Build Coastguard Worker xtrace bcompare "$LOCAL" "$REMOTE" -mergeoutput="$MERGED" 57*90c8c64dSAndroid Build Coastguard Worker fi 58*90c8c64dSAndroid Build Coastguard Worker ;; 59*90c8c64dSAndroid Build Coastguard Worker meld) 60*90c8c64dSAndroid Build Coastguard Worker if $has_base; then 61*90c8c64dSAndroid Build Coastguard Worker xtrace meld "$LOCAL" "$BASE" "$REMOTE" -o "$MERGED" 62*90c8c64dSAndroid Build Coastguard Worker else 63*90c8c64dSAndroid Build Coastguard Worker xtrace meld "$LOCAL" "$MERGED" "$REMOTE" 64*90c8c64dSAndroid Build Coastguard Worker fi 65*90c8c64dSAndroid Build Coastguard Worker ;; 66*90c8c64dSAndroid Build Coastguard Worker vim*) 67*90c8c64dSAndroid Build Coastguard Worker if $has_base; then 68*90c8c64dSAndroid Build Coastguard Worker xtrace vimdiff -c '4wincmd w | wincmd J' "$LOCAL" "$BASE" "$REMOTE" "$MERGED" 69*90c8c64dSAndroid Build Coastguard Worker else 70*90c8c64dSAndroid Build Coastguard Worker xtrace vimdiff -c 'wincmd l' "$LOCAL" "$MERGED" "$REMOTE" 71*90c8c64dSAndroid Build Coastguard Worker fi 72*90c8c64dSAndroid Build Coastguard Worker ;; 73*90c8c64dSAndroid Build Coastguard Worker esac 74*90c8c64dSAndroid Build Coastguard Worker} 75*90c8c64dSAndroid Build Coastguard Worker 76*90c8c64dSAndroid Build Coastguard Worker# 77*90c8c64dSAndroid Build Coastguard Worker# BEGIN 78*90c8c64dSAndroid Build Coastguard Worker# 79*90c8c64dSAndroid Build Coastguard Worker 80*90c8c64dSAndroid Build Coastguard WorkerMERGETOOL=vimdiff 81*90c8c64dSAndroid Build Coastguard Workerif [[ -n "$DISPLAY" ]]; then 82*90c8c64dSAndroid Build Coastguard Worker if command -v bcompare; then 83*90c8c64dSAndroid Build Coastguard Worker MERGETOOL=bcompare 84*90c8c64dSAndroid Build Coastguard Worker elif command -v meld; then 85*90c8c64dSAndroid Build Coastguard Worker MERGETOOL=meld 86*90c8c64dSAndroid Build Coastguard Worker fi 87*90c8c64dSAndroid Build Coastguard Workerfi >/dev/null 88*90c8c64dSAndroid Build Coastguard Worker 89*90c8c64dSAndroid Build Coastguard Workerwhile [[ "$1" =~ ^- ]]; do 90*90c8c64dSAndroid Build Coastguard Worker arg="${1}" 91*90c8c64dSAndroid Build Coastguard Worker shift 92*90c8c64dSAndroid Build Coastguard Worker case "$arg" in 93*90c8c64dSAndroid Build Coastguard Worker --) break ;; 94*90c8c64dSAndroid Build Coastguard Worker -t | --tool) 95*90c8c64dSAndroid Build Coastguard Worker MERGETOOL="${1}" 96*90c8c64dSAndroid Build Coastguard Worker shift 97*90c8c64dSAndroid Build Coastguard Worker ;; 98*90c8c64dSAndroid Build Coastguard Worker -h | --help | --usage) 99*90c8c64dSAndroid Build Coastguard Worker usage 100*90c8c64dSAndroid Build Coastguard Worker exit 0 101*90c8c64dSAndroid Build Coastguard Worker ;; 102*90c8c64dSAndroid Build Coastguard Worker *) 103*90c8c64dSAndroid Build Coastguard Worker usage 104*90c8c64dSAndroid Build Coastguard Worker exit 1 105*90c8c64dSAndroid Build Coastguard Worker ;; 106*90c8c64dSAndroid Build Coastguard Worker esac 107*90c8c64dSAndroid Build Coastguard Workerdone 108*90c8c64dSAndroid Build Coastguard Worker 109*90c8c64dSAndroid Build Coastguard WorkerTRUST_EXIT_CODE=false 110*90c8c64dSAndroid Build Coastguard Workerif git rev-parse >/dev/null 2>/dev/null; then 111*90c8c64dSAndroid Build Coastguard Worker case "$MERGETOOL" in 112*90c8c64dSAndroid Build Coastguard Worker bc* | vim*) 113*90c8c64dSAndroid Build Coastguard Worker TRUST_EXIT_CODE=true 114*90c8c64dSAndroid Build Coastguard Worker ;; 115*90c8c64dSAndroid Build Coastguard Worker esac 116*90c8c64dSAndroid Build Coastguard Workerfi 117*90c8c64dSAndroid Build Coastguard Worker 118*90c8c64dSAndroid Build Coastguard Workerreadonly MERGETOOL 119*90c8c64dSAndroid Build Coastguard Workerreadonly TRUST_EXIT_CODE 120*90c8c64dSAndroid Build Coastguard Worker 121*90c8c64dSAndroid Build Coastguard WorkerFILES_UNFILTERED=() 122*90c8c64dSAndroid Build Coastguard Workerif [[ "${#}" -eq 0 ]]; then 123*90c8c64dSAndroid Build Coastguard Worker while IFS= read -r -d '' ARG; do 124*90c8c64dSAndroid Build Coastguard Worker FILES_UNFILTERED+=("$ARG") 125*90c8c64dSAndroid Build Coastguard Worker done < <(git -c grep.fallbackToNoIndex=true grep -zlE "$CONFLICT_MARKER_BEGIN" 2>/dev/null) 126*90c8c64dSAndroid Build Coastguard Workerelse 127*90c8c64dSAndroid Build Coastguard Worker FILES_UNFILTERED+=("${@}") 128*90c8c64dSAndroid Build Coastguard Workerfi 129*90c8c64dSAndroid Build Coastguard Worker 130*90c8c64dSAndroid Build Coastguard WorkerFILES=() 131*90c8c64dSAndroid Build Coastguard Workerfor file in "${FILES_UNFILTERED[@]}"; do 132*90c8c64dSAndroid Build Coastguard Worker if ! [[ -f "$file" ]] || [[ -L "$file" ]]; then 133*90c8c64dSAndroid Build Coastguard Worker echo "[SKIPPED] ${file}: not a regular file" 134*90c8c64dSAndroid Build Coastguard Worker elif ! grep -qE "$CONFLICT_MARKER_BEGIN" "$file"; then 135*90c8c64dSAndroid Build Coastguard Worker echo "[SKIPPED] ${file}: no conflict markers found" 136*90c8c64dSAndroid Build Coastguard Worker else 137*90c8c64dSAndroid Build Coastguard Worker FILES+=("$file") 138*90c8c64dSAndroid Build Coastguard Worker fi 139*90c8c64dSAndroid Build Coastguard Workerdone 140*90c8c64dSAndroid Build Coastguard Worker 141*90c8c64dSAndroid Build Coastguard Workerecho "Found files with conflict markers:" 142*90c8c64dSAndroid Build Coastguard Workerprintf ' %s\n' "${FILES[@]}" 143*90c8c64dSAndroid Build Coastguard Worker 144*90c8c64dSAndroid Build Coastguard Workerfor file in "${FILES[@]}"; do 145*90c8c64dSAndroid Build Coastguard Worker echo 146*90c8c64dSAndroid Build Coastguard Worker echo "Merging '${file}'" 147*90c8c64dSAndroid Build Coastguard Worker 148*90c8c64dSAndroid Build Coastguard Worker mergetool "$file" 149*90c8c64dSAndroid Build Coastguard Worker exit_code="$?" 150*90c8c64dSAndroid Build Coastguard Worker if [[ "$exit_code" -ne 0 ]]; then 151*90c8c64dSAndroid Build Coastguard Worker echo "Failed to merge '${file}'" 152*90c8c64dSAndroid Build Coastguard Worker fi 153*90c8c64dSAndroid Build Coastguard Worker 154*90c8c64dSAndroid Build Coastguard Worker if $TRUST_EXIT_CODE && [[ "$exit_code" -eq 0 ]]; then 155*90c8c64dSAndroid Build Coastguard Worker if [[ -n "$(git ls-files "$file")" ]]; then 156*90c8c64dSAndroid Build Coastguard Worker xtrace git add "$file" 157*90c8c64dSAndroid Build Coastguard Worker fi 158*90c8c64dSAndroid Build Coastguard Worker continue 159*90c8c64dSAndroid Build Coastguard Worker fi 160*90c8c64dSAndroid Build Coastguard Worker read -r -p "Continue merging other files? [Y/n]" -n 1 yn || exit 161*90c8c64dSAndroid Build Coastguard Worker echo 162*90c8c64dSAndroid Build Coastguard Worker [[ "$yn" == [nNqQ] ]] && exit "$exit_code" 163*90c8c64dSAndroid Build Coastguard Workerdone 164*90c8c64dSAndroid Build Coastguard Worker 165*90c8c64dSAndroid Build Coastguard Workerexit 0 166