Merge branch 'felipec'

Integrate changes from felipec where appropriate and still relevant.
This commit is contained in:
Mark Nauwelaerts
2025-05-01 20:18:03 +02:00
35 changed files with 1705 additions and 713 deletions

25
.github/workflows/ci.yml vendored Normal file
View File

@@ -0,0 +1,25 @@
name: CI
on:
push:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
hg: [ '6.0', '6.1', '6.2', '6.3', '6.4', '6.5', '6.6', '6.7', '6.8', '6.9' ]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.10'
- uses: actions/cache@v3
id: cache-pip
with:
path: ~/.cache/pip
key: pip
- name: Install hg
run:
pip install mercurial==${{ matrix.hg }}
- run: make test

View File

@@ -1,20 +0,0 @@
dist: xenial
language: minimal
cache:
directories:
- $HOME/.cache/git-remote-hg
script:
- ./tools/check-versions hg:$HG_VERSION
matrix:
include:
- env:
- env: HG_VERSION=@
- env: HG_VERSION=5.0
- env: HG_VERSION=4.9
- env: HG_VERSION=4.8
- env: HG_VERSION=4.7
- env: HG_VERSION=4.6
- env: HG_VERSION=4.5

View File

@@ -1,4 +1,4 @@
'git-remote-hg' is the semi-official Mercurial bridge from Git project, once
`git-remote-hg` is the semi-official Mercurial bridge from the Git project, once
installed, it allows you to clone, fetch and push to and from Mercurial
repositories as if they were Git ones:
@@ -6,10 +6,10 @@ repositories as if they were Git ones:
git clone "hg::http://selenic.com/repo/hello"
--------------------------------------
To enable this, simply add the 'git-remote-hg' script anywhere in your `$PATH`:
To enable this, simply add the `git-remote-hg` script anywhere in your `$PATH`:
--------------------------------------
wget https://raw.github.com/mnauw/git-remote-hg/master/git-remote-hg -O ~/bin/git-remote-hg
wget https://raw.githubusercontent.com/mnauw/git-remote-hg/master/git-remote-hg -O ~/bin/git-remote-hg
chmod +x ~/bin/git-remote-hg
--------------------------------------
@@ -49,7 +49,8 @@ If you want to see Mercurial revisions as Git commit notes:
% git config core.notesRef refs/notes/hg
--------------------------------------
If you are not interested in Mercurial permanent and global branches (aka. commit labels):
If you are not interested in Mercurial permanent and global branches (aka.
commit labels):
--------------------------------------
% git config --global remote-hg.track-branches false
@@ -57,13 +58,14 @@ If you are not interested in Mercurial permanent and global branches (aka. commi
With this configuration, the 'branches/foo' refs won't appear.
If you want the equivalent of 'hg clone --insecure':
If you want the equivalent of `hg clone --insecure`:
--------------------------------------
% git config --global remote-hg.insecure true
--------------------------------------
If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly the same commits:
If you want `git-remote-hg` to be compatible with `hg-git`, and generate exactly
the same commits:
--------------------------------------
% git config --global remote-hg.hg-git-compat true
@@ -71,15 +73,14 @@ If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly
== Notes ==
Remember to run `git gc --aggressive` after cloning a repository, specially if
Remember to run `git gc --aggressive` after cloning a repository, especially if
it's a big one. Otherwise lots of space will be wasted.
The oldest version of mercurial supported is 1.9. For the most part 1.8 works,
but you might experience some issues.
The newest supported version of Mercurial is 6.2, the oldest one is 2.4.
=== Pushing branches ===
To push a branch, you need to use the "branches/" prefix:
To push a branch, you need to use the 'branches/' prefix:
--------------------------------------
% git checkout branches/next
@@ -89,7 +90,7 @@ To push a branch, you need to use the "branches/" prefix:
All the pushed commits will receive the "next" Mercurial named branch.
*Note*: Make sure you don't have +remote-hg.track-branches+ disabled.
*Note*: Make sure you don't have `remote-hg.track-branches` disabled.
=== Cloning HTTPS ===
@@ -99,7 +100,7 @@ The simplest way is to specify the user and password in the URL:
git clone hg::https://user:password@bitbucket.org/user/repo
--------------------------------------
You can also use the http://mercurial.selenic.com/wiki/SchemesExtension[schemes extension]:
You can also use the https://mercurial-scm.org/wiki/SchemesExtension[schemes extension]:
--------------------------------------
[auth]
@@ -109,11 +110,7 @@ bb.password = password
--------------------------------------
Finally, you can also use the
https://pypi.python.org/pypi/mercurial_keyring[keyring extension].
However, some of these features require very new versions of 'git-remote-hg',
so you might have better luck simply specifying the username and password in
the URL.
https://pypi.org/project/mercurial_keyring[keyring extension].
=== Submodules ===
@@ -141,10 +138,10 @@ Mercurial branches and bookmarks have some limitations of Git branches: you
can't have both 'dev/feature' and 'dev' (as Git uses files and directories to
store them).
Multiple anonymous heads (which are useless anyway) are not supported; you
Multiple anonymous heads (which are useless anyway) are not supported: you
would only see the latest head.
Closed branches are not supported; they are not shown and you can't close or
Closed branches are not supported: they are not shown and you can't close or
reopen. Additionally in certain rare situations a synchronization issue can
occur (https://github.com/felipec/git/issues/65[Bug #65]).
@@ -170,16 +167,27 @@ below for more details.
== Other projects ==
There are other 'git-remote-hg' projects out there, do not confuse this one,
this is the one distributed officially by the Git project
(_though actually no longer so nowadays_):
There are other `git-remote-hg` projects out there, but this is the original,
which was distributed officially in the Git project.
* https://github.com/msysgit/msysgit/wiki/Guide-to-git-remote-hg[msysgit's git-remote-hg]
* https://github.com/rfk/git-remote-hg[rfk's git-remote-hg]
Over the years many similar tools have died out, the only actively maintained
alternative is mnauw's fork of this project:
https://github.com/mnauw/git-remote-hg[mnauw/git-remote-hg]. I've merged some of
his patches, and he has merged some of my patches, so the projects are mostly in
sync, but not quite. In particular Nauwelaerts' fork has many administrative
extensions, which although useful to some people, I don't believe they belong
in the core.
For a comparison between these and other projects go
https://github.com/felipec/git/wiki/Comparison-of-git-remote-hg-alternatives[here].
****
mnauw's note; I do not know what "the core" means?
However, the "extensions" provide useful and possibly
critical maintenance wrt git-remote-hg's internal data, so it belongs as close
to the latter one as possible.
****
[[no-limitations]]
== Limitations (or not) ==

View File

@@ -38,7 +38,8 @@ If you want to see Mercurial revisions as Git commit notes:
% git config core.notesRef refs/notes/hg
--------------------------------------
If you are not interested in Mercurial permanent and global branches (aka. commit labels):
If you are not interested in Mercurial permanent and global branches (aka.
commit labels):
--------------------------------------
% git config --global remote-hg.track-branches false
@@ -52,7 +53,8 @@ If you want the equivalent of `hg clone --insecure`:
% git config --global remote-hg.insecure true
--------------------------------------
If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly the same commits:
If you want 'git-remote-hg' to be compatible with 'hg-git', and generate exactly
the same commits:
--------------------------------------
% git config --global remote-hg.hg-git-compat true
@@ -105,16 +107,15 @@ the invalid '~'
NOTES
-----
Remember to run `git gc --aggressive` after cloning a repository, specially if
Remember to run `git gc --aggressive` after cloning a repository, especially if
it's a big one. Otherwise lots of space will be wasted.
The oldest version of Mercurial supported is 1.9. For the most part 1.8 works,
but you might experience some issues.
The newest supported version of Mercurial is 6.2, the oldest one is 2.4.
Pushing branches
~~~~~~~~~~~~~~~~
To push a Mercurial named branch, you need to use the "branches/" prefix:
To push a branch, you need to use the "branches/" prefix:
--------------------------------------
% git checkout branches/next
@@ -135,7 +136,7 @@ The simplest way is to specify the user and password in the URL:
git clone hg::https://user:password@bitbucket.org/user/repo
--------------------------------------
You can also use the http://mercurial.selenic.com/wiki/SchemesExtension[schemes extension]:
You can also use the https://mercurial-scm.org/wiki/SchemesExtension[schemes extension]:
--------------------------------------
[auth]
@@ -145,7 +146,7 @@ bb.password = password
--------------------------------------
Finally, you can also use the
https://pypi.python.org/pypi/mercurial_keyring[keyring extension].
https://pypi.org/project/mercurial_keyring[keyring extension].
CAVEATS
-------
@@ -157,10 +158,10 @@ Mercurial branches and bookmarks have some limitations of Git branches: you
can't have both 'dev/feature' and 'dev' (as Git uses files and directories to
store them).
Multiple anonymous heads (which are useless anyway) are not supported; you
Multiple anonymous heads (which are useless anyway) are not supported: you
would only see the latest head.
Closed branches are not supported; they are not shown and you can't close or
Closed branches are not supported: they are not shown and you can't close or
reopen. Additionally in certain rare situations a synchronization issue can
occur (https://github.com/felipec/git/issues/65[Bug #65]).

View File

@@ -147,10 +147,10 @@ else:
# Commits are modified to preserve hg information and allow bidirectionality.
#
NAME_RE = re.compile(b'^([^<>]+)')
AUTHOR_RE = re.compile(b'^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
NAME_RE = re.compile(br'^([^<>]+)')
AUTHOR_RE = re.compile(br'^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
EMAIL_RE = re.compile(br'([^ \t<>]+@[^ \t<>]+)')
AUTHOR_HG_RE = re.compile(b'^(.*?) ?<(.*?)(?:>(.*))?$')
AUTHOR_HG_RE = re.compile(br'^(.*?) ?<(.*?)(?:>(.*))?$')
RAW_AUTHOR_RE = re.compile(br'^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
VERSION = 2
@@ -159,6 +159,9 @@ def die(msg):
compat.stderr.write(b'ERROR: %s\n' % compat.to_b(msg, 'utf-8'))
sys.exit(1)
def debug(*args):
compat.stderr.write(b'DEBUG: %s\n' % compat.to_b(repr(args)))
def warn(msg):
compat.stderr.write(b'WARNING: %s\n' % compat.to_b(msg, 'utf-8'))
compat.stderr.flush()
@@ -237,27 +240,17 @@ def get_rev_hg(commit):
class Marks:
def __init__(self, path, repo):
def __init__(self, path, _repo=None):
self.path = path
self.repo = repo
self.clear()
self.load()
if self.version < VERSION:
if self.version == 1:
self.upgrade_one()
# upgraded?
if self.version < VERSION:
self.clear()
self.version = VERSION
def clear(self):
self.tips = {}
self.marks = {}
self.rev_marks = {}
self.last_mark = 0
self.version = 0
self.version = VERSION
self.last_note = 0
def load(self):
@@ -273,20 +266,12 @@ class Marks:
self.tips = []
self.marks = marks
self.last_mark = tmp['last-mark']
self.version = tmp.get('version', 1)
self.version = tmp['version']
self.last_note = 0
for rev, mark in compat.iteritems(self.marks):
self.rev_marks[mark] = rev
def upgrade_one(self):
def get_id(rev):
return hghex(self.repo.changelog.node(int(rev)))
self.tips = dict((name, get_id(rev)) for name, rev in compat.iteritems(self.tips))
self.marks = dict((get_id(rev), mark) for rev, mark in compat.iteritems(self.marks))
self.rev_marks = dict((mark, get_id(rev)) for mark, rev in compat.iteritems(self.rev_marks))
self.version = 2
def dict(self):
return { 'tips': self.tips, 'marks': self.marks,
'last-mark': self.last_mark, 'version': self.version,
@@ -408,40 +393,38 @@ class Parser:
return (user, int(date), hgtz(tz))
def fix_file_path(path):
def posix_path(path):
if os.sep == '/':
return path
# even Git for Windows expects forward
return path.replace(compat.to_b(os.sep), b'/')
# also converts forward slash to backwards slash on Win
path = os.path.normpath(path)
if not os.path.isabs(path):
return posix_path(path)
return posix_path(os.path.relpath(path, b'/'))
if os.path.isabs(path):
path = os.path.relpath(path, b'/')
if os.sep == '/':
return path
# even Git for Windows expects forward
return path.replace(compat.to_b(os.sep), b'/')
def export_files(files):
final = []
for f in files:
fid = node.hex(f.filenode())
def export_file(ctx, fname):
f = ctx.filectx(fname)
fid = node.hex(f.filenode())
if fid in filenodes:
mark = filenodes[fid]
else:
mark = marks.next_mark()
filenodes[fid] = mark
d = f.data()
if fid in filenodes:
mark = filenodes[fid]
else:
mark = marks.next_mark()
filenodes[fid] = mark
d = f.data()
puts(b"blob")
puts(b"mark :%u" % mark)
puts(b"data %d" % len(d))
puts(d)
puts(b"blob")
puts(b"mark :%u" % mark)
puts(b"data %d" % len(d))
puts(f.data())
path = fix_file_path(f.path())
final.append((gitmode(f.flags()), mark, path))
return final
path = fix_file_path(f.path())
return (gitmode(f.flags()), mark, path)
def get_filechanges(repo, ctx, parent):
if hasattr(parent, 'status'):
stat = parent.status(ctx)
return stat.modified + stat.added, stat.removed
modified = set()
added = set()
removed = set()
@@ -483,7 +466,7 @@ def fixup_user_git(user):
def fixup_user_hg(user):
def sanitize(name):
# stole this from hg-git
return re.sub(b'[<>\n]', b'?', name.lstrip(b'< ').rstrip(b'> '))
return re.sub(br'[<>\n]', b'?', name.lstrip(b'< ').rstrip(b'> '))
m = AUTHOR_HG_RE.match(user)
if m:
@@ -585,18 +568,6 @@ def get_repo(url, alias):
else:
shared_path = os.path.join(gitdir, b'hg')
# check and upgrade old organization
hg_path = os.path.join(shared_path, b'.hg')
if os.path.exists(shared_path) and not os.path.exists(hg_path):
repos = os.listdir(shared_path)
for x in repos:
local_hg = os.path.join(shared_path, x, b'clone', b'.hg')
if not os.path.exists(local_hg):
continue
if not os.path.exists(hg_path):
shutil.move(local_hg, hg_path)
shutil.rmtree(os.path.join(shared_path, x, b'clone'))
# setup shared repo (if not there)
try:
hg.peer(myui, {}, shared_path, create=True)
@@ -607,11 +578,16 @@ def get_repo(url, alias):
os.makedirs(dirname)
local_path = os.path.join(dirname, b'clone')
if not os.path.exists(local_path):
hg.share(myui, shared_path, local_path, update=False)
if check_version(4, 2):
if not os.path.exists(local_path):
hg.share(myui, shared_path, local_path, update=False, relative=True)
else:
# make sure the shared path is always up-to-date
util.writefile(os.path.join(local_path, b'.hg', b'sharedpath'), hg_path)
if not os.path.exists(local_path):
hg.share(myui, shared_path, local_path, update=False)
else:
# make sure the shared path is always up-to-date
hg_path = os.path.join(shared_path, b'.hg')
util.writefile(os.path.join(local_path, b'.hg', b'sharedpath'), hg_path)
repo = hg.repository(myui, local_path)
try:
@@ -721,7 +697,7 @@ def export_ref(repo, name, kind, head):
extra_msg += b"rename : %s => %s\n" % e
for key, value in compat.iteritems(extra):
if key in (b'author', b'committer', b'encoding', b'message', b'branch', b'hg-git'):
if key in (b'author', b'committer', b'encoding', b'message', b'branch', b'hg-git', b'transplant_source'):
continue
elif key == b'hg-git-rename-source' and value == b'git':
# extra data that hg-git might put there unconditionally
@@ -736,7 +712,7 @@ def export_ref(repo, name, kind, head):
if len(parents) == 0:
puts(b'reset %s/%s' % (prefix, ename))
modified_final = export_files(c.filectx(f) for f in modified)
modified_final = [export_file(c, fname) for fname in modified]
puts(b"commit %s/%s" % (prefix, ename))
puts(b"mark :%d" % (marks.get_mark(c.hex())))
@@ -849,8 +825,11 @@ def do_list(parser, branchmap):
for branch, heads in compat.iteritems(branchmap):
# only open heads
heads = [h for h in heads if b'close' not in repo.changelog.read(h)[5]]
if heads:
try:
heads = [h for h in heads if b'close' not in repo.changelog.read(h)[5]]
if heads:
branches[branch] = heads
except error.LookupError:
branches[branch] = heads
list_head(repo, cur)
@@ -1340,7 +1319,10 @@ def checkheads(repo, remote, p_revs, force):
def push_unsafe(repo, remote, p_revs, force):
fci = discovery.findcommonincoming
commoninc = fci(repo, remote, force=force)
if check_version(4, 5):
commoninc = fci(repo, remote, force=force, ancestorsof=list(p_revs))
else:
commoninc = fci(repo, remote, force=force)
common, _, remoteheads = commoninc
fco = discovery.findcommonoutgoing
outgoing = fco(repo, remote, onlyheads=list(p_revs), commoninc=commoninc, force=force)
@@ -1371,12 +1353,6 @@ def push_unsafe(repo, remote, p_revs, force):
else:
ret = remote.addchangegroup(cg, b'push', repo.url())
phases = remote.listkeys(b'phases')
if phases:
for head in p_revs:
# update to public
remote.pushkey(b'phases', hghex(head), b'1', b'0')
return ret
def push(repo, remote, p_revs, force):
@@ -1411,6 +1387,7 @@ def do_push_hg(parser):
global parsed_refs, parsed_tags
p_bmarks = []
p_revs = {}
ok_refs = []
parsed_refs = {}
parsed_tags = {}
@@ -1457,7 +1434,7 @@ def do_push_hg(parser):
continue
p_revs[bnode] = ref
puts(b"ok %s" % ref)
ok_refs.append(ref)
elif ref.startswith(b'refs/heads/'):
bmark = ref[len(b'refs/heads/'):]
new = node
@@ -1467,14 +1444,14 @@ def do_push_hg(parser):
puts(b"ok %s up to date" % ref)
continue
puts(b"ok %s" % ref)
ok_refs.append(ref)
if not bookmark_is_fake(bmark, parser.repo._bookmarks):
p_bmarks.append((ref, bmark, old, new))
p_revs[bnode] = ref
elif ref.startswith(b'refs/tags/'):
if dry_run:
puts(b"ok %s" % ref)
ok_refs.append(ref)
continue
tag = ref[len(b'refs/tags/'):]
tag = hgref(tag)
@@ -1501,14 +1478,15 @@ def do_push_hg(parser):
fp.write(b'%s %s\n' % (node, tag))
fp.close()
p_revs[bnode] = ref
puts(b"ok %s" % ref)
ok_refs.append(ref)
else:
# transport-helper/fast-export bugs
continue
if dry_run:
if peer:
checkheads(parser.repo, peer, p_revs, force_push)
if not peer or checkheads(parser.repo, peer, p_revs, force_push):
for ref in ok_refs:
puts(b"ok %s" % ref)
return
success = True
@@ -1529,12 +1507,18 @@ def do_push_hg(parser):
if not peer.pushkey(b'bookmarks', bmark, old, new):
success = False
puts(b"error %s" % ref)
ok_refs.remove(ref)
else:
# update local bookmarks
for ref, bmark, old, new in p_bmarks:
if not bookmarks.pushbookmark(parser.repo, bmark, old, new):
success = False
puts(b"error %s" % ref)
ok_refs.remove(ref)
# update rest of the refs
for ref in ok_refs:
puts(b"ok %s" % ref)
return success
@@ -1743,8 +1727,7 @@ def fix_path(alias, repo, orig_url):
url = compat.urlparse(orig_url, b'file')
if url.scheme != b'file' or os.path.isabs(os.path.expanduser(url.path)):
return
abs_url = compat.urljoin(b"%s/" % compat.getcwd(), orig_url)
cmd = ['git', 'config', b'remote.%s.url' % alias, b"hg::%s" % abs_url]
cmd = ['git', 'config', b'remote.%s.url' % alias, b"hg::%s" % os.path.abspath(orig_url)]
subprocess.call(cmd)
def select_private_refs(alias):
@@ -1922,7 +1905,7 @@ def main(args):
fix_path(alias, peer or repo, url)
marks_path = os.path.join(marksdir, b'marks-hg')
marks = Marks(marks_path, repo)
marks = Marks(marks_path)
if sys.platform == 'win32':
import msvcrt

View File

@@ -1,9 +1,9 @@
RM ?= rm -f
T = main.t main-push.t bidi.t helper.t
TEST_DIRECTORY := $(CURDIR)
SHARNESS_TEST_DIRECTORY := $(CURDIR)
export TEST_DIRECTORY
export SHARNESS_TEST_DIRECTORY
all: test
@@ -11,7 +11,7 @@ test: $(T)
$(MAKE) clean
$(T):
$(SHELL) $@ $(TEST_OPTS)
./$@ $(TEST_OPTS)
clean:
$(RM) -r 'trash directory'.* test-results

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# Copyright (c) 2012 Felipe Contreras
#
@@ -8,14 +8,7 @@
test_description='Test bidirectionality of remote-hg'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-hg tests; python with mercurial not available'
test_done
fi
. ./test-lib.sh
# clone to a git repo
git_clone () {

View File

@@ -0,0 +1,60 @@
blob
mark :1
data 2
A
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 7
origin
M 100644 :1 afile
blob
mark :3
data 2
C
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 3 +0000
committer A U Thor <author@example.com> 3 +0000
data 5
A->C
from :2
M 100644 :3 afile
blob
mark :5
data 2
B
commit refs/heads/master
mark :6
author A U Thor <author@example.com> 1 +0000
committer A U Thor <author@example.com> 1 +0000
data 5
A->B
from :2
M 100644 :5 afile
commit refs/heads/master
mark :7
author A U Thor <author@example.com> 2 +0000
committer A U Thor <author@example.com> 2 +0000
data 5
B->C
from :6
M 100644 :3 afile
commit refs/heads/master
mark :8
author A U Thor <author@example.com> 4 +0000
committer A U Thor <author@example.com> 4 +0000
data 6
merge
from :4
merge :7

View File

@@ -0,0 +1,67 @@
changeset: 9a6668f453c3003b71e11bb8d7572af57a7ce891
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 331ac2e605f2e6092ccb3802244a65b71f3be726
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: afile
extra: branch=default
description:
origin
changeset: ead35d346ecb18ce9d9d54604ff62b41caa196ce
phase: draft
parent: 9a6668f453c3003b71e11bb8d7572af57a7ce891
parent: -0000000000000000000000000000000000000000
manifest: 894f8ad9a84f743d52747963d0b9f4e9cf37d489
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:01 1970 +0000
files: afile
extra: branch=default
description:
A->B
changeset: 541c7bc8b2d01c8bf71b2298d17edcda120e49bf
phase: draft
parent: ead35d346ecb18ce9d9d54604ff62b41caa196ce
parent: -0000000000000000000000000000000000000000
manifest: 04dae4001cb1fb2384111589720617c4b742044c
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:02 1970 +0000
files: afile
extra: branch=default
description:
B->C
changeset: 5694aadcd7171ecb9768b13e29d027e22a360d44
phase: draft
parent: 9a6668f453c3003b71e11bb8d7572af57a7ce891
parent: -0000000000000000000000000000000000000000
manifest: 6efc6bb8e097947aa212887bdb01fb89dfa3de13
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:03 1970 +0000
files: afile
extra: branch=default
description:
A->C
changeset: 9ee75b4362cc15f9110d6538b2f1c9f0cf14825a
bookmark: master
tag: tip
phase: draft
parent: 5694aadcd7171ecb9768b13e29d027e22a360d44
parent: 541c7bc8b2d01c8bf71b2298d17edcda120e49bf
manifest: eb9f4687448653e876d787cd6f2e59140680ff09
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:04 1970 +0000
files: afile
extra: branch=default
description:
merge

View File

@@ -0,0 +1,56 @@
blob
mark :1
data 6
alpha
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 12
add älphà
M 100644 :1 alpha
blob
mark :3
data 5
beta
commit refs/heads/master
mark :4
author tést èncödîng <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 9
add beta
from :2
M 100644 :3 beta
blob
mark :5
data 6
gamma
commit refs/heads/master
mark :6
author tést èncödîng <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 12
add gämmâ
from :4
M 100644 :5 gamma
blob
mark :7
data 6
delta
commit refs/heads/master
mark :8
author tést èncödîng <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 12
add déltà
from :6
M 100644 :7 delta

View File

@@ -0,0 +1,58 @@
changeset: 6674f1c866b5c428db4acde16404c14077889646
bookmark: master
tag: tip
phase: draft
parent: 7e9fd3fd2f75d7de4bf3d77c47f192a51927ac28
parent: -0000000000000000000000000000000000000000
manifest: ea49f93388380ead5601c8fcbfa187516e7c2ed8
user: tést èncödîng <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: delta
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add déltà
changeset: 7e9fd3fd2f75d7de4bf3d77c47f192a51927ac28
phase: draft
parent: 99c5adad03b9a9935e181f4be91ff7693a790110
parent: -0000000000000000000000000000000000000000
manifest: f580e7da3673c137370da2b931a1dee83590d7b4
user: tést èncödîng <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: gamma
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add gämmâ
changeset: 99c5adad03b9a9935e181f4be91ff7693a790110
phase: draft
parent: 1e3e49d2cc8feaad4942d100108f20f207742d3a
parent: -0000000000000000000000000000000000000000
manifest: f0bd6fbafbaebe4bb59c35108428f6fce152431d
user: tést èncödîng <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: beta
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add beta
changeset: 1e3e49d2cc8feaad4942d100108f20f207742d3a
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add älphà

View File

@@ -0,0 +1,32 @@
blob
mark :1
data 6
alpha
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 10
add alpha
M 100644 :1 alpha
commit refs/heads/master
mark :3
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 19
set executable bit
from :2
M 100755 :1 alpha
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 21
clear executable bit
from :3
M 100644 :1 alpha

View File

@@ -0,0 +1,46 @@
changeset: 1efb93106a36bf71352ab04e769a3422522cf946
bookmark: master
tag: tip
phase: draft
parent: d7cae8b1fdab97568ba5eca44ca2bf5a44d7c394
parent: -0000000000000000000000000000000000000000
manifest: 51e6255d794f794a8c4e0f03edf264444e3c5ce7
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
clear executable bit
changeset: d7cae8b1fdab97568ba5eca44ca2bf5a44d7c394
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: e4bf4ef5e9aea7a6a57573e533a5519bd062f144
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
set executable bit
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha
644 alpha
644 alpha

View File

@@ -0,0 +1,60 @@
blob
mark :1
data 6
alpha
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 10
add alpha
M 100644 :1 alpha
blob
mark :3
data 5
beta
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 9
add beta
from :2
M 100644 :3 beta
blob
mark :5
data 5
blah
commit refs/heads/master
mark :6
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 8
add foo
from :4
M 100644 :5 foo/bar
commit refs/heads/master
mark :7
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 13
remove alpha
from :6
D alpha
commit refs/heads/master
mark :8
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 15
remove foo/bar
from :7
D foo/bar

View File

@@ -0,0 +1,75 @@
changeset: 54f595cbdf1f516dc3b2b25faa6f051aae712f5d
bookmark: master
tag: tip
phase: draft
parent: 7fe32a9185c6d37db430ee5248cdb2ae66582478
parent: -0000000000000000000000000000000000000000
manifest: 3f83f42fa00fb0cac14a83aa48baac2f287a9329
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files-: foo/bar
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
remove foo/bar
changeset: 7fe32a9185c6d37db430ee5248cdb2ae66582478
phase: draft
parent: a21fd0b26a555427c2ea72f8ed37190f6216f705
parent: -0000000000000000000000000000000000000000
manifest: cd10925837609b99d345c44c85bd1f73d742cbbc
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files-: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
remove alpha
changeset: a21fd0b26a555427c2ea72f8ed37190f6216f705
phase: draft
parent: 7cd99375c843931bd8959b766a94e050f428512b
parent: -0000000000000000000000000000000000000000
manifest: a6ee442a94bfc6fb0b7d717183bb8b4534ca4ccd
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: foo/bar
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add foo
changeset: 7cd99375c843931bd8959b766a94e050f428512b
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: f0bd6fbafbaebe4bb59c35108428f6fce152431d
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: beta
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add beta
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha
beta
foo/bar
beta

View File

@@ -0,0 +1,32 @@
changeset: 7cd99375c843931bd8959b766a94e050f428512b
bookmark: master
tag: beta
tag: tip
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: f0bd6fbafbaebe4bb59c35108428f6fce152431d
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: beta
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add beta
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
tag: alpha
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha

View File

@@ -0,0 +1,141 @@
blob
mark :1
data 6
alpha
reset refs/heads/not-master
commit refs/heads/not-master
mark :2
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 10
add alpha
M 100644 :1 alpha
blob
mark :3
data 5
beta
commit refs/heads/master
mark :4
author test <none@none> 0 +0000
committer test <none@none> 0 +0000
data 9
add beta
from :2
M 100644 :3 beta
blob
mark :5
data 11
beta
gamma
commit refs/heads/master
mark :6
author test ext:(%20%28comment%29) <test@example.com> 0 +0000
committer test ext:(%20%28comment%29) <test@example.com> 0 +0000
data 12
modify beta
from :4
M 100644 :5 beta
blob
mark :7
data 6
gamma
commit refs/heads/master
mark :8
author <test@example.com> 0 +0000
committer <test@example.com> 0 +0000
data 10
add gamma
from :6
M 100644 :7 gamma
blob
mark :9
data 6
delta
commit refs/heads/master
mark :10
author name <test@example.com> 0 +0000
committer name <test@example.com> 0 +0000
data 10
add delta
from :8
M 100644 :9 delta
blob
mark :11
data 8
epsilon
commit refs/heads/master
mark :12
author name <test@example.com> 0 +0000
committer name <test@example.com> 0 +0000
data 12
add epsilon
from :10
M 100644 :11 epsilon
blob
mark :13
data 5
zeta
commit refs/heads/master
mark :14
author test <none@none> 0 +0000
committer test <none@none> 0 +0000
data 9
add zeta
from :12
M 100644 :13 zeta
blob
mark :15
data 4
eta
commit refs/heads/master
mark :16
author test <test@example.com> 0 +0000
committer test <test@example.com> 0 +0000
data 8
add eta
from :14
M 100644 :15 eta
blob
mark :17
data 6
theta
commit refs/heads/master
mark :18
author test ?test@example.com <test ?test@example.com> 0 +0000
committer test ?test@example.com <test ?test@example.com> 0 +0000
data 10
add theta
from :16
M 100644 :17 theta
blob
mark :19
data 5
iota
commit refs/heads/master
mark :20
author test ext:(%20example%20%3Cdot%3E%20com%3E) <test ?at> 0 +0000
committer test ext:(%20example%20%3Cdot%3E%20com%3E) <test ?at> 0 +0000
data 9
add iota
from :18
M 100644 :19 iota

View File

@@ -0,0 +1,134 @@
changeset: 307c03466a07cccafaafc991f36d695d6ad595f3
bookmark: master
tag: tip
phase: draft
parent: 5832614d351449a2f8d6f7ccbef4877c2b18cbe0
parent: -0000000000000000000000000000000000000000
manifest: e8f1b3ae088bdd25e3570a4953ccb6b948524473
user: test <test ?at> example <dot> com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: iota
extra: branch=default
description:
add iota
changeset: 5832614d351449a2f8d6f7ccbef4877c2b18cbe0
phase: draft
parent: e52ded4aca5d210ed58c63158d64fb911876f345
parent: -0000000000000000000000000000000000000000
manifest: 7e4875db7e2970c529f462520121d333e514bf4d
user: test ?test@example.com <test ?test@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: theta
extra: branch=default
description:
add theta
changeset: e52ded4aca5d210ed58c63158d64fb911876f345
phase: draft
parent: 9a34ba7d552e8b73ad306baf1d1eb83de0f74c12
parent: -0000000000000000000000000000000000000000
manifest: ef03e54a9916ac3158c9686503dd4f609c26b3ec
user: test <test@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: eta
extra: branch=default
description:
add eta
changeset: 9a34ba7d552e8b73ad306baf1d1eb83de0f74c12
phase: draft
parent: 6281edc25b9fe9538407726f044a9a61ac7ba5bc
parent: -0000000000000000000000000000000000000000
manifest: 616201b85baf7ed02d41f6a7deb04c52009d8483
user: test
date: Thu Jan 01 00:00:00 1970 +0000
files+: zeta
extra: branch=default
description:
add zeta
changeset: 6281edc25b9fe9538407726f044a9a61ac7ba5bc
phase: draft
parent: 4c7841053c633cb51f8375555d08b6bea54fc4cb
parent: -0000000000000000000000000000000000000000
manifest: c703b3d7be8a0638047142f57ff83d4e94b5d1fa
user: name <test@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: epsilon
extra: branch=default
description:
add epsilon
changeset: 4c7841053c633cb51f8375555d08b6bea54fc4cb
phase: draft
parent: fa8f26586397dd4797842e9300c8db221fe5514d
parent: -0000000000000000000000000000000000000000
manifest: 300b54001cbfa5d027b4bccdb594ccb463adb55d
user: name <test@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: delta
extra: branch=default
description:
add delta
changeset: fa8f26586397dd4797842e9300c8db221fe5514d
phase: draft
parent: 2708ff417fb7e2c0a4f9596286c0a398553fa793
parent: -0000000000000000000000000000000000000000
manifest: 45b0c483a79307d14f7e234feb78776478f828ec
user: <test@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: gamma
extra: branch=default
description:
add gamma
changeset: 2708ff417fb7e2c0a4f9596286c0a398553fa793
phase: draft
parent: 8c51e5fe974fe1cc63a56bbfad343f9ede6bed30
parent: -0000000000000000000000000000000000000000
manifest: c305998040b12e956b998318982c9eb92d2d7b28
user: test <test@example.com> (comment)
date: Thu Jan 01 00:00:00 1970 +0000
files: beta
extra: branch=default
description:
modify beta
changeset: 8c51e5fe974fe1cc63a56bbfad343f9ede6bed30
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: f0bd6fbafbaebe4bb59c35108428f6fce152431d
user: test
date: Thu Jan 01 00:00:00 1970 +0000
files+: beta
extra: branch=default
description:
add beta
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
bookmark: not-master
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha

View File

@@ -0,0 +1,38 @@
blob
mark :1
data 6
alpha
reset refs/heads/not-master
commit refs/heads/not-master
mark :2
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 10
add alpha
M 100644 :1 alpha
commit refs/heads/master
mark :3
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 52
rename alpha to beta
--HG--
rename : alpha => beta
from :2
D alpha
M 100644 :1 beta
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 44
started branch gamma
--HG--
branch : gamma
from :3

View File

@@ -0,0 +1,44 @@
changeset: 3320583a8de0b31511f499a4ab3426bee1a7f478
branch: gamma
bookmark: master
tag: tip
phase: draft
parent: 5889597089fea2d144989baa9427d1a080293fdb
parent: -0000000000000000000000000000000000000000
manifest: e353b4d5282d044ad738398fd32d0b684d04a14b
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
extra: branch=gamma
description:
started branch gamma
changeset: 5889597089fea2d144989baa9427d1a080293fdb
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: e353b4d5282d044ad738398fd32d0b684d04a14b
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: beta
files-: alpha
extra: branch=default
description:
rename alpha to beta
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
bookmark: not-master
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha

View File

@@ -0,0 +1,33 @@
alpha
changeset: 16869bbe54be9f8082a8aec346de09f6c05cf1de
bookmark: master
tag: tip
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: 26f8145fb5b20cc6f70dd131b646f95ab79738c0
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: .hgtags
extra: branch=default
description:
Added tag alpha for changeset 362b656574c3
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
bookmark: not-master
tag: alpha
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha
362b656574c3c9e89fa7f2d7a943091dc93bce4d alpha

View File

@@ -0,0 +1,51 @@
blob
mark :1
data 2
A
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 7
origin
M 100644 :1 afile
blob
mark :3
data 2
C
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 2 +0000
committer A U Thor <author@example.com> 2 +0000
data 5
A->C
from :2
M 100644 :3 afile
blob
mark :5
data 2
B
commit refs/heads/master
mark :6
author A U Thor <author@example.com> 1 +0000
committer A U Thor <author@example.com> 1 +0000
data 5
A->B
from :2
M 100644 :5 afile
commit refs/heads/master
mark :7
author A U Thor <author@example.com> 3 +0000
committer A U Thor <author@example.com> 3 +0000
data 11
merge to C
from :4
merge :6

View File

@@ -0,0 +1,54 @@
changeset: 9a6668f453c3003b71e11bb8d7572af57a7ce891
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 331ac2e605f2e6092ccb3802244a65b71f3be726
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: afile
extra: branch=default
description:
origin
changeset: ead35d346ecb18ce9d9d54604ff62b41caa196ce
phase: draft
parent: 9a6668f453c3003b71e11bb8d7572af57a7ce891
parent: -0000000000000000000000000000000000000000
manifest: 894f8ad9a84f743d52747963d0b9f4e9cf37d489
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:01 1970 +0000
files: afile
extra: branch=default
description:
A->B
changeset: d585ac55494928500f510b965b878d47f9ee60f6
phase: draft
parent: 9a6668f453c3003b71e11bb8d7572af57a7ce891
parent: -0000000000000000000000000000000000000000
manifest: 6efc6bb8e097947aa212887bdb01fb89dfa3de13
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:02 1970 +0000
files: afile
extra: branch=default
description:
A->C
changeset: c6ab734e24c39948e5a25713b48f4972c960ff8b
bookmark: master
tag: tip
phase: draft
parent: d585ac55494928500f510b965b878d47f9ee60f6
parent: ead35d346ecb18ce9d9d54604ff62b41caa196ce
manifest: 96bedb13781f1b9d729a2210a530f0c5c68f42e6
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:03 1970 +0000
files: afile
extra: branch=default
description:
merge to C

View File

@@ -0,0 +1,52 @@
blob
mark :1
data 2
A
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 7
origin
M 100644 :1 afile
blob
mark :3
data 2
C
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 2 +0000
committer A U Thor <author@example.com> 2 +0000
data 5
A->C
from :2
M 100644 :3 afile
blob
mark :5
data 2
B
commit refs/heads/master
mark :6
author A U Thor <author@example.com> 1 +0000
committer A U Thor <author@example.com> 1 +0000
data 5
A->B
from :2
M 100644 :5 afile
commit refs/heads/master
mark :7
author A U Thor <author@example.com> 3 +0000
committer A U Thor <author@example.com> 3 +0000
data 11
merge to B
from :4
merge :6
M 100644 :5 afile

View File

@@ -0,0 +1,54 @@
changeset: 9a6668f453c3003b71e11bb8d7572af57a7ce891
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 331ac2e605f2e6092ccb3802244a65b71f3be726
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: afile
extra: branch=default
description:
origin
changeset: ead35d346ecb18ce9d9d54604ff62b41caa196ce
phase: draft
parent: 9a6668f453c3003b71e11bb8d7572af57a7ce891
parent: -0000000000000000000000000000000000000000
manifest: 894f8ad9a84f743d52747963d0b9f4e9cf37d489
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:01 1970 +0000
files: afile
extra: branch=default
description:
A->B
changeset: d585ac55494928500f510b965b878d47f9ee60f6
phase: draft
parent: 9a6668f453c3003b71e11bb8d7572af57a7ce891
parent: -0000000000000000000000000000000000000000
manifest: 6efc6bb8e097947aa212887bdb01fb89dfa3de13
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:02 1970 +0000
files: afile
extra: branch=default
description:
A->C
changeset: 542b187b70e70dc759631d1065794f3c2c5a3e7b
bookmark: master
tag: tip
phase: draft
parent: d585ac55494928500f510b965b878d47f9ee60f6
parent: ead35d346ecb18ce9d9d54604ff62b41caa196ce
manifest: 0907d7dbc98790102fa6cb91b68b271ef0bc5b64
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:03 1970 +0000
files: afile
extra: branch=default
description:
merge to B

View File

@@ -0,0 +1,27 @@
blob
mark :1
data 6
alpha
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 10
add alpha
M 100644 :1 alpha
commit refs/heads/master
mark :3
author A U Thor <author@example.com> 0 +0000
committer A U Thor <author@example.com> 0 +0000
data 52
rename alpha to beta
--HG--
rename : alpha => beta
from :2
D alpha
M 100644 :1 beta

View File

@@ -0,0 +1,29 @@
changeset: a985b184598fd779e53576c65c5dd1d274736c73
bookmark: master
tag: tip
phase: draft
parent: 0558a161e3ca0d59f5f165e3182402d9f1e574a8
parent: -0000000000000000000000000000000000000000
manifest: e353b4d5282d044ad738398fd32d0b684d04a14b
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: beta
files-: alpha
extra: branch=default
description:
rename alpha to beta
changeset: 0558a161e3ca0d59f5f165e3182402d9f1e574a8
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Thu Jan 01 00:00:00 1970 +0000
files+: alpha
extra: branch=default
description:
add alpha

27
test/expected/symlink/log Normal file
View File

@@ -0,0 +1,27 @@
blob
mark :1
data 6
alpha
reset refs/heads/master
commit refs/heads/master
mark :2
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 10
add alpha
M 100644 :1 alpha
blob
mark :3
data 5
alpha
commit refs/heads/master
mark :4
author A U Thor <author@example.com> 1167600600 +0230
committer C O Mitter <committer@example.com> 1167600600 +0230
data 9
add beta
from :2
M 120000 :3 beta

View File

@@ -0,0 +1,32 @@
changeset: 87cbc97576079d3dfef04c678bfc8ab69999ebdf
bookmark: master
tag: tip
phase: draft
parent: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
parent: -0000000000000000000000000000000000000000
manifest: 4950f48a7f5b0ce6f31c2f4307e296dbac652026
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: beta
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add beta
changeset: 362b656574c3c9e89fa7f2d7a943091dc93bce4d
phase: draft
parent: -0000000000000000000000000000000000000000
parent: -0000000000000000000000000000000000000000
manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
user: A U Thor <author@example.com>
date: Mon Jan 01 00:00:00 2007 +0230
files+: alpha
extra: branch=default
extra: committer=C O Mitter <committer@example.com> 1167600600 -9000
description:
add alpha
644 alpha
644 @ beta

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# Copyright (c) 2012 Felipe Contreras
#
@@ -6,36 +6,24 @@
# https://bitbucket.org/durin42/hg-git/src
#
# shellcheck disable=SC2016,SC2034,SC2086,SC2164,SC1091
test_description='Test remote-hg output compared to hg-git'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
. "$TEST_DIRECTORY"/test-lib.sh
. ./test-lib.sh
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-hg tests; python with mercurial not available'
test_done
fi
export EXPECTED_DIR="$SHARNESS_TEST_DIRECTORY/expected"
if "$PYTHON" -c 'import hggit' > /dev/null 2>&1
then
hggit=hggit
elif "$PYTHON" -c 'import hgext.git' > /dev/null 2>&1
then
hggit=hgext.git
else
skip_all='skipping remote-hg tests; hg-git not available'
test_done
fi
# clone to a git repo with git
git_clone_git () {
git_clone () {
git clone -q "hg::$1" $2 &&
(cd $2 && git checkout master && git branch -D default)
(
cd $2 &&
git checkout master &&
{ git branch -D default || true ;}
)
}
# clone to an hg repo with git
hg_clone_git () {
hg_clone () {
(
hg init $2 &&
hg -R $2 bookmark -i master &&
@@ -46,83 +34,96 @@ hg_clone_git () {
(cd $2 && hg -q update)
}
# clone to a git repo with hg
git_clone_hg () {
(
git init -q $2 &&
cd $1 &&
hg bookmark -i -f -r tip master &&
hg -q push -r master ../$2 || true
)
}
# clone to an hg repo with hg
hg_clone_hg () {
hg -q clone $1 $2
}
# push an hg repo with git
hg_push_git () {
hg_push () {
(
cd $2
git checkout -q -b tmp &&
git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
git branch -D default &&
git checkout -q @{-1} &&
git branch -q -D tmp 2> /dev/null || true
)
}
# push an hg git repo with hg
hg_push_hg () {
(
cd $1 &&
hg -q push ../$2 || true
git checkout -q '@{-1}' &&
{ git branch -q -D tmp 2> /dev/null || true ;}
)
}
hg_log () {
hg -R $1 log --graph --debug > log &&
grep -v 'tag: *default/' log
hg -R $1 log --debug -r 'sort(tip:0, date)' |
sed -e '/tag: *default/d' -e 's/[0-9]\+:\([0-9a-f]\{40\}\)/\1/'
}
git_log () {
git --git-dir=$1/.git fast-export --branches
git -C $1 fast-export --branches
}
test_cmp_expected () {
test_cmp "$EXPECTED_DIR/$test_id/$1" "$1"
}
cmp_hg_to_git_log () {
hg_log hgrepo2 > hg-log &&
git_log gitrepo > git-log &&
test_cmp_expected hg-log &&
test_cmp_expected git-log
}
cmp_hg_to_git_log_hgrepo1 () {
git_clone hgrepo1 gitrepo &&
hg_clone gitrepo hgrepo2 &&
cmp_hg_to_git_log
}
cmp_hg_to_git_manifest () {
(
hg_clone gitrepo hgrepo &&
cd hgrepo &&
hg_log . &&
eval "$1"
) > output &&
git_clone hgrepo gitrepo2 &&
git_log gitrepo2 > log &&
test_cmp_expected output &&
test_cmp_expected log
}
setup () {
cat > "$HOME"/.hgrc <<-EOF &&
cat > "$HOME"/.hgrc <<-EOF
[ui]
username = A U Thor <author@example.com>
[defaults]
backout = -d "0 0"
commit = -d "0 0"
debugrawcommit = -d "0 0"
tag = -d "0 0"
[extensions]
$hggit =
graphlog =
[git]
debugextrainmessage = 1
EOF
git config --global receive.denycurrentbranch warn
git config --global remote-hg.hg-git-compat true
git config --global remote-hg.track-branches false
git config --global remote-hg.shared-marks false
HGEDITOR=true
HGMERGE=true
cat > "$HOME"/.gitconfig <<-EOF
[remote-hg]
hg-git-compat = true
track-branches = false
EOF
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
export HGEDITOR HGMERGE GIT_AUTHOR_DATE GIT_COMMITTER_DATE
export HGEDITOR=true
export HGMERGE=true
export GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230"
export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
}
setup
test_expect_success 'rename' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
# save old function
eval "old_$(declare -f test_expect_success)"
test_expect_success () {
local req
test "$#" = 3 && { req=$1; shift; } || req=
test_id="$1"
old_test_expect_success "$req" "$1" "
test_when_finished \"rm -rf gitrepo* hgrepo*\" && $2"
}
test_expect_success 'rename' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
@@ -133,21 +134,10 @@ test_expect_success 'rename' '
hg commit -m "rename alpha to beta"
) &&
for x in hg git
do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
cmp_hg_to_git_log_hgrepo1
'
test_expect_success 'executable bit' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
test_expect_success !WIN 'executable bit' '
(
git init -q gitrepo &&
cd gitrepo &&
@@ -163,27 +153,10 @@ test_expect_success 'executable bit' '
git commit -m "clear executable bit"
) &&
for x in hg git
do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -r 1 -v &&
hg manifest -v
) > "output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x > "log-$x"
done &&
test_cmp output-hg output-git &&
test_cmp log-hg log-git
cmp_hg_to_git_manifest "hg manifest -v -r -1; hg manifest -v"
'
test_expect_success 'symlink' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
test_expect_success !WIN 'symlink' '
(
git init -q gitrepo &&
cd gitrepo &&
@@ -195,26 +168,10 @@ test_expect_success 'symlink' '
git commit -m "add beta"
) &&
for x in hg git
do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -v
) > "output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x > "log-$x"
done &&
test_cmp output-hg output-git &&
test_cmp log-hg log-git
cmp_hg_to_git_manifest "hg manifest -v"
'
test_expect_success 'merge conflict 1' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo1 &&
cd hgrepo1 &&
@@ -223,33 +180,22 @@ test_expect_success 'merge conflict 1' '
hg ci -m "origin" &&
echo B > afile &&
hg ci -m "A->B" &&
hg ci -m "A->B" -d "1 0" &&
hg up -r0 &&
echo C > afile &&
hg ci -m "A->C" &&
hg ci -m "A->C" -d "2 0" &&
hg merge -r1 &&
echo C > afile &&
hg resolve -m afile &&
hg ci -m "merge to C"
hg ci -m "merge to C" -d "3 0"
) &&
for x in hg git
do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
cmp_hg_to_git_log_hgrepo1
'
test_expect_success 'merge conflict 2' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo1 &&
cd hgrepo1 &&
@@ -258,33 +204,22 @@ test_expect_success 'merge conflict 2' '
hg ci -m "origin" &&
echo B > afile &&
hg ci -m "A->B" &&
hg ci -m "A->B" -d "1 0" &&
hg up -r0 &&
echo C > afile &&
hg ci -m "A->C" &&
hg ci -m "A->C" -d "2 0" &&
hg merge -r1 || true &&
echo B > afile &&
hg resolve -m afile &&
hg ci -m "merge to B"
hg ci -m "merge to B" -d "3 0"
) &&
for x in hg git
do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
cmp_hg_to_git_log_hgrepo1
'
test_expect_success 'converged merge' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo1 &&
cd hgrepo1 &&
@@ -293,34 +228,23 @@ test_expect_success 'converged merge' '
hg ci -m "origin" &&
echo B > afile &&
hg ci -m "A->B" &&
hg ci -m "A->B" -d "1 0" &&
echo C > afile &&
hg ci -m "B->C" &&
hg ci -m "B->C" -d "2 0" &&
hg up -r0 &&
echo C > afile &&
hg ci -m "A->C" &&
hg ci -m "A->C" -d "3 0" &&
hg merge -r2 || true &&
hg ci -m "merge"
hg ci -m "merge" -d "4 0"
) &&
for x in hg git
do
git_clone_$x hgrepo1 gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
cmp_hg_to_git_log_hgrepo1
'
test_expect_success 'encoding' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
@@ -345,22 +269,17 @@ test_expect_success 'encoding' '
git commit -m "add déltà"
) &&
for x in hg git
do
hg_clone_$x gitrepo hgrepo-$x &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
hg_clone gitrepo hgrepo &&
git_clone hgrepo gitrepo2 &&
HGENCODING=utf-8 hg_log hgrepo-$x > "hg-log-$x" &&
git_log gitrepo2-$x > "git-log-$x"
done &&
HGENCODING=utf-8 hg_log hgrepo > hg-log &&
git_log gitrepo2 > git-log &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
test_cmp_expected hg-log &&
test_cmp_expected git-log
'
test_expect_success 'file removal' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
@@ -380,27 +299,10 @@ test_expect_success 'file removal' '
git commit -m "remove foo/bar"
) &&
for x in hg git
do
(
hg_clone_$x gitrepo hgrepo-$x &&
cd hgrepo-$x &&
hg_log . &&
hg manifest -r 3 &&
hg manifest
) > "output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x > "log-$x"
done &&
test_cmp output-hg output-git &&
test_cmp log-hg log-git
cmp_hg_to_git_manifest "hg manifest -r 3; hg manifest"
'
test_expect_success 'git tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
@@ -416,153 +318,127 @@ test_expect_success 'git tags' '
git tag -a -m "added tag beta" beta
) &&
for x in hg git
do
hg_clone_$x gitrepo hgrepo-$x &&
hg_log hgrepo-$x > "log-$x"
done &&
hg_clone gitrepo hgrepo &&
hg_log hgrepo > log &&
test_cmp log-hg log-git
test_cmp_expected log
'
test_expect_success 'hg author' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
for x in hg git
do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone gitrepo hgrepo &&
cd hgrepo &&
(
hg_clone_$x gitrepo-$x hgrepo-$x &&
cd hgrepo-$x &&
hg co master &&
echo beta > beta &&
hg add beta &&
hg commit -u "test" -m "add beta" &&
hg co master &&
echo beta > beta &&
hg add beta &&
hg commit -u "test" -m "add beta" &&
echo gamma >> beta &&
hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
echo gamma >> beta &&
hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
echo gamma > gamma &&
hg add gamma &&
hg commit -u "<test@example.com>" -m "add gamma" &&
echo gamma > gamma &&
hg add gamma &&
hg commit -u "<test@example.com>" -m "add gamma" &&
echo delta > delta &&
hg add delta &&
hg commit -u "name<test@example.com>" -m "add delta" &&
echo delta > delta &&
hg add delta &&
hg commit -u "name<test@example.com>" -m "add delta" &&
echo epsilon > epsilon &&
hg add epsilon &&
hg commit -u "name <test@example.com" -m "add epsilon" &&
echo epsilon > epsilon &&
hg add epsilon &&
hg commit -u "name <test@example.com" -m "add epsilon" &&
echo zeta > zeta &&
hg add zeta &&
hg commit -u " test " -m "add zeta" &&
echo zeta > zeta &&
hg add zeta &&
hg commit -u " test " -m "add zeta" &&
echo eta > eta &&
hg add eta &&
hg commit -u "test < test@example.com >" -m "add eta" &&
echo eta > eta &&
hg add eta &&
hg commit -u "test < test@example.com >" -m "add eta" &&
echo theta > theta &&
hg add theta &&
hg commit -u "test >test@example.com>" -m "add theta" &&
echo theta > theta &&
hg add theta &&
hg commit -u "test >test@example.com>" -m "add theta" &&
echo iota > iota &&
hg add iota &&
hg commit -u "test <test <at> example <dot> com>" -m "add iota"
) &&
echo iota > iota &&
hg add iota &&
hg commit -u "test <test <at> example <dot> com>" -m "add iota"
) &&
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
hg_push_$x hgrepo-$x gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
cmp_hg_to_git_log
'
test_expect_success 'hg branch' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
for x in hg git
do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha > alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
) &&
echo alpha > alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone gitrepo hgrepo &&
(
hg_clone_$x gitrepo-$x hgrepo-$x &&
cd hgrepo &&
hg -q co master &&
hg mv alpha beta &&
hg -q commit -m "rename alpha to beta" &&
hg branch gamma | grep -v "permanent and global" &&
hg -q commit -m "started branch gamma"
) &&
cd hgrepo-$x &&
hg -q co master &&
hg mv alpha beta &&
hg -q commit -m "rename alpha to beta" &&
hg branch gamma | grep -v "permanent and global" &&
hg -q commit -m "started branch gamma"
) &&
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
hg_push_$x hgrepo-$x gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
test_cmp git-log-hg git-log-git
cmp_hg_to_git_log
'
test_expect_success 'hg tags' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
git init -q gitrepo &&
cd gitrepo &&
for x in hg git
do
(
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
) &&
(
hg_clone gitrepo hgrepo &&
(
hg_clone_$x gitrepo-$x hgrepo-$x &&
cd hgrepo &&
hg co master &&
hg tag alpha
) &&
cd hgrepo-$x &&
hg co master &&
hg tag alpha
) &&
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
hg_push_$x hgrepo-$x gitrepo-$x &&
hg_clone_$x gitrepo-$x hgrepo2-$x &&
(
git -C gitrepo tag -l &&
hg_log hgrepo2 &&
cat hgrepo2/.hgtags
) > output &&
(
git --git-dir=gitrepo-$x/.git tag -l &&
hg_log hgrepo2-$x &&
cat hgrepo2-$x/.hgtags
) > "output-$x"
done &&
test_cmp output-hg output-git
test_cmp_expected output
'
test_done

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
#
# Copyright (c) 2012 Felipe Contreras
#
@@ -8,8 +8,7 @@
test_description='Test remote-hg'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
. "$TEST_DIRECTORY"/test-lib.sh
. ./test-lib.sh
if test "$CAPABILITY_PUSH" = "t"
then
@@ -20,12 +19,6 @@ else
git config --global remote-hg.capability-push false
fi
if ! test_have_prereq PYTHON
then
skip_all='skipping remote-hg tests; python with mercurial not available'
test_done
fi
check () {
echo $3 > expected &&
git --git-dir=$1/.git log --format='%s' -1 $2 > actual &&
@@ -513,7 +506,7 @@ else
test_expect_failure "$testcopyrenamedesc" "$testcopyrename"
fi
test_expect_success 'fetch special filenames' '
test_expect_success !WIN 'fetch special filenames' '
test_when_finished "rm -rf hgrepo gitrepo && LC_ALL=C" &&
LC_ALL=en_US.UTF-8
@@ -652,16 +645,27 @@ test_expect_success 'remote big push' '
(
cd gitrepo &&
check_push 1 --all <<-\EOF
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
if test "$CAPABILITY_PUSH" = "t"
then
# cap push handles refs one by one
# so it will still correctly report several ok
check_push 1 --all <<-\EOF
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
else
check_push 1 --all <<-\EOF
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
fi
) &&
if test "$CAPABILITY_PUSH" = "t"
@@ -675,7 +679,8 @@ test_expect_success 'remote big push' '
check_bookmark hgrepo good_bmark three &&
check_bookmark hgrepo bad_bmark1 one &&
check_bookmark hgrepo bad_bmark2 one &&
check_bookmark hgrepo new_bmark six
check_bookmark hgrepo new_bmark six &&
check gitrepo origin/master two
else
check_branch hgrepo default one &&
check_branch hgrepo good_branch "good branch" &&
@@ -684,7 +689,8 @@ test_expect_success 'remote big push' '
check_bookmark hgrepo good_bmark one &&
check_bookmark hgrepo bad_bmark1 one &&
check_bookmark hgrepo bad_bmark2 one &&
check_bookmark hgrepo new_bmark
check_bookmark hgrepo new_bmark &&
check gitrepo origin/master one
fi
'
@@ -734,12 +740,21 @@ test_expect_success 'remote big push non fast forward' '
echo five > content &&
git commit -q -a -m five &&
check_push 1 --all <<-\EOF &&
master
good_bmark
bad_bmark:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
if test "$CAPABILITY_PUSH" = "t"
then
check_push 1 --all <<-\EOF
master
good_bmark
bad_bmark:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
else
# cap export now only report error cases
check_push 1 --all <<-\EOF
bad_bmark:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
fi &&
git fetch &&
@@ -753,9 +768,8 @@ test_expect_success 'remote big push non fast forward' '
branches/bad_branch:non-fast-forward
EOF
else
# cap export now only report error cases
check_push 1 --all <<-\EOF
master
good_bmark
bad_bmark:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
@@ -797,6 +811,7 @@ test_expect_success 'remote big push force' '
fi
) &&
check gitrepo origin/master two &&
check_branch hgrepo good_branch eight &&
check_branch hgrepo bad_branch nine &&
check_branch hgrepo new_branch ten &&
@@ -814,16 +829,27 @@ test_expect_success 'remote big push dry-run' '
(
cd gitrepo &&
check_push 1 --dry-run --all <<-\EOF &&
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
if test "$CAPABILITY_PUSH" = "t"
then
# cap push handles refs one by one
# so it will still correctly report several ok
check_push 1 --dry-run --all <<-\EOF
master
good_bmark
branches/good_branch
new_bmark:new
branches/new_branch:new
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
else
check_push 1 --dry-run --all <<-\EOF
bad_bmark1:non-fast-forward
bad_bmark2:non-fast-forward
branches/bad_branch:non-fast-forward
EOF
fi &&
check_push 0 --dry-run master good_bmark new_bmark branches/good_branch branches/new_branch <<-\EOF
master
@@ -834,6 +860,7 @@ test_expect_success 'remote big push dry-run' '
EOF
) &&
check gitrepo origin/master one &&
check_branch hgrepo default one &&
check_branch hgrepo good_branch "good branch" &&
check_branch hgrepo bad_branch "bad branch" &&
@@ -878,6 +905,7 @@ test_expect_success 'remote big push force dry-run' '
fi
) &&
check gitrepo origin/master one &&
check_branch hgrepo default one &&
check_branch hgrepo good_branch "good branch" &&
check_branch hgrepo bad_branch "bad branch" &&

