Merge branch 'fc/remote-hg'
Updates remote-hg helper (in contrib/). * fc/remote-hg: (21 commits) remote-hg: activate graphlog extension for hg_log() remote-hg: fix bad file paths remote-hg: document location of stored hg repository remote-hg: fix bad state issue remote-hg: add 'insecure' option remote-hg: add simple mail test remote-hg: add basic author tests remote-hg: show more proper errors remote-hg: force remote push remote-hg: push to the appropriate branch remote-hg: update tags globally remote-hg: update remote bookmarks remote-hg: refactor export remote-hg: split bookmark handling remote-hg: redirect buggy mercurial output remote-hg: trivial test cleanups remote-hg: make sure fake bookmarks are updated remote-hg: fix for files with spaces remote-hg: properly report errors on bookmark pushes remote-hg: add missing config variable in doc ...
This commit is contained in:
commit
37d32de72a
@ -8,8 +8,11 @@
|
|||||||
# Just copy to your ~/bin, or anywhere in your $PATH.
|
# Just copy to your ~/bin, or anywhere in your $PATH.
|
||||||
# Then you can clone with:
|
# Then you can clone with:
|
||||||
# git clone hg::/path/to/mercurial/repo/
|
# git clone hg::/path/to/mercurial/repo/
|
||||||
|
#
|
||||||
|
# For remote repositories a local clone is stored in
|
||||||
|
# "$GIT_DIR/hg/origin/clone/.hg/".
|
||||||
|
|
||||||
from mercurial import hg, ui, bookmarks, context, util, encoding
|
from mercurial import hg, ui, bookmarks, context, util, encoding, node, error
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
@ -18,11 +21,22 @@ import json
|
|||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import urllib
|
import urllib
|
||||||
|
import atexit
|
||||||
|
|
||||||
#
|
#
|
||||||
# If you want to switch to hg-git compatibility mode:
|
# If you want to switch to hg-git compatibility mode:
|
||||||
# git config --global remote-hg.hg-git-compat true
|
# git config --global remote-hg.hg-git-compat true
|
||||||
#
|
#
|
||||||
|
# If you are not in hg-git-compat mode and want to disable the tracking of
|
||||||
|
# named branches:
|
||||||
|
# git config --global remote-hg.track-branches false
|
||||||
|
#
|
||||||
|
# If you don't want to force pushes (and thus risk creating new remote heads):
|
||||||
|
# git config --global remote-hg.force-push false
|
||||||
|
#
|
||||||
|
# If you want the equivalent of hg's clone/pull--insecure option:
|
||||||
|
# git config remote-hg.insecure true
|
||||||
|
#
|
||||||
# git:
|
# git:
|
||||||
# Sensible defaults for git.
|
# Sensible defaults for git.
|
||||||
# hg bookmarks are exported as git branches, hg branches are prefixed
|
# hg bookmarks are exported as git branches, hg branches are prefixed
|
||||||
@ -56,6 +70,9 @@ def hgmode(mode):
|
|||||||
m = { '100755': 'x', '120000': 'l' }
|
m = { '100755': 'x', '120000': 'l' }
|
||||||
return m.get(mode, '')
|
return m.get(mode, '')
|
||||||
|
|
||||||
|
def hghex(node):
|
||||||
|
return hg.node.hex(node)
|
||||||
|
|
||||||
def get_config(config):
|
def get_config(config):
|
||||||
cmd = ['git', 'config', '--get', config]
|
cmd = ['git', 'config', '--get', config]
|
||||||
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
|
||||||
@ -188,9 +205,15 @@ class Parser:
|
|||||||
tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
|
tz = ((tz / 100) * 3600) + ((tz % 100) * 60)
|
||||||
return (user, int(date), -tz)
|
return (user, int(date), -tz)
|
||||||
|
|
||||||
|
def fix_file_path(path):
|
||||||
|
if not os.path.isabs(path):
|
||||||
|
return path
|
||||||
|
return os.path.relpath(path, '/')
|
||||||
|
|
||||||
def export_file(fc):
|
def export_file(fc):
|
||||||
d = fc.data()
|
d = fc.data()
|
||||||
print "M %s inline %s" % (gitmode(fc.flags()), fc.path())
|
path = fix_file_path(fc.path())
|
||||||
|
print "M %s inline %s" % (gitmode(fc.flags()), path)
|
||||||
print "data %d" % len(d)
|
print "data %d" % len(d)
|
||||||
print d
|
print d
|
||||||
|
|
||||||
@ -267,17 +290,30 @@ def get_repo(url, alias):
|
|||||||
|
|
||||||
myui = ui.ui()
|
myui = ui.ui()
|
||||||
myui.setconfig('ui', 'interactive', 'off')
|
myui.setconfig('ui', 'interactive', 'off')
|
||||||
|
myui.fout = sys.stderr
|
||||||
|
|
||||||
|
try:
|
||||||
|
if get_config('remote-hg.insecure') == 'true\n':
|
||||||
|
myui.setconfig('web', 'cacerts', '')
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
pass
|
||||||
|
|
||||||
if hg.islocal(url):
|
if hg.islocal(url):
|
||||||
repo = hg.repository(myui, url)
|
repo = hg.repository(myui, url)
|
||||||
else:
|
else:
|
||||||
local_path = os.path.join(dirname, 'clone')
|
local_path = os.path.join(dirname, 'clone')
|
||||||
if not os.path.exists(local_path):
|
if not os.path.exists(local_path):
|
||||||
peer, dstpeer = hg.clone(myui, {}, url, local_path, update=False, pull=True)
|
try:
|
||||||
|
peer, dstpeer = hg.clone(myui, {}, url, local_path, update=True, pull=True)
|
||||||
|
except:
|
||||||
|
die('Repository error')
|
||||||
repo = dstpeer.local()
|
repo = dstpeer.local()
|
||||||
else:
|
else:
|
||||||
repo = hg.repository(myui, local_path)
|
repo = hg.repository(myui, local_path)
|
||||||
peer = hg.peer(myui, {}, url)
|
try:
|
||||||
|
peer = hg.peer(myui, {}, url)
|
||||||
|
except:
|
||||||
|
die('Repository error')
|
||||||
repo.pull(peer, heads=None, force=True)
|
repo.pull(peer, heads=None, force=True)
|
||||||
|
|
||||||
return repo
|
return repo
|
||||||
@ -372,7 +408,7 @@ def export_ref(repo, name, kind, head):
|
|||||||
for f in modified:
|
for f in modified:
|
||||||
export_file(c.filectx(f))
|
export_file(c.filectx(f))
|
||||||
for f in removed:
|
for f in removed:
|
||||||
print "D %s" % (f)
|
print "D %s" % (fix_file_path(f))
|
||||||
print
|
print
|
||||||
|
|
||||||
count += 1
|
count += 1
|
||||||
@ -532,7 +568,6 @@ def parse_blob(parser):
|
|||||||
data = parser.get_data()
|
data = parser.get_data()
|
||||||
blob_marks[mark] = data
|
blob_marks[mark] = data
|
||||||
parser.next()
|
parser.next()
|
||||||
return
|
|
||||||
|
|
||||||
def get_merge_files(repo, p1, p2, files):
|
def get_merge_files(repo, p1, p2, files):
|
||||||
for e in repo[p1].files():
|
for e in repo[p1].files():
|
||||||
@ -543,7 +578,7 @@ def get_merge_files(repo, p1, p2, files):
|
|||||||
files[e] = f
|
files[e] = f
|
||||||
|
|
||||||
def parse_commit(parser):
|
def parse_commit(parser):
|
||||||
global marks, blob_marks, bmarks, parsed_refs
|
global marks, blob_marks, parsed_refs
|
||||||
global mode
|
global mode
|
||||||
|
|
||||||
from_mark = merge_mark = None
|
from_mark = merge_mark = None
|
||||||
@ -576,7 +611,7 @@ def parse_commit(parser):
|
|||||||
mark = int(mark_ref[1:])
|
mark = int(mark_ref[1:])
|
||||||
f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] }
|
f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] }
|
||||||
elif parser.check('D'):
|
elif parser.check('D'):
|
||||||
t, path = line.split(' ')
|
t, path = line.split(' ', 1)
|
||||||
f = { 'deleted' : True }
|
f = { 'deleted' : True }
|
||||||
else:
|
else:
|
||||||
die('Unknown file command: %s' % line)
|
die('Unknown file command: %s' % line)
|
||||||
@ -619,11 +654,15 @@ def parse_commit(parser):
|
|||||||
if merge_mark:
|
if merge_mark:
|
||||||
get_merge_files(repo, p1, p2, files)
|
get_merge_files(repo, p1, p2, files)
|
||||||
|
|
||||||
|
# Check if the ref is supposed to be a named branch
|
||||||
|
if ref.startswith('refs/heads/branches/'):
|
||||||
|
extra['branch'] = ref[len('refs/heads/branches/'):]
|
||||||
|
|
||||||
if mode == 'hg':
|
if mode == 'hg':
|
||||||
i = data.find('\n--HG--\n')
|
i = data.find('\n--HG--\n')
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
tmp = data[i + len('\n--HG--\n'):].strip()
|
tmp = data[i + len('\n--HG--\n'):].strip()
|
||||||
for k, v in [e.split(' : ') for e in tmp.split('\n')]:
|
for k, v in [e.split(' : ', 1) for e in tmp.split('\n')]:
|
||||||
if k == 'rename':
|
if k == 'rename':
|
||||||
old, new = v.split(' => ', 1)
|
old, new = v.split(' => ', 1)
|
||||||
files[new]['rename'] = old
|
files[new]['rename'] = old
|
||||||
@ -648,10 +687,11 @@ def parse_commit(parser):
|
|||||||
rev = repo[node].rev()
|
rev = repo[node].rev()
|
||||||
|
|
||||||
parsed_refs[ref] = node
|
parsed_refs[ref] = node
|
||||||
|
|
||||||
marks.new_mark(rev, commit_mark)
|
marks.new_mark(rev, commit_mark)
|
||||||
|
|
||||||
def parse_reset(parser):
|
def parse_reset(parser):
|
||||||
|
global parsed_refs
|
||||||
|
|
||||||
ref = parser[1]
|
ref = parser[1]
|
||||||
parser.next()
|
parser.next()
|
||||||
# ugh
|
# ugh
|
||||||
@ -681,6 +721,8 @@ def parse_tag(parser):
|
|||||||
def do_export(parser):
|
def do_export(parser):
|
||||||
global parsed_refs, bmarks, peer
|
global parsed_refs, bmarks, peer
|
||||||
|
|
||||||
|
p_bmarks = []
|
||||||
|
|
||||||
parser.next()
|
parser.next()
|
||||||
|
|
||||||
for line in parser.each_block('done'):
|
for line in parser.each_block('done'):
|
||||||
@ -699,28 +741,55 @@ def do_export(parser):
|
|||||||
|
|
||||||
for ref, node in parsed_refs.iteritems():
|
for ref, node in parsed_refs.iteritems():
|
||||||
if ref.startswith('refs/heads/branches'):
|
if ref.startswith('refs/heads/branches'):
|
||||||
pass
|
print "ok %s" % ref
|
||||||
elif ref.startswith('refs/heads/'):
|
elif ref.startswith('refs/heads/'):
|
||||||
bmark = ref[len('refs/heads/'):]
|
bmark = ref[len('refs/heads/'):]
|
||||||
if bmark in bmarks:
|
p_bmarks.append((bmark, node))
|
||||||
old = bmarks[bmark].hex()
|
continue
|
||||||
else:
|
|
||||||
old = ''
|
|
||||||
if not bookmarks.pushbookmark(parser.repo, bmark, old, node):
|
|
||||||
continue
|
|
||||||
elif ref.startswith('refs/tags/'):
|
elif ref.startswith('refs/tags/'):
|
||||||
tag = ref[len('refs/tags/'):]
|
tag = ref[len('refs/tags/'):]
|
||||||
parser.repo.tag([tag], node, None, True, None, {})
|
if mode == 'git':
|
||||||
|
msg = 'Added tag %s for changeset %s' % (tag, hghex(node[:6]));
|
||||||
|
parser.repo.tag([tag], node, msg, False, None, {})
|
||||||
|
else:
|
||||||
|
parser.repo.tag([tag], node, None, True, None, {})
|
||||||
|
print "ok %s" % ref
|
||||||
else:
|
else:
|
||||||
# transport-helper/fast-export bugs
|
# transport-helper/fast-export bugs
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
if peer:
|
||||||
|
parser.repo.push(peer, force=force_push)
|
||||||
|
|
||||||
|
# handle bookmarks
|
||||||
|
for bmark, node in p_bmarks:
|
||||||
|
ref = 'refs/heads/' + bmark
|
||||||
|
new = hghex(node)
|
||||||
|
|
||||||
|
if bmark in bmarks:
|
||||||
|
old = bmarks[bmark].hex()
|
||||||
|
else:
|
||||||
|
old = ''
|
||||||
|
|
||||||
|
if bmark == 'master' and 'master' not in parser.repo._bookmarks:
|
||||||
|
# fake bookmark
|
||||||
|
pass
|
||||||
|
elif bookmarks.pushbookmark(parser.repo, bmark, old, new):
|
||||||
|
# updated locally
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print "error %s" % ref
|
||||||
|
continue
|
||||||
|
|
||||||
|
if peer:
|
||||||
|
if not peer.pushkey('bookmarks', bmark, old, new):
|
||||||
|
print "error %s" % ref
|
||||||
|
continue
|
||||||
|
|
||||||
print "ok %s" % ref
|
print "ok %s" % ref
|
||||||
|
|
||||||
print
|
print
|
||||||
|
|
||||||
if peer:
|
|
||||||
parser.repo.push(peer, force=False)
|
|
||||||
|
|
||||||
def fix_path(alias, repo, orig_url):
|
def fix_path(alias, repo, orig_url):
|
||||||
repo_url = util.url(repo.url())
|
repo_url = util.url(repo.url())
|
||||||
url = util.url(orig_url)
|
url = util.url(orig_url)
|
||||||
@ -733,7 +802,7 @@ def main(args):
|
|||||||
global prefix, dirname, branches, bmarks
|
global prefix, dirname, branches, bmarks
|
||||||
global marks, blob_marks, parsed_refs
|
global marks, blob_marks, parsed_refs
|
||||||
global peer, mode, bad_mail, bad_name
|
global peer, mode, bad_mail, bad_name
|
||||||
global track_branches
|
global track_branches, force_push, is_tmp
|
||||||
|
|
||||||
alias = args[1]
|
alias = args[1]
|
||||||
url = args[2]
|
url = args[2]
|
||||||
@ -741,12 +810,16 @@ def main(args):
|
|||||||
|
|
||||||
hg_git_compat = False
|
hg_git_compat = False
|
||||||
track_branches = True
|
track_branches = True
|
||||||
|
force_push = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if get_config('remote-hg.hg-git-compat') == 'true\n':
|
if get_config('remote-hg.hg-git-compat') == 'true\n':
|
||||||
hg_git_compat = True
|
hg_git_compat = True
|
||||||
track_branches = False
|
track_branches = False
|
||||||
if get_config('remote-hg.track-branches') == 'false\n':
|
if get_config('remote-hg.track-branches') == 'false\n':
|
||||||
track_branches = False
|
track_branches = False
|
||||||
|
if get_config('remote-hg.force-push') == 'false\n':
|
||||||
|
force_push = False
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -771,6 +844,7 @@ def main(args):
|
|||||||
bmarks = {}
|
bmarks = {}
|
||||||
blob_marks = {}
|
blob_marks = {}
|
||||||
parsed_refs = {}
|
parsed_refs = {}
|
||||||
|
marks = None
|
||||||
|
|
||||||
repo = get_repo(url, alias)
|
repo = get_repo(url, alias)
|
||||||
prefix = 'refs/hg/%s' % alias
|
prefix = 'refs/hg/%s' % alias
|
||||||
@ -798,9 +872,13 @@ def main(args):
|
|||||||
die('unhandled command: %s' % line)
|
die('unhandled command: %s' % line)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
def bye():
|
||||||
|
if not marks:
|
||||||
|
return
|
||||||
if not is_tmp:
|
if not is_tmp:
|
||||||
marks.store()
|
marks.store()
|
||||||
else:
|
else:
|
||||||
shutil.rmtree(dirname)
|
shutil.rmtree(dirname)
|
||||||
|
|
||||||
|
atexit.register(bye)
|
||||||
sys.exit(main(sys.argv))
|
sys.exit(main(sys.argv))
|
||||||
|
@ -22,7 +22,6 @@ fi
|
|||||||
|
|
||||||
# clone to a git repo
|
# clone to a git repo
|
||||||
git_clone () {
|
git_clone () {
|
||||||
hg -R $1 bookmark -f -r tip master &&
|
|
||||||
git clone -q "hg::$PWD/$1" $2
|
git clone -q "hg::$PWD/$1" $2
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,6 +29,7 @@ git_clone () {
|
|||||||
hg_clone () {
|
hg_clone () {
|
||||||
(
|
(
|
||||||
hg init $2 &&
|
hg init $2 &&
|
||||||
|
hg -R $2 bookmark -i master &&
|
||||||
cd $1 &&
|
cd $1 &&
|
||||||
git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
|
git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
|
||||||
) &&
|
) &&
|
||||||
@ -50,7 +50,8 @@ hg_push () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hg_log () {
|
hg_log () {
|
||||||
hg -R $1 log --graph --debug | grep -v 'tag: *default/'
|
hg -R $1 log --graph --debug >log &&
|
||||||
|
grep -v 'tag: *default/' log
|
||||||
}
|
}
|
||||||
|
|
||||||
setup () {
|
setup () {
|
||||||
@ -62,6 +63,8 @@ setup () {
|
|||||||
echo "commit = -d \"0 0\""
|
echo "commit = -d \"0 0\""
|
||||||
echo "debugrawcommit = -d \"0 0\""
|
echo "debugrawcommit = -d \"0 0\""
|
||||||
echo "tag = -d \"0 0\""
|
echo "tag = -d \"0 0\""
|
||||||
|
echo "[extensions]"
|
||||||
|
echo "graphlog ="
|
||||||
) >> "$HOME"/.hgrc &&
|
) >> "$HOME"/.hgrc &&
|
||||||
git config --global remote-hg.hg-git-compat true
|
git config --global remote-hg.hg-git-compat true
|
||||||
|
|
||||||
@ -200,8 +203,8 @@ test_expect_success 'hg branch' '
|
|||||||
hg_push hgrepo gitrepo &&
|
hg_push hgrepo gitrepo &&
|
||||||
hg_clone gitrepo hgrepo2 &&
|
hg_clone gitrepo hgrepo2 &&
|
||||||
|
|
||||||
: TODO, avoid "master" bookmark &&
|
: Back to the common revision &&
|
||||||
(cd hgrepo2 && hg checkout gamma) &&
|
(cd hgrepo && hg checkout default) &&
|
||||||
|
|
||||||
hg_log hgrepo > expected &&
|
hg_log hgrepo > expected &&
|
||||||
hg_log hgrepo2 > actual &&
|
hg_log hgrepo2 > actual &&
|
||||||
|
@ -27,7 +27,6 @@ fi
|
|||||||
|
|
||||||
# clone to a git repo with git
|
# clone to a git repo with git
|
||||||
git_clone_git () {
|
git_clone_git () {
|
||||||
hg -R $1 bookmark -f -r tip master &&
|
|
||||||
git clone -q "hg::$PWD/$1" $2
|
git clone -q "hg::$PWD/$1" $2
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,6 +34,7 @@ git_clone_git () {
|
|||||||
hg_clone_git () {
|
hg_clone_git () {
|
||||||
(
|
(
|
||||||
hg init $2 &&
|
hg init $2 &&
|
||||||
|
hg -R $2 bookmark -i master &&
|
||||||
cd $1 &&
|
cd $1 &&
|
||||||
git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
|
git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*'
|
||||||
) &&
|
) &&
|
||||||
@ -47,7 +47,7 @@ git_clone_hg () {
|
|||||||
(
|
(
|
||||||
git init -q $2 &&
|
git init -q $2 &&
|
||||||
cd $1 &&
|
cd $1 &&
|
||||||
hg bookmark -f -r tip master &&
|
hg bookmark -i -f -r tip master &&
|
||||||
hg -q push -r master ../$2 || true
|
hg -q push -r master ../$2 || true
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -78,7 +78,8 @@ hg_push_hg () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
hg_log () {
|
hg_log () {
|
||||||
hg -R $1 log --graph --debug | grep -v 'tag: *default/'
|
hg -R $1 log --graph --debug >log &&
|
||||||
|
grep -v 'tag: *default/' log
|
||||||
}
|
}
|
||||||
|
|
||||||
git_log () {
|
git_log () {
|
||||||
@ -97,6 +98,7 @@ setup () {
|
|||||||
echo "[extensions]"
|
echo "[extensions]"
|
||||||
echo "hgext.bookmarks ="
|
echo "hgext.bookmarks ="
|
||||||
echo "hggit ="
|
echo "hggit ="
|
||||||
|
echo "graphlog ="
|
||||||
) >> "$HOME"/.hgrc &&
|
) >> "$HOME"/.hgrc &&
|
||||||
git config --global receive.denycurrentbranch warn
|
git config --global receive.denycurrentbranch warn
|
||||||
git config --global remote-hg.hg-git-compat true
|
git config --global remote-hg.hg-git-compat true
|
||||||
|
@ -118,4 +118,40 @@ test_expect_success 'update bookmark' '
|
|||||||
hg -R hgrepo bookmarks | egrep "devel[ ]+3:"
|
hg -R hgrepo bookmarks | egrep "devel[ ]+3:"
|
||||||
'
|
'
|
||||||
|
|
||||||
|
author_test () {
|
||||||
|
echo $1 >> content &&
|
||||||
|
hg commit -u "$2" -m "add $1" &&
|
||||||
|
echo "$3" >> ../expected
|
||||||
|
}
|
||||||
|
|
||||||
|
test_expect_success 'authors' '
|
||||||
|
mkdir -p tmp && cd tmp &&
|
||||||
|
test_when_finished "cd .. && rm -rf tmp" &&
|
||||||
|
|
||||||
|
(
|
||||||
|
hg init hgrepo &&
|
||||||
|
cd hgrepo &&
|
||||||
|
|
||||||
|
touch content &&
|
||||||
|
hg add content &&
|
||||||
|
|
||||||
|
author_test alpha "" "H G Wells <wells@example.com>" &&
|
||||||
|
author_test beta "test" "test <unknown>" &&
|
||||||
|
author_test beta "test <test@example.com> (comment)" "test <unknown>" &&
|
||||||
|
author_test gamma "<test@example.com>" "Unknown <test@example.com>" &&
|
||||||
|
author_test delta "name<test@example.com>" "name <test@example.com>" &&
|
||||||
|
author_test epsilon "name <test@example.com" "name <unknown>" &&
|
||||||
|
author_test zeta " test " "test <unknown>" &&
|
||||||
|
author_test eta "test < test@example.com >" "test <test@example.com>" &&
|
||||||
|
author_test theta "test >test@example.com>" "test <unknown>" &&
|
||||||
|
author_test iota "test < test <at> example <dot> com>" "test <unknown>" &&
|
||||||
|
author_test kappa "test@example.com" "test@example.com <unknown>"
|
||||||
|
) &&
|
||||||
|
|
||||||
|
git clone "hg::$PWD/hgrepo" gitrepo &&
|
||||||
|
git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" > actual &&
|
||||||
|
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_done
|
test_done
|
||||||
|
Loading…
x
Reference in New Issue
Block a user