mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 15:57:43 +03:00
merge with -stable
This commit is contained in:
commit
f25ebf4477
@ -108,7 +108,18 @@ def _demandimport(name, globals=None, locals=None, fromlist=None):
|
|||||||
setattr(mod, x, _demandmod(x, mod.__dict__, locals))
|
setattr(mod, x, _demandmod(x, mod.__dict__, locals))
|
||||||
return mod
|
return mod
|
||||||
|
|
||||||
ignore = ['_hashlib', '_xmlplus', 'fcntl', 'win32com.gen_py']
|
ignore = [
|
||||||
|
'_hashlib',
|
||||||
|
'_xmlplus',
|
||||||
|
'fcntl',
|
||||||
|
'win32com.gen_py',
|
||||||
|
# imported by tarfile, not available under Windows
|
||||||
|
'pwd',
|
||||||
|
'grp',
|
||||||
|
# imported by profile, itself imported by hotshot.stats,
|
||||||
|
# not available under Windows
|
||||||
|
'resource',
|
||||||
|
]
|
||||||
|
|
||||||
def enable():
|
def enable():
|
||||||
"enable global demand-loading of modules"
|
"enable global demand-loading of modules"
|
||||||
|
@ -24,6 +24,7 @@ def find(name):
|
|||||||
def load(ui, name, path):
|
def load(ui, name, path):
|
||||||
if name in _extensions:
|
if name in _extensions:
|
||||||
return
|
return
|
||||||
|
_extensions[name] = None
|
||||||
if path:
|
if path:
|
||||||
# the module will be loaded in sys.modules
|
# the module will be loaded in sys.modules
|
||||||
# choose an unique name so that it doesn't
|
# choose an unique name so that it doesn't
|
||||||
|
@ -9,7 +9,10 @@ def fancyopts(args, options, state):
|
|||||||
for s, l, d, c in options:
|
for s, l, d, c in options:
|
||||||
pl = l.replace('-', '_')
|
pl = l.replace('-', '_')
|
||||||
map['-'+s] = map['--'+l] = pl
|
map['-'+s] = map['--'+l] = pl
|
||||||
state[pl] = d
|
if isinstance(d, list):
|
||||||
|
state[pl] = d[:]
|
||||||
|
else:
|
||||||
|
state[pl] = d
|
||||||
dt[pl] = type(d)
|
dt[pl] = type(d)
|
||||||
if (d is not None and d is not True and d is not False and
|
if (d is not None and d is not True and d is not False and
|
||||||
not callable(d)):
|
not callable(d)):
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
from node import *
|
from node import *
|
||||||
from i18n import _
|
from i18n import _
|
||||||
import errno, util, os, tempfile, context
|
import errno, util, os, tempfile, context, heapq
|
||||||
|
|
||||||
def filemerge(repo, fw, fd, fo, wctx, mctx):
|
def filemerge(repo, fw, fd, fo, wctx, mctx):
|
||||||
"""perform a 3-way merge in the working directory
|
"""perform a 3-way merge in the working directory
|
||||||
@ -252,6 +252,58 @@ def findcopies(repo, m1, m2, ma, limit):
|
|||||||
|
|
||||||
return copy, diverge
|
return copy, diverge
|
||||||
|
|
||||||
|
def symmetricdifference(repo, rev1, rev2):
|
||||||
|
"""symmetric difference of the sets of ancestors of rev1 and rev2
|
||||||
|
|
||||||
|
I.e. revisions that are ancestors of rev1 or rev2, but not both.
|
||||||
|
"""
|
||||||
|
# basic idea:
|
||||||
|
# - mark rev1 and rev2 with different colors
|
||||||
|
# - walk the graph in topological order with the help of a heap;
|
||||||
|
# for each revision r:
|
||||||
|
# - if r has only one color, we want to return it
|
||||||
|
# - add colors[r] to its parents
|
||||||
|
#
|
||||||
|
# We keep track of the number of revisions in the heap that
|
||||||
|
# we may be interested in. We stop walking the graph as soon
|
||||||
|
# as this number reaches 0.
|
||||||
|
WHITE = 1
|
||||||
|
BLACK = 2
|
||||||
|
ALLCOLORS = WHITE | BLACK
|
||||||
|
colors = {rev1: WHITE, rev2: BLACK}
|
||||||
|
|
||||||
|
cl = repo.changelog
|
||||||
|
|
||||||
|
visit = [-rev1, -rev2]
|
||||||
|
heapq.heapify(visit)
|
||||||
|
n_wanted = len(visit)
|
||||||
|
ret = []
|
||||||
|
|
||||||
|
while n_wanted:
|
||||||
|
r = -heapq.heappop(visit)
|
||||||
|
wanted = colors[r] != ALLCOLORS
|
||||||
|
n_wanted -= wanted
|
||||||
|
if wanted:
|
||||||
|
ret.append(r)
|
||||||
|
|
||||||
|
for p in cl.parentrevs(r):
|
||||||
|
if p == nullrev:
|
||||||
|
continue
|
||||||
|
if p not in colors:
|
||||||
|
# first time we see p; add it to visit
|
||||||
|
n_wanted += wanted
|
||||||
|
colors[p] = colors[r]
|
||||||
|
heapq.heappush(visit, -p)
|
||||||
|
elif colors[p] != ALLCOLORS and colors[p] != colors[r]:
|
||||||
|
# at first we thought we wanted p, but now
|
||||||
|
# we know we don't really want it
|
||||||
|
n_wanted -= 1
|
||||||
|
colors[p] |= colors[r]
|
||||||
|
|
||||||
|
del colors[r]
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
def manifestmerge(repo, p1, p2, pa, overwrite, partial):
|
def manifestmerge(repo, p1, p2, pa, overwrite, partial):
|
||||||
"""
|
"""
|
||||||
Merge p1 and p2 with ancestor ma and generate merge action list
|
Merge p1 and p2 with ancestor ma and generate merge action list
|
||||||
@ -290,7 +342,12 @@ def manifestmerge(repo, p1, p2, pa, overwrite, partial):
|
|||||||
action.append((f, m) + args)
|
action.append((f, m) + args)
|
||||||
|
|
||||||
if not (backwards or overwrite):
|
if not (backwards or overwrite):
|
||||||
copy, diverge = findcopies(repo, m1, m2, ma, pa.rev())
|
rev1 = p1.rev()
|
||||||
|
if rev1 is None:
|
||||||
|
# p1 is a workingctx
|
||||||
|
rev1 = p1.parents()[0].rev()
|
||||||
|
limit = min(symmetricdifference(repo, rev1, p2.rev()))
|
||||||
|
copy, diverge = findcopies(repo, m1, m2, ma, limit)
|
||||||
|
|
||||||
for of, fl in diverge.items():
|
for of, fl in diverge.items():
|
||||||
act("divergent renames", "dr", of, fl)
|
act("divergent renames", "dr", of, fl)
|
||||||
|
24
tests/hghave
24
tests/hghave
@ -8,6 +8,8 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
tempprefix = 'hg-hghave-'
|
||||||
|
|
||||||
def has_symlink():
|
def has_symlink():
|
||||||
return hasattr(os, "symlink")
|
return hasattr(os, "symlink")
|
||||||
|
|
||||||
@ -15,7 +17,7 @@ def has_fifo():
|
|||||||
return hasattr(os, "mkfifo")
|
return hasattr(os, "mkfifo")
|
||||||
|
|
||||||
def has_executablebit():
|
def has_executablebit():
|
||||||
fd, path = tempfile.mkstemp()
|
fd, path = tempfile.mkstemp(prefix=tempprefix)
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
try:
|
try:
|
||||||
s = os.lstat(path).st_mode
|
s = os.lstat(path).st_mode
|
||||||
@ -26,18 +28,26 @@ def has_executablebit():
|
|||||||
|
|
||||||
def has_eol_in_paths():
|
def has_eol_in_paths():
|
||||||
try:
|
try:
|
||||||
fd, path = tempfile.mkstemp(suffix='\n\r')
|
fd, path = tempfile.mkstemp(prefix=tempprefix, suffix='\n\r')
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
os.remove(path)
|
os.remove(path)
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def has_lsprof():
|
||||||
|
try:
|
||||||
|
import _lsprof
|
||||||
|
return True
|
||||||
|
except ImportError:
|
||||||
|
return False
|
||||||
|
|
||||||
checks = {
|
checks = {
|
||||||
"symlink": (has_symlink, "symbolic links"),
|
|
||||||
"fifo": (has_fifo, "named pipes"),
|
|
||||||
"execbit": (has_executablebit, "executable bit"),
|
|
||||||
"eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
|
"eol-in-paths": (has_eol_in_paths, "end-of-lines in paths"),
|
||||||
|
"execbit": (has_executablebit, "executable bit"),
|
||||||
|
"fifo": (has_fifo, "named pipes"),
|
||||||
|
"lsprof": (has_lsprof, "python lsprof module"),
|
||||||
|
"symlink": (has_symlink, "symbolic links"),
|
||||||
}
|
}
|
||||||
|
|
||||||
def list_features():
|
def list_features():
|
||||||
@ -71,7 +81,7 @@ if __name__ == '__main__':
|
|||||||
negate = feature.startswith('no-')
|
negate = feature.startswith('no-')
|
||||||
if negate:
|
if negate:
|
||||||
feature = feature[3:]
|
feature = feature[3:]
|
||||||
|
|
||||||
if feature not in checks:
|
if feature not in checks:
|
||||||
error('hghave: unknown feature: ' + feature)
|
error('hghave: unknown feature: ' + feature)
|
||||||
continue
|
continue
|
||||||
@ -80,7 +90,7 @@ if __name__ == '__main__':
|
|||||||
if not negate and not check():
|
if not negate and not check():
|
||||||
error('hghave: missing feature: ' + desc)
|
error('hghave: missing feature: ' + desc)
|
||||||
elif negate and check():
|
elif negate and check():
|
||||||
error('hghave: unexpected feature: ' + desc)
|
error('hghave: system supports %s' % desc)
|
||||||
|
|
||||||
if failures != 0:
|
if failures != 0:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -5,7 +5,6 @@ u = ui.ui()
|
|||||||
|
|
||||||
repo = hg.repository(u, 'test1', create=1)
|
repo = hg.repository(u, 'test1', create=1)
|
||||||
os.chdir('test1')
|
os.chdir('test1')
|
||||||
repo = hg.repository(u, '.') # FIXME: can't lock repo without doing this
|
|
||||||
|
|
||||||
# create 'foo' with fixed time stamp
|
# create 'foo' with fixed time stamp
|
||||||
f = file('foo', 'w')
|
f = file('foo', 'w')
|
||||||
|
32
tests/test-dispatch.py
Normal file
32
tests/test-dispatch.py
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import os
|
||||||
|
from mercurial import commands
|
||||||
|
|
||||||
|
def dispatch(cmd):
|
||||||
|
"""Simple wrapper around commands.dispatch()
|
||||||
|
|
||||||
|
Prints command and result value, but does not handle quoting.
|
||||||
|
"""
|
||||||
|
print "running: %s" % (cmd,)
|
||||||
|
result = commands.dispatch(cmd.split())
|
||||||
|
print "result: %r" % (result,)
|
||||||
|
|
||||||
|
|
||||||
|
dispatch("init test1")
|
||||||
|
os.chdir('test1')
|
||||||
|
|
||||||
|
# create file 'foo', add and commit
|
||||||
|
f = file('foo', 'wb')
|
||||||
|
f.write('foo\n')
|
||||||
|
f.close()
|
||||||
|
dispatch("add foo")
|
||||||
|
dispatch("commit -m commit1 -d 2000-01-01 foo")
|
||||||
|
|
||||||
|
# append to file 'foo' and commit
|
||||||
|
f = file('foo', 'ab')
|
||||||
|
f.write('bar\n')
|
||||||
|
f.close()
|
||||||
|
dispatch("commit -m commit2 -d 2000-01-02 foo")
|
||||||
|
|
||||||
|
# check 88803a69b24 (fancyopts modified command table)
|
||||||
|
dispatch("log -r 0")
|
||||||
|
dispatch("log -r tip")
|
23
tests/test-dispatch.py.out
Normal file
23
tests/test-dispatch.py.out
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
running: init test1
|
||||||
|
result: None
|
||||||
|
running: add foo
|
||||||
|
result: None
|
||||||
|
running: commit -m commit1 -d 2000-01-01 foo
|
||||||
|
result: None
|
||||||
|
running: commit -m commit2 -d 2000-01-02 foo
|
||||||
|
result: None
|
||||||
|
running: log -r 0
|
||||||
|
changeset: 0:0e4634943879
|
||||||
|
user: test
|
||||||
|
date: Sat Jan 01 00:00:00 2000 +0000
|
||||||
|
summary: commit1
|
||||||
|
|
||||||
|
result: None
|
||||||
|
running: log -r tip
|
||||||
|
changeset: 1:45589e459b2e
|
||||||
|
tag: tip
|
||||||
|
user: test
|
||||||
|
date: Sun Jan 02 00:00:00 2000 +0000
|
||||||
|
summary: commit2
|
||||||
|
|
||||||
|
result: None
|
35
tests/test-issue672
Executable file
35
tests/test-issue672
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# 0-2-4
|
||||||
|
# \ \ \
|
||||||
|
# 1-3-5
|
||||||
|
#
|
||||||
|
# rename in #1, content change in #4.
|
||||||
|
|
||||||
|
hg init t
|
||||||
|
cd t
|
||||||
|
|
||||||
|
touch 1
|
||||||
|
touch 2
|
||||||
|
hg commit -Am init -d "0 0" # 0
|
||||||
|
|
||||||
|
hg rename 1 1a
|
||||||
|
hg commit -m rename -d "0 0" # 1
|
||||||
|
|
||||||
|
hg co -C 0
|
||||||
|
echo unrelated >> 2
|
||||||
|
hg ci -m unrelated1 -d "0 0" # 2
|
||||||
|
|
||||||
|
hg merge --debug 1
|
||||||
|
hg ci -m merge1 -d "0 0" # 3
|
||||||
|
|
||||||
|
hg co -C 2
|
||||||
|
echo hello >> 1
|
||||||
|
hg ci -m unrelated2 -d "0 0" # 4
|
||||||
|
|
||||||
|
hg co -C 3
|
||||||
|
hg merge -y --debug 4
|
||||||
|
|
||||||
|
hg co -C 4
|
||||||
|
hg merge -y --debug 3
|
||||||
|
|
33
tests/test-issue672.out
Normal file
33
tests/test-issue672.out
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
adding 1
|
||||||
|
adding 2
|
||||||
|
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||||||
|
resolving manifests
|
||||||
|
overwrite None partial False
|
||||||
|
ancestor 81f4b099af3d local c64f439569a9+ remote 2f8037f47a5c
|
||||||
|
1: other deleted -> r
|
||||||
|
1a: remote created -> g
|
||||||
|
removing 1
|
||||||
|
getting 1a
|
||||||
|
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||||||
|
(branch merge, don't forget to commit)
|
||||||
|
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||||||
|
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||||||
|
resolving manifests
|
||||||
|
overwrite None partial False
|
||||||
|
ancestor c64f439569a9 local ac7575e3c052+ remote 746e9549ea96
|
||||||
|
1a: local moved to 1 -> m
|
||||||
|
merging 1a and 1
|
||||||
|
my 1a@ac7575e3c052+ other 1@746e9549ea96 ancestor 1@81f4b099af3d
|
||||||
|
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
|
||||||
|
(branch merge, don't forget to commit)
|
||||||
|
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||||||
|
resolving manifests
|
||||||
|
overwrite None partial False
|
||||||
|
ancestor c64f439569a9 local 746e9549ea96+ remote ac7575e3c052
|
||||||
|
1: remote moved to 1a -> m
|
||||||
|
copying 1 to 1a
|
||||||
|
merging 1 and 1a
|
||||||
|
my 1@746e9549ea96+ other 1a@2f8037f47a5c ancestor 1@81f4b099af3d
|
||||||
|
removing 1
|
||||||
|
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
|
||||||
|
(branch merge, don't forget to commit)
|
@ -12,13 +12,13 @@
|
|||||||
# ln -s a a.lnk
|
# ln -s a a.lnk
|
||||||
# ln -s d/b d/b.lnk
|
# ln -s d/b d/b.lnk
|
||||||
# hg ci -Am t
|
# hg ci -Am t
|
||||||
# hg bundle --base null ../test-no-symlinks.bundle
|
# hg bundle --base null ../test-no-symlinks.hg
|
||||||
|
|
||||||
# Extract a symlink on a platform not supporting them
|
# Extract a symlink on a platform not supporting them
|
||||||
echo % unbundle
|
echo % unbundle
|
||||||
hg init t
|
hg init t
|
||||||
cd t
|
cd t
|
||||||
hg pull "$TESTDIR/test-no-symlinks.bundle"
|
hg pull -q "$TESTDIR/test-no-symlinks.hg"
|
||||||
hg update
|
hg update
|
||||||
|
|
||||||
cat a.lnk && echo
|
cat a.lnk && echo
|
||||||
@ -34,14 +34,14 @@ cat b2.lnk && echo
|
|||||||
|
|
||||||
# Bundle and extract again
|
# Bundle and extract again
|
||||||
echo % bundle
|
echo % bundle
|
||||||
hg bundle --base null ../symlinks.bundle
|
hg bundle --base null ../symlinks.hg
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
hg init t2
|
hg init t2
|
||||||
cd t2
|
cd t2
|
||||||
hg pull ../symlinks.bundle
|
hg pull ../symlinks.hg
|
||||||
hg update
|
hg update
|
||||||
|
|
||||||
cat a.lnk && echo
|
cat a.lnk && echo
|
||||||
cat d/a2.lnk && echo
|
cat d/a2.lnk && echo
|
||||||
cat b2.lnk && echo
|
cat b2.lnk && echo
|
||||||
|
@ -1,11 +1,4 @@
|
|||||||
% unbundle
|
% unbundle
|
||||||
pulling from C:\dev\mercurial\hg\hg-local-stable\tests/test-no-symlinks.bundle
|
|
||||||
requesting all changes
|
|
||||||
adding changesets
|
|
||||||
adding manifests
|
|
||||||
adding file changes
|
|
||||||
added 1 changesets with 4 changes to 4 files
|
|
||||||
(run 'hg update' to get a working copy)
|
|
||||||
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||||
a
|
a
|
||||||
d/b
|
d/b
|
||||||
@ -13,7 +6,7 @@ d/b
|
|||||||
a
|
a
|
||||||
d/b
|
d/b
|
||||||
% bundle
|
% bundle
|
||||||
pulling from ../symlinks.bundle
|
pulling from ../symlinks.hg
|
||||||
requesting all changes
|
requesting all changes
|
||||||
adding changesets
|
adding changesets
|
||||||
adding manifests
|
adding manifests
|
||||||
|
12
tests/test-profile
Executable file
12
tests/test-profile
Executable file
@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo % test --time
|
||||||
|
hg --time help 2>&1 | grep -q Time || echo --time failed
|
||||||
|
|
||||||
|
echo % test --profile
|
||||||
|
hg --profile help 2>&1 | grep -q ncalls || echo --profile failed
|
||||||
|
|
||||||
|
echo % test --lsprof
|
||||||
|
if "$TESTDIR/hghave" -q lsprof; then
|
||||||
|
hg --lsprof help 2>&1 | grep -q CallCount || echo --lsprof failed
|
||||||
|
fi
|
3
tests/test-profile.out
Normal file
3
tests/test-profile.out
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
% test --time
|
||||||
|
% test --profile
|
||||||
|
% test --lsprof
|
Loading…
Reference in New Issue
Block a user