View File

@@ -1,8 +1,10 @@
#!/bin/sh
#!/bin/bash
: "${SHARNESS_TEST_SRCDIR:=$(cd "$(dirname "${BASH_SOURCE-$0}")" && pwd)}"
if [ -z "$SHARNESS" ] ; then
for d in \
"." \
"$SHARNESS_TEST_SRCDIR" \
"$HOME/share/sharness" \
"/usr/local/share/sharness" \
"/usr/share/sharness"
@@ -62,7 +64,15 @@ GIT_COMMITTER_EMAIL=committer@example.com
GIT_COMMITTER_NAME='C O Mitter'
export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
# maintain backwards compatible default
# (as used in remote helper)
git config --global init.defaultBranch master
git config --global protocol.file.allow always
unset XDG_CONFIG_HOME
if [[ $(uname -s) = MSYS* ]]; then
test_set_prereq WIN
export TEST_CMP='diff --strip-trailing-cr -u'
fi

View File

@@ -1,22 +1,16 @@
#!/usr/bin/env ruby
#
# Copyright (c) 2019 Felipe Contreras
# Copyright (c) 2019-2023 Felipe Contreras
#
# This script runs the tests for all versions of the components:
# hg, hggit and dulwich
# This script runs the tests for all versions of hg.
#
# You can run it without arguments, in which case it reads the file
# 'versions.txt' and executes all those checks.
# You can run it without arguments, in which case it runs the tests for all
# versions in `versions.txt`.
#
# Or you can pass the versions to check manually, like:
# Or you can specify a single version manually:
#
# ./check-versions hg:4.7 hggit:0.8.12 dulwich:0.19.7
#
# Or you can pass just the hg version, the other versions are fetched from
# 'versions.txt':
#
# ./check-versions hg:5.0
# ./check-versions 6.3
#
require 'fileutils'
@@ -62,46 +56,26 @@ def check_version(a, b)
(a <=> b) >= 0
end
# Component {{{1
# Hg {{{1
class Component
class Hg
attr_reader :id
def initialize(id, url, kind: nil, **args)
@id = id
@url = url
@kind = kind || (url.start_with?('git') ? :git : :hg)
@tool = @kind.to_s
@checkout_fix = args[:checkout_fix]
@version_format = args[:version_format]
def initialize
@url = 'https://www.mercurial-scm.org/repo/hg'
end
def dir
"#{$workdir}/#{@id}"
end
def get_version(version)
return @kind == :hg ? 'tip' : '@' if version == '@'
@version_format ? @version_format % version : version
"#{$workdir}/hg"
end
def clone
run_cmd [@tool, 'clone', '-q', @url, dir]
run_cmd %w[hg clone -q] + [@url, dir]
end
def checkout(version)
Dir.chdir(dir) do
case @kind
when :hg
cmd = %w[update --clean]
when :git
cmd = %w[reset --hard]
else
cmd = %w[checkout]
end
run_cmd [@tool] + cmd + ['-q', get_version(version)]
@checkout_fix.call(version) if @checkout_fix
run_cmd %w[hg update --clean -q] << version
checkout_fix(version)
end
end
@@ -112,6 +86,18 @@ class Component
end
end
def checkout_fix(version)
FileUtils.cp('hg', "#{$builddir}/bin/")
return if check_version(version, '4.3')
if run_cmd %W[hg import -q --no-commit #{__dir__}/hg_setup_hack_2.4.patch], fatal: false
File.write('.hg_force_version', "%s\n" % version)
else
File.write('mercurial/__version__.py', "version = \"%s\"\n" % version)
end
end
end
# Functions {{{1
@@ -121,16 +107,14 @@ def setup
FileUtils.mkdir_p(dirs.map { |e| "#{$builddir}/#{e}" })
FileUtils.mkdir_p($workdir)
$components.each do |id, component|
next if File.exists?(component.dir)
return if File.exist?($hg.dir)
if $verbosity < HIGH
puts "Cloning #{component.id}"
else
title "Cloning #{component.id}"
end
component.clone
if $verbosity < HIGH
puts "Cloning hg"
else
title "Cloning hg"
end
$hg.clone
end
def test_env(paths: nil)
@@ -163,31 +147,14 @@ def run_tests(tests)
end
end
def versions_to_s(versions)
versions.map { |k,v| "#{k}:#{v}" }.join(' ')
end
def check(version)
section version
def versions_from_args(args)
args.map { |e| k, v = e.split(':'); [k.to_sym, v] }.to_h
end
title "Checking out hg #{version}"
$hg.checkout(version)
def versions_from_s(str)
versions_from_args(str.split(' '))
end
def check(versions)
section versions_to_s(versions)
versions.each do |id, version|
component = $components[id]
next unless component
title "Checking out #{component.id} #{version}"
component.checkout(version)
title "Building #{component.id}"
component.build
end
title "Building hg"
$hg.build
paths = {
PATH: "#{$builddir}/bin",
@@ -200,103 +167,31 @@ def check(versions)
end
end
# Add components {{{1
$components = {}
def add_component(id, url, **args)
$components[id] = Component.new(id, url, **args)
end
hg_checkout_fix = lambda do |version|
FileUtils.cp('hg', "#{$builddir}/bin/")
return if check_version(version, '4.3')
if run_cmd %W[hg import -q --no-commit #{__dir__}/hg_setup_hack_2.4.patch], fatal: false
File.write('.hg_force_version', "%s\n" % version)
else
File.write('mercurial/__version__.py', "version = \"%s\"\n" % version)
end
end
add_component(:hg, 'https://www.mercurial-scm.org/repo/hg', checkout_fix: hg_checkout_fix)
hggit_checkout_fix = lambda do |version|
return unless check_version(version, '0.8.0')
run_cmd %W[hg import -q --no-commit #{__dir__}/hggit_rename_fix_0.8.0.patch], fatal: false
end
add_component(:hggit, 'https://bitbucket.org/durin42/hg-git', checkout_fix: hggit_checkout_fix)
add_component(:dulwich, 'https://github.com/dulwich/dulwich.git', version_format: 'dulwich-%s', kind: :git)
def load_checks(file)
file.each do |e|
e.chomp!
next if e.empty? or e.start_with?('#')
content, comment = e.split(' # ')
versions = versions_from_s(content)
$checks << versions
end
end
def store_results(file)
$results.each do |versions, result|
content = versions_to_s(versions)
comment = result ? 'OK' : 'FAIL'
file.puts '%s # %s' % [content, comment]
end
end
$hg = Hg.new()
# Main {{{1
setup
$checks = []
$results = []
$versions = versions_from_args(ARGV)
$version = ARGV.first
$checks = File.readlines(__dir__ + '/versions.txt', chomp: true)
$results = File.open(__dir__ + '/results.txt', 'w')
File.open("#{__dir__}/versions.txt") do |f|
load_checks(f)
end
if $versions.size == 1 and $versions.key?(:hg)
# mode 1
$verbosity = LOW
if ['@', nil].include?($versions[:hg])
versions = $checks.last
versions[:hg] = $versions[:hg] if $versions[:hg]
else
versions = $checks.find { |e| e[:hg] == $versions[:hg] }
exit 1 unless versions
end
exit check(versions) ? 0 : 1
elsif not $versions.empty?
# mode 2
if $version
$verbosity = HIGH
exit check(versions) ? 0 : 1
exit check($version) ? 0 : 1
else
# mode 3
$verbosity = QUIET
at_exit do
File.open("#{__dir__}/results.txt", 'w') do |f|
store_results(f)
end
end
failures = 0
$checks.each do |versions|
result = check(versions)
$checks.each do |version|
result = check(version)
failures += 1 unless result
$results << [versions, result]
$results.puts '%s # %s' % [version, result ? 'OK' : 'FAIL']
end
exit 1 unless failures == 0

View File

@@ -1,22 +0,0 @@
diff --git a/hggit/git_handler.py b/hggit/git_handler.py
--- a/hggit/git_handler.py
+++ b/hggit/git_handler.py
@@ -693,6 +693,8 @@
def import_git_commit(self, commit):
self.ui.debug(_("importing: %s\n") % commit.id)
+ extra_in_message = self.ui.configbool('git', 'debugextrainmessage', False)
+
detect_renames = False
(strip_message, hg_renames,
hg_branch, extra) = git2hg.extract_hg_metadata(
@@ -703,7 +705,8 @@
# renames detected from Git. This is because we export an extra
# 'HG:rename-source' Git parameter when this isn't set, which will
# break bidirectionality.
- extra['hg-git-rename-source'] = 'git'
+ if not extra_in_message:
+ extra['hg-git-rename-source'] = 'git'
else:
renames = hg_renames

View File

@@ -1,33 +1,46 @@
# vi: ft=ruby
hg:2.4 hggit:0.4.0 dulwich:0.9.0 # 2013_02
hg:2.5 hggit:0.4.0 dulwich:0.9.0 # 2013_02
hg:2.6 hggit:0.4.0 dulwich:0.9.0 # 2013_02
hg:2.7 hggit:0.4.0 dulwich:0.9.0 # 2013_02
hg:2.8 hggit:0.4.0 dulwich:0.9.0 # 2013_02
hg:2.9 hggit:0.4.0 dulwich:0.9.0 # 2013_02
hg:3.0 hggit:0.7.0 dulwich:0.10.0 # 2014_11
hg:3.1 hggit:0.7.0 dulwich:0.10.0 # 2014_11
hg:3.2 hggit:0.7.0 dulwich:0.10.0 # 2014_11
hg:3.3 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:3.4 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:3.5 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:3.6 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:3.7 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:3.8 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:3.9 hggit:0.8.4 dulwich:0.13.0 # 2016_01
hg:4.0 hggit:0.8.10 dulwich:0.18.0 # 2017_11
hg:4.1 hggit:0.8.10 dulwich:0.18.0 # 2017_11
hg:4.2 hggit:0.8.10 dulwich:0.18.0 # 2017_11
hg:4.3 hggit:0.8.10 dulwich:0.18.0 # 2017_11
hg:4.4 hggit:0.8.10 dulwich:0.18.0 # 2017_11
hg:4.5 hggit:0.8.11 dulwich:0.18.0 # 2018_02
hg:4.6 hggit:0.8.12 dulwich:0.19.7 # 2018_10
hg:4.7 hggit:0.8.12 dulwich:0.19.7 # 2018_10
hg:4.8 hggit:@ dulwich:0.19.11
hg:4.9 hggit:@ dulwich:0.19.11
hg:5.0 hggit:@ dulwich:0.19.11
2.4
2.5
2.6
2.7
2.8
2.9
3.0
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
4.0
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
5.0
5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
5.9
6.0
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9