12 Commits

Author SHA1 Message Date
ceqi
19aa906308 Update usage section example commands
Change <repo> to <local-repo> so that it's clear that we invoke from a local repository;
Add 'git checkout HEAD' command as we need to run it as the final step.

Thanks
2018-02-13 13:37:58 +00:00
Frej Drejhammar
50dc10770b Warn contributors from doing work that will no be merged
From time to time contributors spend time doing work that will not be
accepted as it duplicates functionality that is already provided with
the mapping files. Try to dissuade them from doing that by explaining
the reasons in the comment.
2018-02-01 07:03:03 +01:00
Martin Freund
90483e02e5 Quote $PYTHON variable to support paths with spaces 2018-01-24 11:43:22 +01:00
Frej Drejhammar
cc8fefe008 Change syntax of mapping files
This is done to allow escape sequences in the key and value strings.
2017-10-02 13:05:14 +02:00
Frej Drejhammar
e174c2a0b7 Refactor load_mapping() to move line parsing to inner function
This is done in preparation to allowing mappings to contain quoted
characters.
2017-09-29 18:50:41 +02:00
Frej Drejhammar
2536f87544 Avoid nuisance error printout from readlink test
2>&1 > /dev/null does not do what I expected, > /dev/null 2>&1 does.
2017-08-25 11:28:52 +02:00
Frej Drejhammar
17c8a22066 Don't break if the destination directory name contains a space 2017-08-18 16:19:27 +02:00
Frej Drejhammar
7aa82e8234 Eliminate bashism
'>&' is apparently a bashism, change '>& /dev/null' to '2>&1 > /dev/null'.

Problem reported by KatolaZ <katolaz@freaknet.org>.

Resolves #99 and closes #100.
2017-06-24 11:58:36 +02:00
Frej Drejhammar
02bb982dd9 Behave nicely when the found readlink does not understand '-f'
Instead of just crashing when the found readlink does not understand
'-f', fall back to the pre ac887f310f
behaviour and print an error message if we fail to find
hg-fast-export.py.
2017-06-05 18:41:44 +02:00
Frej Drejhammar
c252e6748e documentation: Point users to the issue tracker for support questions 2017-06-02 16:18:43 +02:00
Felix Althaus
ac887f310f Make hg-fst-export.sh callable via a symbolic link
Calling hg-fast-export.sh via a symlink used to fail because the
script would look for hg-fast-export.py in the symlink‘s
directory. This patch adds symlink resolution using greadlink with a
fallback to readlink in order to support MacOS. That way you can
safely add a symlink to hg-fast-export.sh somewhere in you PATH.

Fixes https://github.com/frej/fast-export/issues/93
2017-06-02 16:13:20 +02:00
Frej Drejhammar
4bb50bb3fb Fix crash when a branch name starts with '/'
If a branch name starts with '/' it will be split into ['', ...] and
then mapped over with dot(), only dot() does not handle the empty
string. Teach dot() to handle the empty string.

This fixes the underlying problem in issue #91.
2017-05-14 14:32:59 +02:00
3 changed files with 78 additions and 18 deletions

View File

