50 Commits
v0.1 ... v0.3

Author SHA1 Message Date
Felipe Contreras
b6e9475918 readme: mention Mercurial dependency
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 23:37:08 -05:00
Lars Noschinski
517ceb91ac Fix import of broken committers
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 22:44:49 -05:00
Felipe Contreras
114804f0cb travis: add more Mercurial versions
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 22:29:50 -05:00
Felipe Contreras
b022367aef test: temporarily disable hg-git tests
They work, but they need too many changes in different packages.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 22:29:50 -05:00
Felipe Contreras
18626d346f Revert "test: use C.UTF-8 locale in tests"
This reverts commit f53a8653ab.

It turns out Debian and Fedora do provide the C.UTF-8 locale, but other
distributions don't.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 22:29:50 -05:00
Felipe Contreras
b81ec14c2e Improve hg-git compatibility
Recent versions of Mercurial check if a filectx is the same as the
parents, and avoid creating a new filelog. This is what we want, but
hg-git doesn't do that.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 22:29:50 -05:00
Felipe Contreras
1e279075dc Add compatibility for Mercurial v3.2
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 22:29:50 -05:00
Felipe Contreras
02a0a59a4b travis: force version of hg-git
The latest that works.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2016-05-16 17:56:25 -05:00
Felipe Contreras
185852eac4 test: cleanup hg-git test
We don't need hgext.bookmarks since a long long time (ever).

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-06-03 06:00:02 -05:00
Felipe Contreras
29a0d8a0e3 test: skip tests with broken hg-git compatibility
https://bitbucket.org/durin42/hg-git/issue/115/

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-06-02 18:42:17 -05:00
Felipe Contreras
aa528c9649 Fix memfilectx API change
It will change in 3.1.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-06-02 17:49:56 -05:00
Felipe Contreras
018aa4753b Improve version parsing
Development versions have extra stuff in the form of
'version+distance-id'.

Let's assume we are already in the next major version when in
development.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-06-02 17:49:29 -05:00
Felipe Contreras
f173208406 build: don't install docs by default
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-31 15:58:33 -05:00
Felipe Contreras
e7df347fab readme: fix not about v2.0
It didn't get in.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-31 15:49:28 -05:00
Brian Gernhardt
0de8aa91f4 build: avoid non-portable install -D
BSD install doesn't understand the -D option. Use a separate install
command to create the directory (with the -d option) before installing
the file.

Signed-off-by: Brian Gernhardt <brian@gernhardtsoftware.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-31 15:41:28 -05:00
Paul Wise
22d9794c11 test: add compatibility with Debian hg-git package
Debian has named the hggit python module as hgext.git.

Signed-off-by: Paul Wise <pabs3@bonedaddy.net>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-30 17:37:01 -05:00
Paul Wise
f53a8653ab test: use C.UTF-8 locale in tests
The en_US.UTF-8 locale is not guaranteed to exist, and if it doesn't,
several tests fail.

Signed-off-by: Paul Wise <pabs3@bonedaddy.net>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-30 17:37:01 -05:00
Paul Wise
b4c63539f2 Ignore the generated manual page
Signed-off-by: Paul Wise <pabs3@bonedaddy.net>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-30 17:37:01 -05:00
Paul Wise
38070007aa build: general improvements
Allow customising the bin and manual page dirs.

Signed-off-by: Paul Wise <pabs3@bonedaddy.net>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-30 17:37:01 -05:00
Felipe Contreras
fadd5f698b test: improve test locations
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-22 22:09:28 -05:00
Felipe Contreras
1eb8fa4805 readme: add contributing section
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-13 14:26:45 -05:00
Felipe Contreras
19f31c1c84 doc: add help for sending patches
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-13 14:26:32 -05:00
Felipe Contreras
ff221de459 Split multiple import lines
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-10 23:54:33 -05:00
Felipe Contreras
179fefda96 More pep8 fixes
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-10 23:49:49 -05:00
Felipe Contreras
c226ba3904 remote-hg,bzr: conform more to pep8
Reported-by: William Giokas <1007380@gmail.com>

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-10 01:01:20 -05:00
Felipe Contreras
776e36c147 build: fix install location
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 10:29:52 -05:00
Felipe Contreras
5b6d5283cb Use python2 instead of python
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 09:11:14 -05:00
Felipe Contreras
5738ee42d8 test: add missing redirection
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 09:10:57 -05:00
Felipe Contreras
1d27390dd0 readme: fix link location
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 09:09:16 -05:00
Felipe Contreras
cad5c95465 travis: add initial configuration
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 09:04:31 -05:00
Felipe Contreras
259838a342 test: fix redirection style
To be sane, a redirection operation has to have spaces, like any binary
operand: 'a > b'.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:55:51 -05:00
Felipe Contreras
55bbd81a75 test: trivial style cleanups
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:49:30 -05:00
Felipe Contreras
8db5b9a537 Add support for hg v3.0
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
bbc4009acf test: trivial cleanups and fixes
There was a broken && chain, and cat is simpler than echo in a subshell.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
c84feb364b test: dd file operation tests
Inspired by gitifyhg.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
990152c0c8 Add more tests
Inspired by the tests in gitifyhg.

One test is failing, but that's because of a limitation of
remote-helpers.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
6ba42cdf98 Simplify hg-git regex
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
ef00e40d7c remote-hg: make sure we omit multiple heads
We want to ignore secondary heads, otherwise we will import revisions
that won't have any ref pointing to them and might eventually be pruned,
which would cause problems with the synchronization of marks.

This can only be expressed properly as '::b - ::a', but that's not
efficient, specially in older versions of Mercurial.
'ancestor(a,b)::b - ancestor(a,b)::a' might be better, but it's not
particularly pretty. Mercurial v3.0 will have a new 'only(b, a)' that
does the same, but that hasn't even been released yet. Either way all of
these require repo.revs() which is only available after Mercurial v2.1.

Also, we would need special considerations for when there's no base
revision (importing from root).

It's much better to implement our own function to get a range of
revisions.

The new gitrange() is inspired by Mercurial's revset.missingancestors().

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Max Horn
1c72617831 Do not fail on invalid bookmarks
Mercurial can have bookmarks pointing to "nullid" (the empty root
revision), while Git can not have references to it.

Warn the user about the invalid reference, and do not advertise these
bookmarks as head refs, but otherwise continue the import. In
particular, we still keep track of the fact that the remote repository
has a bookmark of the given name, in case the user wants to modify that
bookmark.

Reported-by: Antoine Pelisse <apelisse@gmail.com>
Signed-off-by: Max Horn <max@quendi.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Daniel Liew
184551c71d Use internal clone's hgrc
Use the hgrc configuration file in the internal mercurial repository in
addition to the other system wide hgrc files. This is done by using the
'ui' object from the 'repository' object which will have loaded the
repository hgrc file if it exists.

