#!/bin/sh

set -eu

usage () {
  echo "$0 [--commit | --rewrite] <repository url>..."
}

move=commit
while [ $# -ne 0 ]
do
  case "$1" in
  -h|--help)
    usage
    exit
    ;;
  --commit)
    move=commit
    ;;
  --rewrite)
    move=rewrite
    ;;
  -*)
    echo "Invalid argument: $1" >&2
    usage >&2
    exit 1
    ;;
  *)
    break
    ;;
  esac
  shift
done

# Create a commit in branch <package>/master moving all files in <path>.
move_commit () {
  local head
  head=$(git symbolic-ref HEAD)

  git symbolic-ref HEAD "refs/heads/$1/master"

  rm -f "$(git rev-parse --git-path index)"
  git read-tree --prefix="$2/" HEAD
  git commit -nm "feat($1): move all files to $2"

  git symbolic-ref HEAD "$head"
  git read-tree HEAD
}

# Rewrite all branches <package>/* moving all files in <path>.
move_rewrite () {
  git filter-branch -f --index-filter '
    git ls-files -s | \
      sed "s%\t\"*%&'"$2"'/%" | \
      GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
      git update-index --index-info && \
      if [ -f "$GIT_INDEX_FILE.new" ]; then \
        mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; \
      fi
  ' --tag-name-filter 'cat' -- --branches="$1/*"
}

for url
do
  pkg=$(basename "$url" .git)
  if [ -d "packages/$pkg" ]
  then
    continue
  fi

  # import all branches and tags as <repository>/*
  git remote add "$pkg" "$url"
  git fetch --no-tags "$pkg" \
    "refs/heads/*:refs/heads/$pkg/*" \
    "refs/tags/*:refs/tags/$pkg/*"
  git remote rm "$pkg"

  move_"$move" "$pkg" "packages/$pkg"

  # merge and delete master branch
  git merge --allow-unrelated-histories "$pkg/master"
  git branch -d "$pkg/master"
done
