hg2git/hg2git

92 lines
1.6 KiB
Bash
Executable File

#!/bin/bash
set -euo pipefail
fatal() {
echo "$@" >&2
exit 1
}
main() {
local target="$1"
# Validate target hg repo
if [[ ! -d $target/.hg ]] ; then
fatal "${1} not a hg repo"
fi
# Convert to absolute path
{
cd "$target"
target=$(pwd)
}
(
cd "$target"
if [[ $(hg status | wc -l) -ne 0 ]] ; then
fatal "${1}: uncommited files, abandoning"
fi
if hg id | fgrep -q '+' ; then
fatal "${1}: uncommitted changes, abandoning"
fi
# Create 'master' hg bookmark, if there isn't one already
if ! hg bookmark | fgrep master ; then
hg bookmark master
fi
)
# Use mercurial-git plugin to convert to bare repo in /tmp/
local gitdir=$(mktemp -d /tmp/hg2git.XXXXXXXX)
(
cd "$gitdir"
git init --bare
)
(
cd "$target"
hg push "$gitdir"
)
# Move into place
local backupdir="$target.hg-converted-$(date -Iseconds)"
mv "$target" "$backupdir"
mkdir -p "${target}"
mv "$gitdir/" "$target/.git"
# Reconstruct working directory
(
cd "$target"
git config --local --bool core.bare false
git checkout master
)
# Copy over excluded files from the working directory
# (add trailing slash to source path)
rsync -avr "${backupdir}/" "$target" --exclude=.git --exclude=.hg
(
cd "$target"
# Remove hgtags file
if [[ -f ./.hgtags ]] ; then
git rm ./.hgtags
git commit -m "hg-git: remove old .hgtags file"
fi
# Convert hgignore->gitignore (partial)
if [[ -f ./.hgignore ]] ; then
git mv .hgignore .gitignore
sed -i '/^mode:/d' .gitignore
# leave in uncommitted state for further fixups
fi
)
}
main "$@"