Signed-off-by: Dan Liew <delcypher@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
32d4f36f22 test: split into setup test
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
ccb3f13d69 Properly detect missing contexts
This can happen when there's a synchronization issue between marks-git
and marks-hg; a key is missing in marks-hg, and when we receive a reset
command the value of ctx basically comes from None.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:07 -05:00
Felipe Contreras
2958556bec Store marks only on success
Commit 2594a79 (remote-hg: fix bad state issue) originally introduced
this code in order to avoid synchronization issues while pushing,
because `git fast-export` might end up writing the marks before a crash
in the remote helper occurs.

However, the problem is in `git fast-export`; the marks should only be
written after both have finished successfully.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:06 -05:00
Felipe Contreras
4ea2fa76b3 Update to 'public' phase when pushing
This is what Mercurial does.

Reported-by: Nathan Palmer
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:06 -05:00
Felipe Contreras
84b8b482a4 Fix parsing of custom committer
Other tools use the 'committer' extra field differently, so let's make
the parsing more reliable and don't assume it's in a certain format.

Reported-by: Kevin Cox <kevincox@kevincox.ca>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:06 -05:00
Felipe Contreras
978314a4be Always normalize paths
Apparently Mercurial can have paths such as 'foo//bar', so normalize all
paths.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:43:06 -05:00
Felipe Contreras
51eabd4a17 doc: add manpage
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:41:57 -05:00
Felipe Contreras
98c3535c3f build: add install target
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:41:57 -05:00
Felipe Contreras
3abf376e9e Add README
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:36:33 -05:00
Felipe Contreras
0b71ca38e7 Reorganize tests
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
2014-05-09 08:33:07 -05:00
12 changed files with 887 additions and 219 deletions

28
.travis.yml Normal file
View File

@@ -0,0 +1,28 @@
language: python
install:
- if [ "$HG_VERSION" != "dev" ];
then pip install -q Mercurial${HG_VERSION+==$HG_VERSION};
else pip install -q http://selenic.com/repo/hg/archive/tip.tar.gz;
fi
- pip install -q dulwich hg-git==0.6.1 || true
before_script:
- hg --version || true
- pip show hg-git dulwich
script:
- make test
matrix:
include:
- env: HG_VERSION=2.9.1
- env: HG_VERSION=2.8.2
- env: HG_VERSION=2.7.2
- env: HG_VERSION=3.0
- env: HG_VERSION=3.5.2
- env: HG_VERSION=3.6.3
- env: HG_VERSION=3.7
- env: HG_VERSION=dev
- python: 2.7
- python: 2.6

View File

@@ -1,6 +1,29 @@
all:
prefix := $(HOME)
bindir := $(prefix)/bin
mandir := $(prefix)/share/man/man1
all: doc
doc: doc/git-remote-hg.1
test:
$(MAKE) -C test
.PHONY: all test
doc/git-remote-hg.1: doc/git-remote-hg.txt
a2x -d manpage -f manpage $<
clean:
$(RM) doc/git-remote-hg.1
D = $(DESTDIR)
install:
install -d -m 755 $(D)$(bindir)/
install -m 755 git-remote-hg $(D)$(bindir)/git-remote-hg
install-doc: doc
install -d -m 755 $(D)$(mandir)/
install -m 644 doc/git-remote-hg.1 $(D)$(mandir)/git-remote-hg.1
.PHONY: all test install install-doc clean

131
README.asciidoc Normal file
View File

