Skip to content

Instantly share code, notes, and snippets.

@d12frosted
Created July 8, 2020 11:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d12frosted/65e8c828910fca64da7d661e2a71b432 to your computer and use it in GitHub Desktop.
Save d12frosted/65e8c828910fca64da7d661e2a71b432 to your computer and use it in GitHub Desktop.
quick code migration from one repository to another
#!/usr/bin/env bash
#
# Requirements:
#
# 1. git >= 2.25
# 2. git-filter-repo
# 3. bash >= 4.0
#
# Installation:
#
# 1. Make a copy of this file
# 2. $ chmod +x migrate_git
#
# Usage:
#
# 1. Modify SOURCE, TARGET and DIRS_TO_MOVE according to your needs.
# 2. ./migrate_git
# 3. Chill
#
set -e
SOURCE="git@github.com:owner/repo.git"
TARGET="git@github.com:owner/repo.git"
declare -A DIRS_TO_MOVE
DIRS_TO_MOVE=(
["source/path/to/dir"]="target/path/to/dir"
)
source_remote="origin"
source_branch="master"
target_remote="target"
target_branch="master"
work_branch="__repo_migration"
################################################################################
echo "
Welcome to repository migration! Moving to new home is a very stressful
activity. I am here to help you make it easier and seamless!
Please note that I will not push to any of the repositories, as it's your
responsibility.
Roughly, here are steps I am going to perform:
1. Clone source repository.
2. Remove all commits not related to the files that must be moved.
3. Add target repository as additional remote and fetch it.
4. Rebase on top of target repository.
--------------------------------------------------------------------------------
"
echo "Moving
"
for s in "${!DIRS_TO_MOVE[@]}"; do
echo " - $s -> ${DIRS_TO_MOVE[$s]}"
done
echo "
from: $SOURCE
to: $TARGET
"
################################################################################
function check() {
command -v "$1" >/dev/null 2>&1
}
check git-filter-repo || {
echo "--------------------------------------------------------------------------------"
echo
echo "{•̃_•̃} Awww snap!"
echo
echo "git-filter-repo is required for this script to work!"
echo
echo "More info: https://github.com/newren/git-filter-repo"
echo " $ brew install git-filter-repo"
echo " # pacman -S git-filter-repo"
echo
exit 1
}
#
################################################################################
repo="repository"
if [ ! -d "$repo/.git" ]; then
rm -rf "$repo"
git clone "$SOURCE" "$repo"
fi
cd "$repo" && {
echo "fetch the latest changes from $SOURCE"
git fetch "$source_remote"
if [ "$(git rev-parse --abbrev-ref HEAD)" != "$work_branch" ]; then
git checkout -b "$work_branch" "$source_remote/$source_branch"
fi
git reset --hard "$source_remote/$source_branch"
args=""
for p in "${!DIRS_TO_MOVE[@]}"; do
args="--path $p/ $args"
done
# shellcheck disable=SC2086
git filter-repo --force $args
# rename rules
for s in "${!DIRS_TO_MOVE[@]}"; do
git filter-repo --path-rename "$s":"${DIRS_TO_MOVE[$s]}"
done
if ! git config "remote.$target_remote.url" > /dev/null; then
git remote add "$target_remote" "$TARGET"
fi
echo "fetch the latest changes from $TARGET"
git fetch "$target_remote"
git rebase "$target_remote/$target_branch"
echo "fix committer name and email"
export FILTER_BRANCH_SQUELCH_WARNING=1
git filter-branch --commit-filter 'export GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; git commit-tree "$@"' -- "$target_remote/$target_branch"..HEAD
}
echo "(⊃。•́‿•̀。)⊃"
echo " \\_done!"
echo
echo " verify repository at $repo"
echo " and push it using"
echo " $ git push $target_remote $work_branch"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment