merge with crew-stable

This commit is contained in:
Benoit Boissinot 2007-08-31 22:31:43 +02:00
commit 5025962412
21 changed files with 452 additions and 34 deletions

View File

@ -1,6 +1,7 @@
# git support for the convert extension
import os
from mercurial import util
from common import NoRepo, commit, converter_source
@ -14,6 +15,24 @@ def recode(s):
return s.decode("utf-8", "replace").encode("utf-8")
class convert_git(converter_source):
# Windows does not support GIT_DIR= construct while other systems
# cannot remove environment variable. Just assume none have
# both issues.
if hasattr(os, 'unsetenv'):
def gitcmd(self, s):
prevgitdir = os.environ.get('GIT_DIR')
os.environ['GIT_DIR'] = self.path
try:
return os.popen(s)
finally:
if prevgitdir is None:
del os.environ['GIT_DIR']
else:
os.environ['GIT_DIR'] = prevgitdir
else:
def gitcmd(self, s):
return os.popen('GIT_DIR=%s %s' % (self.path, s))
def __init__(self, ui, path):
if os.path.isdir(path + "/.git"):
path += "/.git"
@ -23,13 +42,13 @@ class convert_git(converter_source):
raise NoRepo("couldn't open GIT repo %s" % path)
def getheads(self):
fh = os.popen("GIT_DIR=%s git-rev-parse --verify HEAD" % self.path)
fh = self.gitcmd("git-rev-parse --verify HEAD")
return [fh.read()[:-1]]
def catfile(self, rev, type):
if rev == "0" * 40: raise IOError()
fh = os.popen("GIT_DIR=%s git-cat-file %s %s 2>/dev/null"
% (self.path, type, rev))
fh = self.gitcmd("git-cat-file %s %s 2>%s" % (type, rev,
util.nulldev))
return fh.read()
def getfile(self, name, rev):
@ -40,8 +59,7 @@ class convert_git(converter_source):
def getchanges(self, version):
self.modecache = {}
fh = os.popen("GIT_DIR=%s git-diff-tree --root -m -r %s"
% (self.path, version))
fh = self.gitcmd("git-diff-tree --root -m -r %s" % version)
changes = []
for l in fh:
if "\t" not in l: continue
@ -89,7 +107,8 @@ class convert_git(converter_source):
def gettags(self):
tags = {}
fh = os.popen('git-ls-remote --tags "%s" 2>/dev/null' % self.path)
fh = self.gitcmd('git-ls-remote --tags "%s" 2>%s' % (self.path,
util.nulldev))
prefix = 'refs/tags/'
for line in fh:
line = line.strip()

View File

