3 # Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
4 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
6 ROOT
="$(dirname "$
(which "$0")")"
14 PYTHON
=${PYTHON:-python}
16 USAGE
="[--quiet] [-r <repo>] [--force] [-m <max>] [-s] [--hgtags] [-A <file>] [-B <file>] [-T <file>] [-M <name>] [-o <name>] [--hg-hash] [-e <encoding>]"
17 LONG_USAGE
="Import hg repository <repo> up to either tip or <max>
18 If <repo> is omitted, use last hg repository as obtained from state file,
19 GIT_DIR/$PFX-$SFX_STATE by default.
21 Note: The argument order matters.
24 --quiet Passed to git-fast-import(1)
25 -r <repo> Mercurial repository to import
26 --force Ignore validation errors when converting, and pass --force
28 -m <max> Maximum revision to import
29 -s Enable parsing Signed-off-by lines
30 --hgtags Enable exporting .hgtags files
31 -A <file> Read author map from file
32 (Same as in git-svnimport(1) and git-cvsimport(1))
33 -B <file> Read branch map from file
34 -T <file> Read tags map from file
35 -M <name> Set the default branch name (defaults to 'master')
36 -o <name> Use <name> as branch namespace to track upstream (eg 'origin')
37 --hg-hash Annotate commits with the hg hash as git notes in the
39 -e <encoding> Assume commit and author strings retrieved from
40 Mercurial are encoded in <encoding>
41 --fe <filename_encoding> Assume filenames from Mercurial are encoded
42 in <filename_encoding>
46 echo "usage: $(basename "$0") $USAGE"
52 IS_BARE
=$
(git rev-parse
--is-bare-repository) \
53 ||
(echo "Could not find git repo" ; exit 1)
54 if test "z$IS_BARE" != ztrue
; then
55 # This is not a bare repo, cd to the toplevel
56 TOPLEVEL
=$
(git rev-parse
--show-toplevel) \
57 ||
(echo "Could not find git repo toplevel" ; exit 1)
58 cd $TOPLEVEL ||
exit 1
60 GIT_DIR
=$
(git rev-parse
--git-dir) ||
(echo "Could not find git repo" ; exit 1)
64 IGNORECASE
=`git config core.ignoreCase`
65 if [ "true" = "$IGNORECASE" ]; then
70 while case "$#" in 0) break ;; esac
73 -r|
--r|
--re|
--rep|
--repo)
77 --q|
--qu|
--qui|
--quie|
--quiet)
78 GFI_OPTS
="$GFI_OPTS --quiet"
81 # pass --force to git-fast-import and hg-fast-export.py
82 GFI_OPTS
="$GFI_OPTS --force"
87 # pass any other options down to hg2git.py
97 if [ ! -z "$IGNORECASEWARN" ]; then
98 echo "Error: The option core.ignoreCase is set to true in the git"
99 echo "repository. This will produce empty changesets for renames that just"
100 echo "change the case of the file name."
101 echo "Use --force to skip this check or change the option with"
102 echo "git config core.ignoreCase false"
106 # Make a backup copy of each state file
107 for i
in $SFX_STATE $SFX_MARKS $SFX_MAPPING $SFX_HEADS ; do
108 if [ -f "$GIT_DIR/$PFX-$i" ] ; then
109 cp "$GIT_DIR/$PFX-$i" "$GIT_DIR/$PFX-$i~"
113 # for convenience: get default repo from state file
114 if [ x
"$REPO" = x
-a -f "$GIT_DIR/$PFX-$SFX_STATE" ] ; then
115 REPO
="`grep '^:repo ' "$GIT_DIR/$PFX-$SFX_STATE" | cut -d ' ' -f 2`"
116 echo "Using last hg repository \"$REPO\""
119 if [ -z "$REPO" ]; then
120 echo "no repo given, use -r flag"
124 # make sure we have a marks cache
125 if [ ! -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
126 touch "$GIT_DIR/$PFX-$SFX_MARKS"
130 trap 'rm -f "$GIT_DIR/$PFX-$SFX_MARKS.old" "$GIT_DIR/$PFX-$SFX_MARKS.tmp"' 0
135 { read -r _err1 ||
:; read -r _err2 ||
:; } <<-EOT
137 exec 4>&3 3>&1 1>&4 4>&-
140 GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-fast-export.py" \
142 --marks "$GIT_DIR/$PFX-$SFX_MARKS" \
143 --mapping "$GIT_DIR/$PFX-$SFX_MAPPING" \
144 --heads "$GIT_DIR/$PFX-$SFX_HEADS" \
145 --status "$GIT_DIR/$PFX-$SFX_STATE" \
151 git fast-import $GFI_OPTS --export-marks="$GIT_DIR/$PFX-$SFX_MARKS.tmp" 3>&- || _e2=$?
157 [ "$_err1" = 0 -a "$_err2" = 0 ] ||
exit 1
159 # move recent marks cache out of the way...
160 if [ -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
161 mv "$GIT_DIR/$PFX-$SFX_MARKS" "$GIT_DIR/$PFX-$SFX_MARKS.old"
163 touch "$GIT_DIR/$PFX-$SFX_MARKS.old"
166 # ...to create a new merged one
167 cat "$GIT_DIR/$PFX-$SFX_MARKS.old" "$GIT_DIR/$PFX-$SFX_MARKS.tmp" \
168 |
uniq > "$GIT_DIR/$PFX-$SFX_MARKS"
170 # save SHA1s of current heads for incremental imports
171 # and connectivity (plus sanity checking)
172 for head in `git branch | sed 's#^..##'` ; do
173 id
="`git rev-parse refs/heads/$head`"
175 done > "$GIT_DIR/$PFX-$SFX_HEADS"
177 # check diff with color:
178 # ( for i in `find . -type f | grep -v '\.git'` ; do diff -u $i $REPO/$i ; done | cdiff ) | less -r