@@ -12,6 +12,18 @@ copies some code from the mercurial sources.
The current maintainer is Frej Drejhammar <frej.drejhammar@gmail.com>.
Support
-------
If you have problems with hg-fast-export or have found a bug, please
create an issue at the [github issue tracker]
(https://github.com/frej/fast-export/issues). Before creating a new
issue, check that your problem has not already been addressed in an
already closed issue. Do not contact the maintainer directly unless
you want to report a security bug. That way the next person having the
same problem can benefit from the time spent solving the problem the
first time.
Usage
-----
@@ -21,7 +33,8 @@ Using hg-fast-export is quite simple for a mercurial repository <repo>:
mkdir repo-git # or whatever
cd repo-git
git init
hg-fast-export.sh -r <repo>
hg-fast-export.sh -r <local-repo>
git checkout HEAD
```
Please note that hg-fast-export does not automatically check out the
@@ -53,12 +66,18 @@ As mercurial appears to be much less picky about the syntax of the
author information than git, an author mapping file can be given to
hg-fast-export to fix up malformed author strings. The file is
specified using the -A option. The file should contain lines of the
form `FromAuthor=ToAuthor`. The example authors.map below will
translate `User <garbage<user@example.com>` to `User <user@example.com>`.
form `"<key>"="<value>"`. Inside the key and value strings, all escape
sequences understood by the python `string_escape` encoding are
supported. (Versions of fast-export prior to v171002 had a different
syntax, the old syntax can be enabled by the flag
`--mappings-are-raw`.)
The example authors.map below will translate `User
<garbage<tab><user@example.com>` to `User <user@example.com>`.
```
-- Start of authors.map --
User <garbage<user@example.com>=User <user@example.com>
"User <garbage\t<user@example.com>"="User <user@example.com>"
-- End of authors.map --
```

View File

@@ -153,11 +153,16 @@ def sanitize_name(name,what="branch", mapping={}):
# modifying names which previously were not touched it will break
# preexisting setups which are doing incremental imports.
#
# Use the -B and -T options to mangle branch and tag names
# instead. If you have a source repository where this is too much
# work to do manually, write a tool that does it for you.
# Fast-export tries to not inflict arbitrary naming policy on the
# user, instead it aims to provide mechanisms allowing the user to
# apply their own policy. Therefore do not add a transform which can
# already be implemented with the -B and -T options to mangle branch
# and tag names. If you have a source repository where this is too
# much work to do manually, write a tool that does it for you.
#
def dot(name):
if not name: return name
if name[0] == '.': return '_'+name[1:]
return name
@@ -293,7 +298,24 @@ def export_tags(ui,repo,old_marks,mapping_cache,count,authors,tagsmap):
count=checkpoint(count)
return count
def load_mapping(name, filename):
def load_mapping(name, filename, mapping_is_raw):
raw_regexp=re.compile('^([^=]+)[ ]*=[ ]*(.+)$')
string_regexp='"(((\\.)|(\\")|[^"])*)"'
quoted_regexp=re.compile('^'+string_regexp+'[ ]*=[ ]*'+string_regexp+'$')
def parse_raw_line(line):
m=raw_regexp.match(line)
if m==None:
return None
return (m.group(1).strip(), m.group(2).strip())
def parse_quoted_line(line):
m=quoted_regexp.match(line)
if m==None:
return None
return (m.group(1).decode('string_escape'),
m.group(5).decode('string_escape'))
cache={}
if not os.path.exists(filename):
sys.stderr.write('Could not open mapping file [%s]\n' % (filename))
@@ -301,18 +323,19 @@ def load_mapping(name, filename):
f=open(filename,'r')
l=0
a=0
lre=re.compile('^([^=]+)[ ]*=[ ]*(.+)$')
for line in f.readlines():
l+=1
line=line.strip()
if line=='' or line[0]=='#':
if l==1 and line[0]=='#' and line=='# quoted-escaped-strings':
continue
m=lre.match(line)
elif line=='' or line[0]=='#':
continue
m=parse_raw_line(line) if mapping_is_raw else parse_quoted_line(line)
if m==None:
sys.stderr.write('Invalid file format in [%s], line %d\n' % (filename,l))
continue
# put key:value in cache, key without ^:
cache[m.group(1).strip()]=m.group(2).strip()
cache[m[0]]=m[1]
a+=1
f.close()
sys.stderr.write('Loaded %d %s\n' % (a, name))
@@ -459,6 +482,8 @@ if __name__=='__main__':
help="Assume commit and author strings retrieved from Mercurial are encoded in <encoding>")
parser.add_option("--fe",dest="fn_encoding",
help="Assume file names from Mercurial are encoded in <filename_encoding>")
parser.add_option("--mappings-are-raw",dest="raw_mappings", default=False,
help="Assume mappings are raw <key>=<value> lines")
(options,args)=parser.parse_args()
@@ -473,15 +498,15 @@ if __name__=='__main__':
a={}
if options.authorfile!=None:
a=load_mapping('authors', options.authorfile)
a=load_mapping('authors', options.authorfile, options.raw_mappings)
b={}
if options.branchesfile!=None:
b=load_mapping('branches', options.branchesfile)
b=load_mapping('branches', options.branchesfile, options.raw_mappings)
t={}
if options.tagsfile!=None:
t=load_mapping('tags', options.tagsfile)
t=load_mapping('tags', options.tagsfile, True)
if options.default_branch!=None:
set_default_branch(options.default_branch)

View File

@@ -3,7 +3,22 @@
# Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
ROOT="$(dirname "$(which "$0")")"
READLINK="readlink"
if command -v greadlink > /dev/null; then
READLINK="greadlink" # Prefer greadlink over readlink
fi
if ! $READLINK -f "$(which "$0")" > /dev/null 2>&1 ; then
ROOT="$(dirname "$(which "$0")")"
if [ ! -f "$ROOT/hg-fast-export.py" ] ; then
echo "hg-fast-exports requires a readlink implementation which knows" \
" how to canonicalize paths in order to be called via a symlink."
exit 1
fi
else
ROOT="$(dirname "$($READLINK -f "$(which "$0")")")"
fi
REPO=""
PFX="hg2git"
SFX_MAPPING="mapping"
@@ -40,6 +55,7 @@ Options:
Mercurial are encoded in <encoding>
--fe <filename_encoding> Assume filenames from Mercurial are encoded
in <filename_encoding>
--mappings-are-raw Assume mappings are raw <key>=<value> lines
"
case "$1" in
-h|--help)
@@ -55,7 +71,7 @@ if test "z$IS_BARE" != ztrue; then
# This is not a bare repo, cd to the toplevel
TOPLEVEL=$(git rev-parse --show-toplevel) \
|| (echo "Could not find git repo toplevel" ; exit 1)
cd $TOPLEVEL || exit 1
cd "$TOPLEVEL" || exit 1
fi
GIT_DIR=$(git rev-parse --git-dir) || (echo "Could not find git repo" ; exit 1)
@@ -137,7 +153,7 @@ $(
exec 4>&3 3>&1 1>&4 4>&-
{
_e1=0
GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-fast-export.py" \
GIT_DIR="$GIT_DIR" "$PYTHON" "$ROOT/hg-fast-export.py" \
--repo "$REPO" \
--marks "$GIT_DIR/$PFX-$SFX_MARKS" \
--mapping "$GIT_DIR/$PFX-$SFX_MAPPING" \