@ -1490,6 +1490,11 @@ def clone(ui, source, dest=None, **opts):
Source patch repository is looked for in <src>/.hg/patches by
default. Use -p <url> to change.
'''
def patchdir(repo):
url = repo.url()
if url.endswith('/'):
url = url[:-1]
return url + '/.hg/patches'
cmdutil.setremoteconfig(ui, opts)
if dest is None:
dest = hg.defaultdest(source)
@ -1511,10 +1516,8 @@ def clone(ui, source, dest=None, **opts):
update=False,
stream=opts['uncompressed'])
ui.note(_('cloning patch repo\n'))
spr, dpr = hg.clone(ui, opts['patches'] or (sr.url() + '/.hg/patches'),
dr.url() + '/.hg/patches',
pull=opts['pull'],
update=not opts['noupdate'],
spr, dpr = hg.clone(ui, opts['patches'] or patchdir(sr), patchdir(dr),
pull=opts['pull'], update=not opts['noupdate'],
stream=opts['uncompressed'])
if dr.local():
if qbase:

View File

@ -462,10 +462,10 @@ def parseurl(url, revs):
'''parse url#branch, returning url, branch + revs'''
if '#' not in url:
return url, (revs or None)
return url, (revs or None), None
url, rev = url.split('#', 1)
return url, revs + [rev]
return url, revs + [rev], rev
def revpair(repo, revs):
'''return pair of nodes, given list of revisions. second item can

View File

@ -324,7 +324,7 @@ def bundle(ui, repo, fname, dest=None, **opts):
visit.append(p)
else:
cmdutil.setremoteconfig(ui, opts)
dest, revs = cmdutil.parseurl(
dest, revs, checkout = cmdutil.parseurl(
ui.expandpath(dest or 'default-push', dest or 'default'), revs)
other = hg.repository(ui, dest)
o = repo.findoutgoing(other, force=opts['force'])
@ -1491,7 +1491,7 @@ def identify(ui, repo, source=None,
output = []
if source:
source, revs = cmdutil.parseurl(ui.expandpath(source), [])
source, revs, checkout = cmdutil.parseurl(ui.expandpath(source), [])
srepo = hg.repository(ui, source)
if not rev and revs:
rev = revs[0]
@ -1649,7 +1649,8 @@ def incoming(ui, repo, source="default", **opts):
See pull for valid source format details.
"""
source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
source, revs, checkout = cmdutil.parseurl(ui.expandpath(source),
opts['rev'])
cmdutil.setremoteconfig(ui, opts)
other = hg.repository(ui, source)
@ -1952,7 +1953,7 @@ def outgoing(ui, repo, dest=None, **opts):
See pull for valid destination format details.
"""
dest, revs = cmdutil.parseurl(
dest, revs, checkout = cmdutil.parseurl(
ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
cmdutil.setremoteconfig(ui, opts)
if revs:
@ -2020,12 +2021,12 @@ def paths(ui, repo, search=None):
for name, path in ui.configitems("paths"):
ui.write("%s = %s\n" % (name, path))
def postincoming(ui, repo, modheads, optupdate):
def postincoming(ui, repo, modheads, optupdate, checkout):
if modheads == 0:
return
if optupdate:
if modheads <= 1:
return hg.update(repo, None)
if modheads <= 1 or checkout:
return hg.update(repo, checkout)
else:
ui.status(_("not updating, since new heads added\n"))
if modheads > 1:
@ -2074,7 +2075,8 @@ def pull(ui, repo, source="default", **opts):
Alternatively specify "ssh -C" as your ssh command in your hgrc or
with the --ssh command line option.
"""
source, revs = cmdutil.parseurl(ui.expandpath(source), opts['rev'])
source, revs, checkout = cmdutil.parseurl(ui.expandpath(source),
opts['rev'])
cmdutil.setremoteconfig(ui, opts)
other = hg.repository(ui, source)
@ -2087,7 +2089,7 @@ def pull(ui, repo, source="default", **opts):
raise util.Abort(error)
modheads = repo.pull(other, heads=revs, force=opts['force'])
return postincoming(ui, repo, modheads, opts['update'])
return postincoming(ui, repo, modheads, opts['update'], checkout)
def push(ui, repo, dest=None, **opts):
"""push changes to the specified destination
@ -2119,7 +2121,7 @@ def push(ui, repo, dest=None, **opts):
Pushing to http:// and https:// URLs is only possible, if this
feature is explicitly enabled on the remote Mercurial server.
"""
dest, revs = cmdutil.parseurl(
dest, revs, checkout = cmdutil.parseurl(
ui.expandpath(dest or 'default-push', dest or 'default'), opts['rev'])
cmdutil.setremoteconfig(ui, opts)
@ -2336,6 +2338,14 @@ def revert(ui, repo, *pats, **opts):
changes = repo.status(match=names.has_key, wlock=wlock)[:5]
modified, added, removed, deleted, unknown = map(dict.fromkeys, changes)
# if f is a rename, also revert the source
cwd = repo.getcwd()
for f in added:
src = repo.dirstate.copied(f)
if src and src not in names and repo.dirstate[src][0] == 'r':
removed[src] = None
names[src] = (repo.pathto(src, cwd), True)
revert = ([], _('reverting %s\n'))
add = ([], _('adding %s\n'))
remove = ([], _('removing %s\n'))
@ -2659,7 +2669,7 @@ def unbundle(ui, repo, fname1, *fnames, **opts):
gen = changegroup.readbundle(f, fname)
modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname)
return postincoming(ui, repo, modheads, opts['update'])
return postincoming(ui, repo, modheads, opts['update'], None)
def update(ui, repo, node=None, rev=None, clean=False, date=None):
"""update working directory

View File

@ -99,7 +99,7 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True,
"""
origsource = source
source, rev = cmdutil.parseurl(ui.expandpath(source), rev)
source, rev, checkout = cmdutil.parseurl(ui.expandpath(source), rev)
if isinstance(source, str):
src_repo = repository(ui, source)
@ -141,7 +141,7 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True,
abspath = origsource
copy = False
if src_repo.local() and islocal(dest):
abspath = os.path.abspath(origsource)
abspath = os.path.abspath(util.drop_scheme('file', origsource))
copy = not pull and not rev
src_lock, dest_lock = None, None
@ -229,10 +229,11 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True,
dest_lock.release()
if update:
try:
checkout = dest_repo.lookup("default")
except:
checkout = dest_repo.changelog.tip()
if not checkout:
try:
checkout = dest_repo.lookup("default")
except:
checkout = dest_repo.changelog.tip()
_update(dest_repo, checkout)
return src_repo, dest_repo

View File

@ -612,7 +612,9 @@ class localrepository(repo.repository):
elif fp1 != nullid: # copied on local side, reversed
meta["copyrev"] = hex(manifest2.get(cp))
fp2 = fp1
else: # directory rename
elif cp in manifest2: # directory rename on local side
meta["copyrev"] = hex(manifest2[cp])
else: # directory rename on remote side
meta["copyrev"] = hex(manifest1.get(cp, nullid))
self.ui.debug(_(" %s: copy %s:%s\n") %
(fn, cp, meta["copyrev"]))
@ -626,7 +628,7 @@ class localrepository(repo.repository):
fp2 = nullid
# is the file unmodified from the parent? report existing entry
if fp2 == nullid and not fl.cmp(fp1, t):
if fp2 == nullid and not fl.cmp(fp1, t) and not meta:
return fp1
changelist.append(fn)
@ -718,7 +720,7 @@ class localrepository(repo.repository):
new[f] = self.filecommit(f, m1, m2, linkrev, tr, changed)
new_exec = is_exec(f)
new_link = is_link(f)
if not changed or changed[-1] != f:
if (not changed or changed[-1] != f) and m2.get(f) != new[f]:
# mention the file in the changelog if some flag changed,
# even if there was no content change.
old_exec = m1.execf(f)
@ -1312,7 +1314,7 @@ class localrepository(repo.repository):
mylock = True
try:
fetch = self.findincoming(remote, force=force)
fetch = self.findincoming(remote, heads=heads, force=force)
if fetch == [nullid]:
self.ui.status(_("requesting all changes\n"))

View File

@ -51,9 +51,16 @@ def has_lsprof():
except ImportError:
return False
def has_git():
fh = os.popen('git --version 2>&1')
s = fh.read()
ret = fh.close()
return ret is None and s.startswith('git version')
checks = {
"eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
"execbit": (has_executablebit, "executable bit"),
"git": (has_git, "git command line client"),
"fifo": (has_fifo, "named pipes"),
"hotshot": (has_hotshot, "python hotshot module"),
"lsprof": (has_lsprof, "python lsprof module"),

32
tests/test-changelog-exec Executable file
View File

@ -0,0 +1,32 @@
#!/bin/sh
# b51a8138292a introduced a regression where we would mention in the
# changelog executable files added by the second parent of a merge.
# Test that that doesn't happen anymore
"$TESTDIR/hghave" execbit || exit 80
hg init repo
cd repo
echo foo > foo
hg ci -qAm 'add foo' -d '0 0'
echo bar > bar
chmod +x bar
hg ci -qAm 'add bar' -d '0 0'
echo '% manifest of p2:'
hg manifest
echo
hg up -qC 0
echo >> foo
hg ci -m 'change foo' -d '0 0'
echo '% manifest of p1:'
hg manifest
hg merge
hg ci -m 'merge' -d '0 0'
echo '% this should not mention bar:'
hg tip -v
hg debugindex .hg/store/data/bar.i

View File

@ -0,0 +1,21 @@
% manifest of p2:
bar
foo
% manifest of p1:
foo
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)
% this should not mention bar:
changeset: 3:ef2fc9b4a51b
tag: tip
parent: 2:ed1b79f46b9a
parent: 1:d394a8db219b
user: test
date: Thu Jan 01 00:00:00 1970 +0000
description:
merge
rev offset length base linkrev nodeid p1 p2
0 0 5 0 1 b004912a8510 000000000000 000000000000

View File

@ -25,3 +25,11 @@ cd ../d
hg clone ../a
cd a
hg cat a
# check that we drop the file:// from the path before
# writing the .hgrc
cd ../..
hg clone file://a e
grep 'file:' e/.hg/hgrc
exit 0

View File

@ -14,3 +14,4 @@ checking files
destination directory: a
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
a
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

19
tests/test-convert-git Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
"$TESTDIR/hghave" git || exit 80
echo "[extensions]" >> $HGRCPATH
echo "convert=" >> $HGRCPATH
mkdir git-repo
cd git-repo
git init-db >/dev/null 2>/dev/null
echo a > a
git add a
git commit -m t1 >/dev/null 2>/dev/null || echo "git commit error"
echo b >> a
git commit -a -m t2 >/dev/null || echo "git commit error"
cd ..
hg convert git-repo

View File

@ -0,0 +1,7 @@
assuming destination git-repo-hg
initializing destination git-repo-hg repository
scanning source...
sorting...
converting...
1 t1
0 t2

27
tests/test-pull-r Executable file
View File

@ -0,0 +1,27 @@
#!/bin/sh
hg init repo
cd repo
echo foo > foo
hg ci -qAm 'add foo' -d '0 0'
echo >> foo
hg ci -m 'change foo' -d '0 0'
hg up -qC 0
echo bar > bar
hg ci -qAm 'add bar' -d '0 0'
hg log
cd ..
hg init copy
cd copy
echo '% pull -r 0'
hg pull -qr 0 ../repo
hg log
echo '% pull -r 1'
hg pull -qr 1 ../repo
hg log
# this used to abort: received changelog group is empty
echo '% pull -r 1 again'
hg pull -qr 1 ../repo

37
tests/test-pull-r.out Normal file
View File

@ -0,0 +1,37 @@
changeset: 2:effea6de0384
tag: tip
parent: 0:bbd179dfa0a7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add bar
changeset: 1:ed1b79f46b9a
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: change foo
changeset: 0:bbd179dfa0a7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add foo
% pull -r 0
changeset: 0:bbd179dfa0a7
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add foo
% pull -r 1
changeset: 1:ed1b79f46b9a
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: change foo
changeset: 0:bbd179dfa0a7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add foo
% pull -r 1 again

View File

@ -24,9 +24,11 @@ hg merge --debug 1
echo a/* b/*
hg st -C
hg ci -m "3 merge 2+1" -d "0 0"
hg debugrename b/c
hg co -C 1
hg merge --debug 2
echo a/* b/*
hg st -C
hg ci -m "4 merge 1+2" -d "0 0"
hg debugrename b/c

View File

@ -29,6 +29,7 @@ A b/c
R a/a
R a/b
R a/c
b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
resolving manifests
overwrite None partial False
@ -40,3 +41,4 @@ getting a/c to b/c
a/* b/a b/b b/c
A b/c
a/c
b/c renamed from a/c:354ae8da6e890359ef49ade27b68bbc361f3ca88

View File

@ -94,4 +94,9 @@ hg add newdir/newfile
hg revert b newdir
echo foobar > b/b
hg revert .
true
echo % reverting a rename target should revert the source
hg mv a newa
hg revert newa
hg st a newa

View File

@ -63,3 +63,5 @@ adding b/b
reverting b/b
forgetting newdir/newfile
reverting b/b
% reverting a rename target should revert the source
? newa

83
tests/test-url-rev Executable file
View File

@ -0,0 +1,83 @@
#!/bin/sh
# test basic functionality of url#rev syntax
hg init repo
cd repo
echo a > a
hg ci -qAm 'add a' -d '0 0'
hg branch foo
echo >> a
hg ci -m 'change a' -d '0 0'
cd ..
echo '% clone repo#foo'
hg clone 'repo#foo' clone
echo '% heads'
hg --cwd clone heads
echo '% parents'
hg --cwd clone parents
sed -e 's/default.*#/default = #/' clone/.hg/hgrc
echo
echo '% changing original repo'
cd repo
echo >> a
hg ci -m 'new head of branch foo' -d '0 0'
hg up -qC default
echo bar > bar
hg ci -qAm 'add bar' -d '0 0'
hg log
echo
echo '% outgoing'
hg -q outgoing '../clone#foo'
echo
echo '% push'
hg -q push '../clone#foo'
hg --cwd ../clone heads
cd ..
echo
echo '% rolling back'
cd clone
hg rollback
echo '% incoming'
hg -q incoming
echo '% pull'
hg -q pull
hg heads
echo
echo '% pull should not have updated'
hg parents -q
echo '% going back to the default branch'
hg up -C 0
hg parents
echo '% no new revs, no update'
hg pull -qu
hg parents -q
echo '% rollback'
hg rollback
hg up -C 0
hg parents -q
echo '% pull -u takes us back to branch foo'
hg pull -qu
hg parents
echo '% rollback'
hg rollback
hg up -C 0
echo '% parents'
hg parents -q
echo '% heads'
hg heads -q
echo '% pull -u -r otherrev url#rev updates to rev'
hg pull -qur default default
echo '% parents'
hg parents
echo '% heads'
hg heads

130
tests/test-url-rev.out Normal file
View File

@ -0,0 +1,130 @@
marked working directory as branch foo
% clone repo#foo
requesting all changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% heads
changeset: 1:cd2a86ecc814
branch: foo
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: change a
% parents
changeset: 1:cd2a86ecc814
branch: foo
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: change a
[paths]
default = #foo
% changing original repo
changeset: 3:4cd725637392
tag: tip
parent: 0:1f0dee641bb7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add bar
changeset: 2:faba9097cad4
branch: foo
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: new head of branch foo
changeset: 1:cd2a86ecc814
branch: foo
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: change a
changeset: 0:1f0dee641bb7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add a
% outgoing
2:faba9097cad4
% push
changeset: 2:faba9097cad4
branch: foo
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: new head of branch foo
% rolling back
rolling back last transaction
% incoming
2:faba9097cad4
% pull
changeset: 2:faba9097cad4
branch: foo
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: new head of branch foo
% pull should not have updated
1:cd2a86ecc814
% going back to the default branch
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
changeset: 0:1f0dee641bb7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add a
% no new revs, no update
0:1f0dee641bb7
% rollback
rolling back last transaction
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
0:1f0dee641bb7
% pull -u takes us back to branch foo
changeset: 2:faba9097cad4
branch: foo
tag: tip
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: new head of branch foo
% rollback
rolling back last transaction
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% parents
0:1f0dee641bb7
% heads
1:cd2a86ecc814
% pull -u -r otherrev url#rev updates to rev
% parents
changeset: 2:faba9097cad4
branch: foo
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: new head of branch foo
% heads
changeset: 3:4cd725637392
tag: tip
parent: 0:1f0dee641bb7
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: add bar
changeset: 2:faba9097cad4
branch: foo
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: new head of branch foo