#!/bin/bash

log() {
  echo -e "\e[0;32m$(date -Is) ===> $@\e[m"
}

# branch to fix
branch=${1}

# commit used to merge the initial formatting
formatting=${2}

# target branch of themerge request
upstream=${3}

if [ -z "${branch}" -o -z "${formatting}" ] ; then
  echo "usage: ${0} branch commit_with_reformatting [upstream]"
  exit 1
fi

# no-op (fake) editor
export GIT_EDITOR=true

# get the branch to fix and make sure there are no spurious conflicts
log "checking out $branch"
git checkout $branch
orig_commit=$(git rev-parse HEAD)
log "maps to commit $orig_commit"

log "rebase on ${formatting}~"
if ! git rebase ${formatting}~ ; then
   log "\e[0;31mERROR: rebase failed"
   exit 1
fi

# start rebasing (reformatting after each commit)
log "rebase on ${formatting}"
git rebase --exec 'git diff --diff-filter=MA --no-renames --name-only HEAD~ | xargs -r lb-format && git add -u && git commit --amend --no-edit' ${formatting}
if [ $? != 0 ] ; then
  log "fixing conflicts"
  # in case of conflict, get our version of the conflicting files...
  git status --porcelain | awk '/^U[UA]/{print $2}' | xargs -r git checkout REBASE_HEAD
  git status --porcelain | awk '/^UD/{print $2}' | xargs -r git rm 
  # ... then continue rebasing ...
  log "continue rebase"
  while ! git rebase --continue ; do
    # ... and repeat
    log "fixing conflicts"
    git status --porcelain | awk '/^U[UA]/{print $2}' | xargs -r git checkout REBASE_HEAD
    git status --porcelain | awk '/^UD/{print $2}' | xargs -r git rm 
    log "continue rebase"
  done
fi
log "rebase on ${formatting} completed"

if [ -n "${upstream}" ] ; then
  # after the rebase with only the reformatting, rebase on top of the actual target branch and make sure formatting is consistent
  log "rebase on ${upstream} (with reformatting at each step)"
  if git rebase --exec 'git diff --diff-filter=MA --no-renames --name-only HEAD~ | xargs -r lb-format && git add -u && git commit --amend --no-edit' ${upstream} ; then
    log "rebase on ${upstream} completed"
  else
    log "\e[0;31mERROR: final rebase failed"
    exit 1
  fi
fi

echo ""
echo "------------------------------------------------------------"
echo "Make sure everything is OK before pushing the changes"
echo "(original version: ${orig_commit})"
echo "------------------------------------------------------------"