@@ -0,0 +1,131 @@
'git-remote-hg' is the semi-official Mercurial bridge from Git project, once
installed, it allows you to clone, fetch and push to and from Mercurial
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`:
--------------------------------------
wget https://raw.github.com/felipec/git-remote-hg/master/git-remote-hg -O ~/bin/git-remote-hg
chmod +x ~/bin/git-remote-hg
--------------------------------------
That's it :)
Obviously you will need Mercurial installed.
== Configuration ==
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):
--------------------------------------
% git config --global remote-hg.track-branches false
--------------------------------------
With this configuration, the 'branches/foo' refs won't appear.
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:
--------------------------------------
% git config --global remote-hg.hg-git-compat true
--------------------------------------
== Notes ==
Remember to run `git gc --aggressive` after cloning a repository, specially 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.
=== Pushing branches ===
To push a branch, you need to use the "branches/" prefix:
--------------------------------------
% git checkout branches/next
# do stuff
% git push origin branches/next
--------------------------------------
All the pushed commits will receive the "next" Mercurial named branch.
*Note*: Make sure you don't have +remote-hg.track-branches+ disabled.
=== Cloning HTTPS ===
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]:
--------------------------------------
[auth]
bb.prefix = https://bitbucket.org/user/
bb.username = user
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.
=== Caveats ===
The only major incompatibility is that Git octopus merges (a merge with more
than two parents) are not supported.
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
would only see the latest head.
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]).
Limitations of the remote-helpers' framework apply. In particular, these
commands don't work:
* `git push origin :branch-to-delete`
* `git push origin old:new` (it will push 'old') (patches available)
* `git push --dry-run origin branch` (it will push) (patches available)
== 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:
* 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]
For a comparison between these and other projects go
https://github.com/felipec/git/wiki/Comparison-of-git-remote-hg-alternatives[here].
== Contributing ==
Send your patches to the mailing list git-fc@googlegroups.com (no need to
subscribe).

1
doc/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
git-remote-hg.1

5
doc/SubmittingPatches Normal file
View File

@@ -0,0 +1,5 @@
Please send your patches using `git format-patch` to the mailing list:
git-fc@googlegroups.com.
Make sure all the tests pass by running `make test`, and if possible add a new
test to exercise the code you are submitting.

121
doc/git-remote-hg.txt Normal file
View File

@@ -0,0 +1,121 @@
git-remote-hg(1)
================
NAME
----
git-remote-hg - bidirectional bridge between Git and Mercurial
SYNOPSIS
--------
[verse]
'git clone' hg::<hg repository>
DESCRIPTION
-----------
This tool allows you to transparently clone, fetch and push to and from Mercurial
repositories as if they were Git ones.
To use it you simply need to use the "'hg::'" prefix when specifying a remote URL
(e.g. when cloning).
EXAMPLE
-------
------------
$ git clone hg::http://selenic.com/repo/hello
------------
CONFIGURATION
-------------
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):
--------------------------------------
% git config --global remote-hg.track-branches false
--------------------------------------
With this configuration, the 'branches/foo' refs won't appear.
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:
--------------------------------------
% git config --global remote-hg.hg-git-compat true
--------------------------------------
NOTES
-----
Remember to run `git gc --aggressive` after cloning a repository, specially 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.
Pushing branches
~~~~~~~~~~~~~~~~
To push a Mercurial named branch, you need to use the "branches/" prefix:
--------------------------------------
% git checkout branches/next
# do stuff
% git push origin branches/next
--------------------------------------
All the pushed commits will receive the "next" Mercurial named branch.
*Note*: Make sure you don't have +remote-hg.track-branches+ disabled.
Cloning HTTPS
~~~~~~~~~~~~~
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]:
--------------------------------------
[auth]
bb.prefix = https://bitbucket.org/user/
bb.username = user
bb.password = password
--------------------------------------
Finally, you can also use the
https://pypi.python.org/pypi/mercurial_keyring[keyring extension].
CAVEATS
-------
The only major incompatibility is that Git octopus merges (a merge with more
than two parents) are not supported.
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
would only see the latest head.
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

@@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python2
#
# Copyright (c) 2012 Felipe Contreras
#
@@ -12,7 +12,9 @@
# For remote repositories a local clone is stored in
# "$GIT_DIR/hg/origin/clone/.hg/".
from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions, discovery, util
from mercurial import hg, ui, bookmarks, context, encoding
from mercurial import node, error, extensions, discovery, util
from mercurial import changegroup
import re
import sys
@@ -22,7 +24,8 @@ import shutil
import subprocess
import urllib
import atexit
import urlparse, hashlib
import urlparse
import hashlib
import time as ptime
#
@@ -53,7 +56,7 @@ import time as ptime
NAME_RE = re.compile('^([^<>]+)')
AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')
EMAIL_RE = re.compile(r'([^ \t<>]+@[^ \t<>]+)')
AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$')
AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.*))?$')
RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)')
VERSION = 2
@@ -156,7 +159,9 @@ class Marks:
self.version = 2
def dict(self):
return { 'tips': self.tips, 'marks': self.marks, 'last-mark' : self.last_mark, 'version' : self.version, 'last-note' : self.last_note }
return { 'tips': self.tips, 'marks': self.marks,
'last-mark': self.last_mark, 'version': self.version,
'last-note': self.last_note }
def store(self):
json.dump(self.dict(), open(self.path, 'w'))
@@ -260,6 +265,7 @@ class Parser:
return (user, int(date), -tz)
def fix_file_path(path):
path = os.path.normpath(path)
if not os.path.isabs(path):
return path
return os.path.relpath(path, '/')
@@ -421,10 +427,15 @@ def get_repo(url, alias):
repo = hg.repository(myui, local_path)
try:
peer = hg.peer(myui, {}, url)
peer = hg.peer(repo.ui, {}, url)
except:
die('Repository error')
repo.pull(peer, heads=None, force=True)
if check_version(3, 0):
from mercurial import exchange
exchange.pull(repo, peer, heads=None, force=True)
else:
repo.pull(peer, heads=None, force=True)
updatebookmarks(repo, peer)
@@ -436,16 +447,46 @@ def rev_to_mark(rev):
def mark_to_rev(mark):
return marks.to_rev(mark)
# Get a range of revisions in the form of a..b (git committish)
def gitrange(repo, a, b):
positive = []
pending = set([int(b)])
negative = set([int(a)])
for cur in xrange(b, -1, -1):
if not pending:
break
parents = [p for p in repo.changelog.parentrevs(cur) if p >= 0]
if cur in pending:
positive.append(cur)
pending.remove(cur)
for p in parents:
if p not in negative:
pending.add(p)
elif cur in negative:
negative.remove(cur)
for p in parents:
if p not in pending:
negative.add(p)
else:
pending.discard(p)
positive.reverse()
return positive
def export_ref(repo, name, kind, head):
ename = '%s/%s' % (kind, name)
try:
tip = marks.get_tip(ename)
tip = repo[tip].rev()
tip = repo[tip]
except:
tip = 0
tip = repo[-1]
revs = gitrange(repo, tip, head)
revs = xrange(tip, head.rev() + 1)
total = len(revs)
tip = tip.rev()
for rev in revs:
@@ -460,8 +501,12 @@ def export_ref(repo, name, kind, head):
author = "%s %d %s" % (fixup_user(user), time, gittz(tz))
if 'committer' in extra:
user, time, tz = extra['committer'].rsplit(' ', 2)
committer = "%s %s %s" % (user, time, gittz(int(tz)))
try:
cuser, ctime, ctz = extra['committer'].rsplit(' ', 2)
committer = "%s %s %s" % (fixup_user(cuser), ctime, gittz(int(ctz)))
except ValueError:
cuser = extra['committer']
committer = "%s %d %s" % (fixup_user(cuser), time, gittz(tz))
else:
committer = author
@@ -614,7 +659,7 @@ def list_head(repo, cur):
return
node = repo[branch_tip('default')]
head = 'master' if not 'master' in bmarks else 'default'
head = 'master' if 'master' not in bmarks else 'default'
fake_bmark = head
bmarks[head] = node
@@ -643,7 +688,10 @@ def do_list(parser):
print "? refs/heads/branches/%s" % gitref(branch)
for bmark in bmarks:
print "? refs/heads/%s" % gitref(bmark)
if bmarks[bmark].hex() == '0' * 40:
warn("Ignoring invalid bookmark '%s'", bmark)
else:
print "? refs/heads/%s" % gitref(bmark)
for tag, node in repo.tagslist():
if tag == 'tip':
@@ -702,7 +750,7 @@ def get_merge_files(repo, p1, p2, files):
if e not in files:
if e not in repo[p1].manifest():
continue
f = { 'ctx' : repo[p1][e] }
f = { 'ctx': repo[p1][e] }
files[e] = f
def c_style_unescape(string):
@@ -743,10 +791,10 @@ def parse_commit(parser):
if parser.check('M'):
t, m, mark_ref, path = line.split(' ', 3)
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'):
t, path = line.split(' ', 1)
f = { 'deleted' : True }
f = { 'deleted': True }
else:
die('Unknown file command: %s' % line)
path = c_style_unescape(path)
@@ -760,14 +808,32 @@ def parse_commit(parser):
def getfilectx(repo, memctx, f):
of = files[f]
if 'deleted' in of:
raise IOError
if check_version(3, 2):
return None
else:
raise IOError
if 'ctx' in of:
return of['ctx']
if mode == 'hg':
ctx = of['ctx']
is_exec = ctx.isexec()
is_link = ctx.islink()
if check_version(3, 1):
return context.memfilectx(repo, f, ctx.data(),
is_link, is_exec)
else:
return context.memfilectx(f, ctx.data(),
is_link, is_exec)
else:
return of['ctx']
is_exec = of['mode'] == 'x'
is_link = of['mode'] == 'l'
rename = of.get('rename', None)
return context.memfilectx(f, of['data'],
is_link, is_exec, rename)
if check_version(3, 1):
return context.memfilectx(repo, f, of['data'],
is_link, is_exec, rename)
else:
return context.memfilectx(f, of['data'],
is_link, is_exec, rename)
repo = parser.repo
@@ -870,7 +936,10 @@ def write_tag(repo, tag, node, msg, author):
except error.ManifestLookupError:
data = ""
content = data + "%s %s\n" % (node, tag)
return context.memfilectx(f, content, False, False, None)
if check_version(3, 1):
return context.memfilectx(repo, f, content, False, False, None)
else:
return context.memfilectx(f, content, False, False, None)
p1 = tip.hex()
p2 = '0' * 40
@@ -890,7 +959,7 @@ def write_tag(repo, tag, node, msg, author):
ctx = context.memctx(repo, (p1, p2), msg,
['.hgtags'], getfilectx,
user, date_tz, {'branch' : branch})
user, date_tz, {'branch': branch})
tmp = encoding.encoding
encoding.encoding = 'utf-8'
@@ -903,12 +972,17 @@ def write_tag(repo, tag, node, msg, author):
def checkheads_bmark(repo, ref, ctx):
bmark = ref[len('refs/heads/'):]
if not bmark in bmarks:
if bmark not in bmarks:
# new bmark
return True
ctx_old = bmarks[bmark]
ctx_new = ctx
if not ctx.rev():
print "error %s unknown" % ref
return False
if not repo.changelog.descendant(ctx_old.rev(), ctx_new.rev()):
if force_push:
print "ok %s forced update" % ref
@@ -931,7 +1005,7 @@ def checkheads(repo, remote, p_revs):
for node, ref in p_revs.iteritems():
ctx = repo[node]
branch = ctx.branch()
if not branch in remotemap:
if branch not in remotemap:
# new branch
continue
if not ref.startswith('refs/heads/branches'):
@@ -981,15 +1055,28 @@ def push_unsafe(repo, remote, parsed_refs, p_revs):
if not checkheads(repo, remote, p_revs):
return None
cg = repo.getbundle('push', heads=list(p_revs), common=common)
if check_version(3, 2):
cg = changegroup.getchangegroup(repo, 'push', heads=list(p_revs), common=common)
elif check_version(3, 0):
cg = changegroup.getbundle(repo, 'push', heads=list(p_revs), common=common)
else:
cg = repo.getbundle('push', heads=list(p_revs), common=common)
unbundle = remote.capable('unbundle')
if unbundle:
if force:
remoteheads = ['force']
return remote.unbundle(cg, remoteheads, 'push')
ret = remote.unbundle(cg, remoteheads, 'push')
else:
return remote.addchangegroup(cg, 'push', repo.url())
ret = remote.addchangegroup(cg, 'push', repo.url())
phases = remote.listkeys('phases')
if phases:
for head in p_revs:
# update to public
remote.pushkey('phases', hghex(head), '1', '0')
return ret
def push(repo, remote, parsed_refs, p_revs):
if hasattr(remote, 'canpush') and not remote.canpush():
@@ -1207,7 +1294,11 @@ def main(args):
filenodes = {}
fake_bmark = None
try:
hg_version = tuple(int(e) for e in util.version().split('.'))
version, _, extra = util.version().partition('+')
version = list(int(e) for e in version.split('.'))
if extra:
version[1] += 1
hg_version = tuple(version)
except:
hg_version = None
dry_run = False
@@ -1242,12 +1333,10 @@ def main(args):
die('unhandled command: %s' % line)
sys.stdout.flush()
marks.store()
def bye():
if not marks:
return
if not is_tmp:
marks.store()
else:
if is_tmp:
shutil.rmtree(dirname)
atexit.register(bye)

3
test/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
test-results/
trash directory.*/
.prove

View File

@@ -1,6 +1,6 @@
RM ?= rm -f
T = $(wildcard ../test-*.sh)
T = main.t bidi.t
TEST_DIRECTORY := $(CURDIR)
export TEST_DIRECTORY

View File

@@ -8,7 +8,8 @@
test_description='Test bidirectionality of remote-hg'
. ./test-lib.sh
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
@@ -16,7 +17,7 @@ then
test_done
fi
if ! python -c 'import mercurial'
if ! python2 -c 'import mercurial' > /dev/null 2>&1
then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
@@ -45,7 +46,7 @@ hg_push () {
git checkout -q -b tmp &&
git fetch -q "hg::../$1" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' &&
git checkout -q @{-1} &&
git branch -q -D tmp 2>/dev/null || true
git branch -q -D tmp 2> /dev/null || true
)
}
@@ -54,17 +55,17 @@ hg_log () {
}
setup () {
(
echo "[ui]"
echo "username = A U Thor <author@example.com>"
echo "[defaults]"
echo "backout = -d \"0 0\""
echo "commit = -d \"0 0\""
echo "debugrawcommit = -d \"0 0\""
echo "tag = -d \"0 0\""
echo "[extensions]"
echo "graphlog ="
) >>"$HOME"/.hgrc &&
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]"
graphlog =
EOF
git config --global remote-hg.hg-git-compat true
git config --global remote-hg.track-branches true
@@ -83,22 +84,22 @@ test_expect_success 'encoding' '
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add älphà" &&
GIT_AUTHOR_NAME="tést èncödîng" &&
export GIT_AUTHOR_NAME &&
echo beta >beta &&
echo beta > beta &&
git add beta &&
git commit -m "add beta" &&
echo gamma >gamma &&
echo gamma > gamma &&
git add gamma &&
git commit -m "add gämmâ" &&
: TODO git config i18n.commitencoding latin-1 &&
echo delta >delta &&
echo delta > delta &&
git add delta &&
git commit -m "add déltà"
) &&
@@ -107,8 +108,8 @@ test_expect_success 'encoding' '
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
HGENCODING=utf-8 hg_log hgrepo >expected &&
HGENCODING=utf-8 hg_log hgrepo2 >actual &&
HGENCODING=utf-8 hg_log hgrepo > expected &&
HGENCODING=utf-8 hg_log hgrepo2 > actual &&
test_cmp expected actual
'
@@ -119,14 +120,14 @@ test_expect_success 'file removal' '
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
echo beta >beta &&
echo beta > beta &&
git add beta &&
git commit -m "add beta"
mkdir foo &&
echo blah >foo/bar &&
echo blah > foo/bar &&
git add foo &&
git commit -m "add foo" &&
git rm alpha &&
@@ -139,8 +140,8 @@ test_expect_success 'file removal' '
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
hg_log hgrepo > expected &&
hg_log hgrepo2 > actual &&
test_cmp expected actual
'
@@ -152,12 +153,12 @@ test_expect_success 'git tags' '
git init -q gitrepo &&
cd gitrepo &&
git config receive.denyCurrentBranch ignore &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git tag alpha &&
echo beta >beta &&
echo beta > beta &&
git add beta &&
git commit -m "add beta" &&
git tag -a -m "added tag beta" beta
@@ -167,8 +168,8 @@ test_expect_success 'git tags' '
git_clone hgrepo gitrepo2 &&
hg_clone gitrepo2 hgrepo2 &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
hg_log hgrepo > expected &&
hg_log hgrepo2 > actual &&
test_cmp expected actual
'
@@ -180,7 +181,7 @@ test_expect_success 'hg branch' '
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
@@ -203,8 +204,8 @@ test_expect_success 'hg branch' '
: Back to the common revision &&
(cd hgrepo && hg checkout default) &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
hg_log hgrepo > expected &&
hg_log hgrepo2 > actual &&
test_cmp expected actual
'
@@ -216,7 +217,7 @@ test_expect_success 'hg tags' '
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
@@ -233,8 +234,8 @@ test_expect_success 'hg tags' '
hg_push hgrepo gitrepo &&
hg_clone gitrepo hgrepo2 &&
hg_log hgrepo >expected &&
hg_log hgrepo2 >actual &&
hg_log hgrepo > expected &&
hg_log hgrepo2 > actual &&
test_cmp expected actual
'

View File

@@ -8,7 +8,8 @@
test_description='Test remote-hg output compared to hg-git'
. ./test-lib.sh
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
then
@@ -16,18 +17,32 @@ then
test_done
fi
if ! python -c 'import mercurial'
if ! python2 -c 'import mercurial' > /dev/null 2>&1
then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
if ! python -c 'import hggit'
if python2 -c 'import hggit' > /dev/null 2>&1
then
hggit=hggit
elif python2 -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
hg_version=$(python2 -c 'from mercurial import util; print util.version()')
case $hg_version in
3.0*+*)
skip_all='skipping remote-hg tests; unsuported version of hg by hg-git'
test_done
;;
esac
# clone to a git repo with git
git_clone_git () {
git clone -q "hg::$1" $2 &&
@@ -69,7 +84,7 @@ hg_push_git () {
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
git branch -q -D tmp 2> /dev/null || true
)
}
@@ -82,7 +97,7 @@ hg_push_hg () {
}
hg_log () {
hg -R $1 log --graph --debug >log &&
hg -R $1 log --graph --debug > log &&
grep -v 'tag: *default/' log
}
@@ -91,19 +106,18 @@ git_log () {
}
setup () {
(
echo "[ui]"
echo "username = A U Thor <author@example.com>"
echo "[defaults]"
echo "backout = -d \"0 0\""
echo "commit = -d \"0 0\""
echo "debugrawcommit = -d \"0 0\""
echo "tag = -d \"0 0\""
echo "[extensions]"
echo "hgext.bookmarks ="
echo "hggit ="
echo "graphlog ="
) >>"$HOME"/.hgrc &&
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 =
EOF
git config --global receive.denycurrentbranch warn
git config --global remote-hg.hg-git-compat true
git config --global remote-hg.track-branches false
@@ -124,7 +138,7 @@ test_expect_success 'executable bit' '
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
chmod 0644 alpha &&
git add alpha &&
git commit -m "add alpha" &&
@@ -144,10 +158,10 @@ test_expect_success 'executable bit' '
hg_log . &&
hg manifest -r 1 -v &&
hg manifest -v
) >"output-$x" &&
) > "output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x >"log-$x"
git_log gitrepo2-$x > "log-$x"
done &&
test_cmp output-hg output-git &&
@@ -160,7 +174,7 @@ test_expect_success 'symlink' '
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
ln -s alpha beta &&
@@ -175,10 +189,10 @@ test_expect_success 'symlink' '
cd hgrepo-$x &&
hg_log . &&
hg manifest -v
) >"output-$x" &&
) > "output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x >"log-$x"
git_log gitrepo2-$x > "log-$x"
done &&
test_cmp output-hg output-git &&
@@ -191,19 +205,19 @@ test_expect_success 'merge conflict 1' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
echo A >afile &&
echo A > afile &&
hg add afile &&
hg ci -m "origin" &&
echo B >afile &&
echo B > afile &&
hg ci -m "A->B" &&
hg up -r0 &&
echo C >afile &&
echo C > afile &&
hg ci -m "A->C" &&
hg merge -r1 &&
echo C >afile &&
echo C > afile &&
hg resolve -m afile &&
hg ci -m "merge to C"
) &&
@@ -212,8 +226,8 @@ test_expect_success 'merge conflict 1' '
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"
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -226,19 +240,19 @@ test_expect_success 'merge conflict 2' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
echo A >afile &&
echo A > afile &&
hg add afile &&
hg ci -m "origin" &&
echo B >afile &&
echo B > afile &&
hg ci -m "A->B" &&
hg up -r0 &&
echo C >afile &&
echo C > afile &&
hg ci -m "A->C" &&
hg merge -r1 || true &&
echo B >afile &&
echo B > afile &&
hg resolve -m afile &&
hg ci -m "merge to B"
) &&
@@ -247,8 +261,8 @@ test_expect_success 'merge conflict 2' '
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"
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -261,18 +275,18 @@ test_expect_success 'converged merge' '
(
hg init hgrepo1 &&
cd hgrepo1 &&
echo A >afile &&
echo A > afile &&
hg add afile &&
hg ci -m "origin" &&
echo B >afile &&
echo B > afile &&
hg ci -m "A->B" &&
echo C >afile &&
echo C > afile &&
hg ci -m "B->C" &&
hg up -r0 &&
echo C >afile &&
echo C > afile &&
hg ci -m "A->C" &&
hg merge -r2 || true &&
@@ -283,8 +297,8 @@ test_expect_success 'converged merge' '
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"
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -298,22 +312,22 @@ test_expect_success 'encoding' '
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add älphà" &&
GIT_AUTHOR_NAME="tést èncödîng" &&
export GIT_AUTHOR_NAME &&
echo beta >beta &&
echo beta > beta &&
git add beta &&
git commit -m "add beta" &&
echo gamma >gamma &&
echo gamma > gamma &&
git add gamma &&
git commit -m "add gämmâ" &&
: TODO git config i18n.commitencoding latin-1 &&
echo delta >delta &&
echo delta > delta &&
git add delta &&
git commit -m "add déltà"
) &&
@@ -323,8 +337,8 @@ test_expect_success 'encoding' '
hg_clone_$x gitrepo hgrepo-$x &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
HGENCODING=utf-8 hg_log hgrepo-$x >"hg-log-$x" &&
git_log gitrepo2-$x >"git-log-$x"
HGENCODING=utf-8 hg_log hgrepo-$x > "hg-log-$x" &&
git_log gitrepo2-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -337,14 +351,14 @@ test_expect_success 'file removal' '
(
git init -q gitrepo &&
cd gitrepo &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
echo beta >beta &&
echo beta > beta &&
git add beta &&
git commit -m "add beta"
mkdir foo &&
echo blah >foo/bar &&
echo blah > foo/bar &&
git add foo &&
git commit -m "add foo" &&
git rm alpha &&
@@ -361,10 +375,10 @@ test_expect_success 'file removal' '
hg_log . &&
hg manifest -r 3 &&
hg manifest
) >"output-$x" &&
) > "output-$x" &&
git_clone_$x hgrepo-$x gitrepo2-$x &&
git_log gitrepo2-$x >"log-$x"
git_log gitrepo2-$x > "log-$x"
done &&
test_cmp output-hg output-git &&
@@ -378,12 +392,12 @@ test_expect_success 'git tags' '
git init -q gitrepo &&
cd gitrepo &&
git config receive.denyCurrentBranch ignore &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git tag alpha &&
echo beta >beta &&
echo beta > beta &&
git add beta &&
git commit -m "add beta" &&
git tag -a -m "added tag beta" beta
@@ -392,7 +406,7 @@ test_expect_success 'git tags' '
for x in hg git
do
hg_clone_$x gitrepo hgrepo-$x &&
hg_log hgrepo-$x >"log-$x"
hg_log hgrepo-$x > "log-$x"
done &&
test_cmp log-hg log-git
@@ -407,7 +421,7 @@ test_expect_success 'hg author' '
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
@@ -418,38 +432,38 @@ test_expect_success 'hg author' '
cd hgrepo-$x &&
hg co master &&
echo beta >beta &&
echo beta > beta &&
hg add beta &&
hg commit -u "test" -m "add beta" &&
echo gamma >>beta &&
echo gamma >> beta &&
hg commit -u "test <test@example.com> (comment)" -m "modify beta" &&
echo gamma >gamma &&
echo gamma > gamma &&
hg add gamma &&
hg commit -u "<test@example.com>" -m "add gamma" &&
echo delta >delta &&
echo delta > delta &&
hg add delta &&
hg commit -u "name<test@example.com>" -m "add delta" &&
echo epsilon >epsilon &&
echo epsilon > epsilon &&
hg add epsilon &&
hg commit -u "name <test@example.com" -m "add epsilon" &&
echo zeta >zeta &&
echo zeta > zeta &&
hg add zeta &&
hg commit -u " test " -m "add zeta" &&
echo eta >eta &&
echo eta > eta &&
hg add eta &&
hg commit -u "test < test@example.com >" -m "add eta" &&
echo theta >theta &&
echo theta > theta &&
hg add theta &&
hg commit -u "test >test@example.com>" -m "add theta" &&
echo iota >iota &&
echo iota > iota &&
hg add iota &&
hg commit -u "test <test <at> example <dot> com>" -m "add iota"
) &&
@@ -457,8 +471,8 @@ test_expect_success 'hg author' '
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"
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -474,7 +488,7 @@ test_expect_success 'hg branch' '
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -q -m "add alpha" &&
git checkout -q -b not-master
@@ -494,8 +508,8 @@ test_expect_success 'hg branch' '
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"
hg_log hgrepo2-$x > "hg-log-$x" &&
git_log gitrepo-$x > "git-log-$x"
done &&
test_cmp hg-log-hg hg-log-git &&
@@ -511,7 +525,7 @@ test_expect_success 'hg tags' '
git init -q gitrepo-$x &&
cd gitrepo-$x &&
echo alpha >alpha &&
echo alpha > alpha &&
git add alpha &&
git commit -m "add alpha" &&
git checkout -q -b not-master
@@ -532,7 +546,7 @@ test_expect_success 'hg tags' '
git --git-dir=gitrepo-$x/.git tag -l &&
hg_log hgrepo2-$x &&
cat hgrepo2-$x/.hgtags
) >"output-$x"
) > "output-$x"
done &&
test_cmp output-hg output-git

View File

@@ -8,7 +8,7 @@
test_description='Test remote-hg'
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=${0%/*}/../../t
test -n "$TEST_DIRECTORY" || TEST_DIRECTORY=$(dirname $0)/
. "$TEST_DIRECTORY"/test-lib.sh
if ! test_have_prereq PYTHON
@@ -17,26 +17,26 @@ then
test_done
fi
if ! python -c 'import mercurial'
if ! python2 -c 'import mercurial' > /dev/null 2>&1
then
skip_all='skipping remote-hg tests; mercurial not available'
test_done
fi
check () {
echo $3 >expected &&
git --git-dir=$1/.git log --format='%s' -1 $2 >actual
echo $3 > expected &&
git --git-dir=$1/.git log --format='%s' -1 $2 > actual &&
test_cmp expected actual
}
check_branch () {
if test -n "$3"
then
echo $3 >expected &&
hg -R $1 log -r $2 --template '{desc}\n' >actual &&
echo $3 > expected &&
hg -R $1 log -r $2 --template '{desc}\n' > actual &&
test_cmp expected actual
else
hg -R $1 branches >out &&
hg -R $1 branches > out &&
! grep $2 out
fi
}
@@ -44,20 +44,31 @@ check_branch () {
check_bookmark () {
if test -n "$3"
then
echo $3 >expected &&
hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' >actual &&
echo $3 > expected &&
hg -R $1 log -r "bookmark('$2')" --template '{desc}\n' > actual &&
test_cmp expected actual
else
hg -R $1 bookmarks >out &&
hg -R $1 bookmarks > out &&
! grep $2 out
fi
}
check_files () {
git --git-dir=$1/.git ls-files > actual &&
if test $# -gt 1
then
printf "%s\n" "$2" > expected
else
> expected
fi &&
test_cmp expected actual
}
check_push () {
expected_ret=$1 ret=0 ref_ret=0
shift
git push origin "$@" 2>error
git push origin "$@" 2> error
ret=$?
cat error
@@ -92,12 +103,12 @@ check_push () {
}
setup () {
(
echo "[ui]"
echo "username = H G Wells <wells@example.com>"
echo "[extensions]"
echo "mq ="
) >>"$HOME"/.hgrc &&
cat > "$HOME"/.hgrc <<-EOF &&
[ui]
username = H G Wells <wells@example.com>
[extensions]
mq =
EOF
GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0230" &&
GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" &&
@@ -106,17 +117,18 @@ setup () {
setup
test_expect_success 'cloning' '
test_when_finished "rm -rf gitrepo*" &&
test_expect_success 'setup' '
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
echo zero > content &&
hg add content &&
hg commit -m zero
) &&
)
'
test_expect_success 'cloning' '
test_when_finished "rm -rf gitrepo*" &&
git clone "hg::hgrepo" gitrepo &&
check gitrepo HEAD zero
'
@@ -127,7 +139,7 @@ test_expect_success 'cloning with branches' '
(
cd hgrepo &&
hg branch next &&
echo next >content &&
echo next > content &&
hg commit -m next
) &&
@@ -142,7 +154,7 @@ test_expect_success 'cloning with bookmarks' '
cd hgrepo &&
hg checkout default &&
hg bookmark feature-a &&
echo feature-a >content &&
echo feature-a > content &&
hg commit -m feature-a
) &&
@@ -162,7 +174,7 @@ test_expect_success 'update bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet devel &&
echo devel >content &&
echo devel > content &&
git commit -a -m devel &&
git push --quiet
) &&
@@ -177,7 +189,7 @@ test_expect_success 'new bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-b &&
echo feature-b >content &&
echo feature-b > content &&
git commit -a -m feature-b &&
git push --quiet origin feature-b
) &&
@@ -189,9 +201,9 @@ test_expect_success 'new bookmark' '
rm -rf hgrepo
author_test () {
echo $1 >>content &&
echo $1 >> content &&
hg commit -u "$2" -m "add $1" &&
echo "$3" >>../expected
echo "$3" >> ../expected
}
test_expect_success 'authors' '
@@ -204,7 +216,7 @@ test_expect_success 'authors' '
touch content &&
hg add content &&
>../expected &&
> ../expected &&
author_test alpha "" "H G Wells <wells@example.com>" &&
author_test beta "beta" "beta <unknown>" &&
author_test gamma "gamma <test@example.com> (comment)" "gamma <test@example.com>" &&
@@ -220,7 +232,7 @@ test_expect_success 'authors' '
) &&
git clone "hg::hgrepo" gitrepo &&
git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" >actual &&
git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" > actual &&
test_cmp expected actual
'
@@ -232,11 +244,11 @@ test_expect_success 'strip' '
hg init hgrepo &&
cd hgrepo &&
echo one >>content &&
echo one >> content &&
hg add content &&
hg commit -m one &&
echo two >>content &&
echo two >> content &&
hg commit -m two
) &&
@@ -246,20 +258,20 @@ test_expect_success 'strip' '
cd hgrepo &&
hg strip 1 &&
echo three >>content &&
echo three >> content &&
hg commit -m three &&
echo four >>content &&
echo four >> content &&
hg commit -m four
) &&
(
cd gitrepo &&
git fetch &&
git log --format="%s" origin/master >../actual
git log --format="%s" origin/master > ../actual
) &&
hg -R hgrepo log --template "{desc}\n" >expected &&
hg -R hgrepo log --template "{desc}\n" > expected &&
test_cmp actual expected
'
@@ -269,18 +281,18 @@ test_expect_success 'remote push with master bookmark' '
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
echo zero > content &&
hg add content &&
hg commit -m zero &&
hg bookmark master &&
echo one >content &&
echo one > content &&
hg commit -m one
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
echo two >content &&
echo two > content &&
git commit -a -m two &&
git push
) &&
@@ -288,7 +300,7 @@ test_expect_success 'remote push with master bookmark' '
check_branch hgrepo default two
'
cat >expected <<\EOF
cat > expected <<\EOF
changeset: 0:6e2126489d3d
tag: tip
user: A U Thor <author@example.com>
@@ -306,13 +318,13 @@ test_expect_success 'remote push from master branch' '
git init gitrepo &&
cd gitrepo &&
git remote add origin "hg::../hgrepo" &&
echo one >content &&
echo one > content &&
git add content &&
git commit -a -m one &&
git push origin master
) &&
hg -R hgrepo log >actual &&
hg -R hgrepo log > actual &&
cat actual &&
test_cmp expected actual &&
@@ -328,7 +340,7 @@ test_expect_success 'remote cloning' '
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
echo zero > content &&
hg add content &&
hg commit -m zero
) &&
@@ -360,7 +372,7 @@ test_expect_success 'remote update bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet devel &&
echo devel >content &&
echo devel > content &&
git commit -a -m devel &&
git push --quiet
) &&
@@ -375,7 +387,7 @@ test_expect_success 'remote new bookmark' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-b &&
echo feature-b >content &&
echo feature-b > content &&
git commit -a -m feature-b &&
git push --quiet origin feature-b
) &&
@@ -391,13 +403,13 @@ test_expect_success 'remote push diverged' '
(
cd hgrepo &&
hg checkout default &&
echo bump >content &&
echo bump > content &&
hg commit -m bump
) &&
(
cd gitrepo &&
echo diverge >content &&
echo diverge > content &&
git commit -a -m diverged &&
check_push 1 <<-\EOF
master:non-fast-forward
@@ -420,14 +432,14 @@ test_expect_success 'remote update bookmark diverge' '
(
cd hgrepo &&
echo "bump bookmark" >content &&
echo "bump bookmark" > content &&
hg commit -m "bump bookmark"
) &&
(
cd gitrepo &&
git checkout --quiet diverge &&
echo diverge >content &&
echo diverge > content &&
git commit -a -m diverge &&
check_push 1 <<-\EOF
diverge:fetch-first
@@ -444,7 +456,7 @@ test_expect_success 'remote new bookmark multiple branch head' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git checkout --quiet -b feature-c HEAD^ &&
echo feature-c >content &&
echo feature-c > content &&
git commit -a -m feature-c &&
git push --quiet origin feature-c
) &&
@@ -527,20 +539,20 @@ setup_big_push () {
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
echo zero > content &&
hg add content &&
hg commit -m zero &&
hg bookmark bad_bmark1 &&
echo one >content &&
echo one > content &&
hg commit -m one &&
hg bookmark bad_bmark2 &&
hg bookmark good_bmark &&
hg bookmark -i good_bmark &&
hg -q branch good_branch &&
echo "good branch" >content &&
echo "good branch" > content &&
hg commit -m "good branch" &&
hg -q branch bad_branch &&
echo "bad branch" >content &&
echo "bad branch" > content &&
hg commit -m "bad branch"
) &&
@@ -548,40 +560,40 @@ setup_big_push () {
(
cd gitrepo &&
echo two >content &&
echo two > content &&
git commit -q -a -m two &&
git checkout -q good_bmark &&
echo three >content &&
echo three > content &&
git commit -q -a -m three &&
git checkout -q bad_bmark1 &&
git reset --hard HEAD^ &&
echo four >content &&
echo four > content &&
git commit -q -a -m four &&
git checkout -q bad_bmark2 &&
git reset --hard HEAD^ &&
echo five >content &&
echo five > content &&
git commit -q -a -m five &&
git checkout -q -b new_bmark master &&
echo six >content &&
echo six > content &&
git commit -q -a -m six &&
git checkout -q branches/good_branch &&
echo seven >content &&
echo seven > content &&
git commit -q -a -m seven &&
echo eight >content &&
echo eight > content &&
git commit -q -a -m eight &&
git checkout -q branches/bad_branch &&
git reset --hard HEAD^ &&
echo nine >content &&
echo nine > content &&
git commit -q -a -m nine &&
git checkout -q -b branches/new_branch master &&
echo ten >content &&
echo ten > content &&
git commit -q -a -m ten
)
}
@@ -622,17 +634,17 @@ test_expect_success 'remote big push fetch first' '
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
echo zero > content &&
hg add content &&
hg commit -m zero &&
hg bookmark bad_bmark &&
hg bookmark good_bmark &&
hg bookmark -i good_bmark &&
hg -q branch good_branch &&
echo "good branch" >content &&
echo "good branch" > content &&
hg commit -m "good branch" &&
hg -q branch bad_branch &&
echo "bad branch" >content &&
echo "bad branch" > content &&
hg commit -m "bad branch"
) &&
@@ -641,25 +653,25 @@ test_expect_success 'remote big push fetch first' '
(
cd hgrepo &&
hg bookmark -f bad_bmark &&
echo update_bmark >content &&
echo update_bmark > content &&
hg commit -m "update bmark"
) &&
(
cd gitrepo &&
echo two >content &&
echo two > content &&
git commit -q -a -m two &&
git checkout -q good_bmark &&
echo three >content &&
echo three > content &&
git commit -q -a -m three &&
git checkout -q bad_bmark &&
echo four >content &&
echo four > content &&
git commit -q -a -m four &&
git checkout -q branches/bad_branch &&
echo five >content &&
echo five > content &&
git commit -q -a -m five &&
check_push 1 --all <<-\EOF &&
@@ -754,10 +766,10 @@ test_expect_success 'remote double failed push' '
(
hg init hgrepo &&
cd hgrepo &&
echo zero >content &&
echo zero > content &&
hg add content &&
hg commit -m zero &&
echo one >content &&
echo one > content &&
hg commit -m one
) &&
@@ -765,11 +777,251 @@ test_expect_success 'remote double failed push' '
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git reset --hard HEAD^ &&
echo two >content &&
echo two > content &&
git commit -a -m two &&
test_expect_code 1 git push &&
test_expect_code 1 git push
)
'
test_expect_success 'clone remote with null bookmark, then push' '
test_when_finished "rm -rf gitrepo* hgrepo*" &&
(
hg init hgrepo &&
cd hgrepo &&
echo a > a &&
hg add a &&
hg commit -m a &&
hg bookmark -r null bookmark
) &&
(
git clone "hg::hgrepo" gitrepo &&
check gitrepo HEAD a &&
cd gitrepo &&
git checkout --quiet -b bookmark &&
git remote -v &&
echo b > b &&
git add b &&
git commit -m b &&
git push origin bookmark
)
'
test_expect_success 'notes' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one > content &&
hg add content &&
hg commit -m one &&
echo two > content &&
hg commit -m two
) &&
git clone "hg::hgrepo" gitrepo &&
hg -R hgrepo log --template "{node}\n\n" > expected &&
git --git-dir=gitrepo/.git log --pretty="tformat:%N" --notes=hg > actual &&
test_cmp expected actual
'
test_expect_failure 'push updates notes' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one > content &&
hg add content &&
hg commit -m one
) &&
git clone "hg::hgrepo" gitrepo &&
(
cd gitrepo &&
echo two > content &&
git commit -a -m two
git push
) &&
hg -R hgrepo log --template "{node}\n\n" > expected &&
git --git-dir=gitrepo/.git log --pretty="tformat:%N" --notes=hg > actual &&
test_cmp expected actual
'
test_expect_success 'pull tags' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one > content &&
hg add content &&
hg commit -m one
) &&
git clone "hg::hgrepo" gitrepo &&
(cd hgrepo && hg tag v1.0) &&
(cd gitrepo && git pull) &&
echo "v1.0" > expected &&
git --git-dir=gitrepo/.git tag > actual &&
test_cmp expected actual
'
test_expect_success 'push merged named branch' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one > content &&
hg add content &&
hg commit -m one &&
hg branch feature &&
echo two > content &&
hg commit -m two &&
hg update default &&
echo three > content &&
hg commit -m three
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git merge -m Merge -Xtheirs origin/branches/feature &&
git push
) &&
cat > expected <<-EOF
Merge
three
two
one
EOF
hg -R hgrepo log --template "{desc}\n" > actual &&
test_cmp expected actual
'
test_expect_success 'light tag sets author' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one > content &&
hg add content &&
hg commit -m one
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git tag v1.0 &&
git push --tags
) &&
echo "C O Mitter <committer@example.com>" > expected &&
hg -R hgrepo log --template "{author}\n" -r tip > actual &&
test_cmp expected actual
'
test_expect_success 'push tag different branch' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo one > content &&
hg add content &&
hg commit -m one
hg branch feature &&
echo two > content &&
hg commit -m two
) &&
(
git clone "hg::hgrepo" gitrepo &&
cd gitrepo &&
git branch &&
git checkout branches/feature &&
git tag v1.0 &&
git push --tags
) &&
echo feature > expected &&
hg -R hgrepo log --template="{branch}\n" -r tip > actual &&
test_cmp expected actual
'
test_expect_success 'cloning a removed file works' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo test > test_file &&
hg add test_file &&
hg commit -m add &&
hg rm test_file &&
hg commit -m remove
) &&
git clone "hg::hgrepo" gitrepo &&
check_files gitrepo
'
test_expect_success 'cloning a file replaced with a directory' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
echo test > dir_or_file &&
hg add dir_or_file &&
hg commit -m add &&
hg rm dir_or_file &&
mkdir dir_or_file &&
echo test > dir_or_file/test_file &&
hg add dir_or_file/test_file &&
hg commit -m replase
) &&
git clone "hg::hgrepo" gitrepo &&
check_files gitrepo "dir_or_file/test_file"
'
test_expect_success 'clone replace directory with a file' '
test_when_finished "rm -rf hgrepo gitrepo" &&
(
hg init hgrepo &&
cd hgrepo &&
mkdir dir_or_file &&
echo test > dir_or_file/test_file &&
hg add dir_or_file/test_file &&
hg commit -m add &&
hg rm dir_or_file/test_file &&
echo test > dir_or_file &&
hg add dir_or_file &&
hg commit -m add &&
hg rm dir_or_file
) &&
git clone "hg::hgrepo" gitrepo &&
check_files gitrepo "dir_or_file"
'
test_done