commit 120f9950e644af869a202a0a05dd09e9d3df3065 Author: mappu Date: Sat Oct 6 15:46:58 2018 +1300 hg2git: initial commit diff --git a/hg2git b/hg2git new file mode 100755 index 0000000..a3f7333 --- /dev/null +++ b/hg2git @@ -0,0 +1,91 @@ +#!/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 "$@"