Migrating mercurial to git

Question: Can we merge a mercurial repository into existing git repository without losing history? For the migration of a mercurial to a git repository not much can be found. The are only a few different methods. I found a url where several migration paths to git have been defined (see url).

Tip

Within the following steps repository A will be migrated from a mercurial to a git repository. It is wiste to create a temporary directory in which the mercurial repository will be cloned and migrated to a git repository.

Note

Most of the steps below are shown from a script used to execute the migration of a mercurial repository to a git repository, see migrate_mercurial_to_git. For the execution of the script the url of the mercurial repository needs to be provided as an argument.

usage() {
   echo "migrate_mercurial_to_git <url mercurial repo>"
   echo ""
}

Steps

Needed tooling for migration:

Clone tooling repository:

mkdir -p $MIGRATE_PATH
cd $MIGRATE_PATH
git clone https://github.com/frej/fast-export.git
cd fast-export
git checkout v180317

Tip

During the first attempts I was getting some errors (unexpected “(” in hg-fast-export.sh, hg-fast-export.py cannot import name revsymbol). Eventually found the resolution to checkout a specific version of the tool.

Mercurial repository:

Clone the mercurial repository into temporary name hg_repo and collect committing users:

cd ..
hg clone $1 $HG_REPO
hg log | grep user: | sort | uniq | sed 's/user: *//' > $AUTHORS_FILE

Fix the authors file to reflect the correct syntax for users in git:

Note

Example for fixing the authors file:
”bob”=”Bob Jones <bob@company.com>”
bob@localhost”=”Bob Jones <bob@company.com>”
”bob <bob@company.com>”=”Bob Jones <bob@company.com>”
”bob jones <bob <AT> company <DOT> com>”=”Bob Jones <bob@company.com>”

Create initial git repository and migrate mercurial repository to this:

git init $CONVERTED_PATH
cd $CONVERTED_PATH
$MIGRATE_PATH/fast-export/hg-fast-export.sh -r $HG_REPO_PATH -A $AUTHORS_FILE
git checkout HEAD

Note

Any next steps depend on what should be the actual result. If this is a new git repository the appropriate action for this need to be executed. In our case it had to be merged into an existing git repository. For that already a procedure has been created (Merging Repositories). This only needs to be adapted since repository A does not need to be cloned. For repository A the location <tmp_dir>/converted can be used.