Created
May 17, 2018 02:42
-
-
Save brodygov/668bd6041610ac1426022d5b6f82b323 to your computer and use it in GitHub Desktop.
Mirror a git repository under an archival github user's account
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -eu | |
ARCHIVE_USER="${ARCHIVE_USER-my-archive-user}" | |
ssh_key="$HOME/.ssh/key.mirror-repo" | |
usage() { | |
cat >&2 <<EOM | |
usage: $(basename "$0") [options] SOURCE_REPO DEST_NAME | |
SOURCE_REPO: the source repository to copy just <ORG/REPO>, no host | |
DEST_NAME: the destination repository under $ARCHIVE_USER | |
Set \$ARCHIVE_USER to the user account where all the repos will be mirrored. | |
Repos will be cloned under repos/<DATE>/ and not removed afterwards | |
set DATE=YYYY-MM-DD to override the date used | |
Github repo creation expects a github.netrc file at repo root: | |
machine api.github.com login <ARCHIVE_USER> password <PASSWORD-OR-AUTH-TOKEN> | |
options: | |
--up: mirror up an existing repo | |
--no-up: skip upload step | |
--no-github-ssh: don't automatically use ssh for github.com | |
--no-create-repo: don't automatically create the repo | |
--ssh-key KEY: use KEY instead of default $ssh_key | |
example: | |
$(basename "$0") someorg/demo f025-someorg-demo | |
EOM | |
} | |
echo_red() { | |
echo -en '\033[1;31m' | |
echo -n "$*" | |
echo -e '\033[m' | |
} | |
echo_blue() { | |
echo -en '\033[1;34m' | |
echo -n "$*" | |
echo -e '\033[m' | |
} | |
run() { | |
echo >&2 "+ $*" | |
"$@" | |
} | |
netrc_file="$(dirname "$0")/../github.netrc" | |
upload= | |
skip_upload= | |
github_auto=1 | |
create_repo=1 | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
--up) | |
upload=1 | |
;; | |
--no-up) | |
skip_upload=1 | |
;; | |
--no-github-ssh) | |
github_auto= | |
;; | |
--no-create-repo) | |
create_repo= | |
;; | |
--ssh-key) | |
ssh_key="$2" | |
shift | |
;; | |
-*) | |
usage | |
echo >&2 "Unknown option: $1" | |
exit 2 | |
;; | |
*) | |
break | |
;; | |
esac | |
shift | |
done | |
if [ $# -lt 2 ]; then | |
usage | |
exit 1 | |
fi | |
src="$1" | |
dst="$2" | |
if [[ $src != *:* ]]; then | |
echo "Assuming $src is from github.com" | |
src="[email protected]:$src" | |
fi | |
orig_src="$1" | |
if [[ $github_auto ]]; then | |
if [[ $src == https://github.com/* ]]; then | |
echo "Rewriting $src to be SSH / [email protected]" | |
src="[email protected]:${src:19}" | |
echo "New URL: $src" | |
fi | |
if [[ $dst == https://github.com/$ARCHIVE_USER/* ]]; then | |
echo "Rewriting $dst to be just basename" | |
dst="$(basename "$dst")" | |
fi | |
fi | |
if [ ! -e "$ssh_key" ]; then | |
run ssh-keygen -t rsa -f "$ssh_key" | |
echo "Generated a new key in $ssh_key" | |
echo "Please add this key to the $ARCHIVE_USER account" | |
echo "https://github.com/settings/keys" | |
cat "$ssh_key" | |
exit 1 | |
fi | |
export GIT_SSH_COMMAND="ssh -o identitiesonly=yes -i $ssh_key" | |
echo_blue "Mirroring..." | |
echo_blue "from:" | |
echo_blue " - $src" | |
echo_blue "to:" | |
echo_blue " - https://github.com/$ARCHIVE_USER/$dst" | |
date="${DATE-$(date +%F)}" | |
cd "$(dirname "$0")/.." | |
mkdir -vp "repos/$date" | |
cd "repos/$date" | |
echo_blue "cloning into $PWD/$dst" | |
if [ -e "$dst" ]; then | |
if [ -n "$upload" ]; then | |
echo "$dst already exists, uploading" | |
else | |
echo "$dst already exists, aborting. Pass --up to use existing" | |
exit 3 | |
fi | |
else | |
run git clone --mirror "$src" "$dst" | |
fi | |
if [[ $skip_upload ]]; then | |
echo_blue "--no-up passed, not creating dst repo or uploading" | |
exit | |
fi | |
cd "$dst" | |
if [[ $create_repo ]]; then | |
echo_blue "Checking for dst repo existence" | |
if [ ! -e "$netrc_file" ]; then | |
echo >&2 "netrc file does not exist: $netrc_file" | |
echo >&2 "Pass --no-create-repo to skip github API operations" | |
exit 4 | |
fi | |
if run curl -sSf --netrc-file "$netrc_file" \ | |
"https://api.github.com/repos/$ARCHIVE_USER/$dst" >/dev/null | |
then | |
echo_blue "Repo already exists" | |
else | |
echo_blue "Creating target repo" | |
# create target repo | |
run curl -sSf --netrc-file "$netrc_file" -d '@-' \ | |
https://api.github.com/user/repos >/dev/null <<EOM | |
{"name":"$dst", "private":true, "description": "Mirror of $orig_src"} | |
EOM | |
sleep 1 | |
fi | |
else | |
echo_blue "Skipping repo creation" | |
fi | |
if ! run git remote get-url archive >/dev/null; then | |
run git remote add archive "[email protected]:$ARCHIVE_USER/$dst" | |
fi | |
run git push --mirror archive && ret=$? || ret=$? | |
echo_blue "Done." | |
echo_blue "https://github.com/$ARCHIVE_USER/$dst" | |
exit $ret |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment