mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 00:45:18 +03:00
merge crew and main
This commit is contained in:
commit
c5ab8c0508
@ -213,7 +213,9 @@ class repowatcher(object):
|
||||
if time != int(st_mtime):
|
||||
return 'l'
|
||||
return 'n'
|
||||
if type_ == '?' and self.dirstate._ignore(fn):
|
||||
if type_ == '?' and self.dirstate._dirignore(fn):
|
||||
# we must check not only if the file is ignored, but if any part
|
||||
# of its path match an ignore pattern
|
||||
return 'i'
|
||||
return type_
|
||||
|
||||
|
@ -476,6 +476,11 @@ class queue(object):
|
||||
write_list(self.full_series, self.series_path)
|
||||
if self.guards_dirty:
|
||||
write_list(self.active_guards, self.guards_path)
|
||||
if self.added:
|
||||
qrepo = self.qrepo()
|
||||
if qrepo:
|
||||
qrepo[None].add(self.added)
|
||||
self.added = []
|
||||
|
||||
def removeundo(self, repo):
|
||||
undo = repo.sjoin('undo')
|
||||
@ -1623,7 +1628,6 @@ class queue(object):
|
||||
if (len(files) > 1 or len(rev) > 1) and patchname:
|
||||
raise util.Abort(_('option "-n" not valid when importing multiple '
|
||||
'patches'))
|
||||
self.added = []
|
||||
if rev:
|
||||
# If mq patches are applied, we can only import revisions
|
||||
# that form a linear path to qbase.
|
||||
@ -1810,9 +1814,6 @@ def qimport(ui, repo, *filename, **opts):
|
||||
git=opts['git'])
|
||||
finally:
|
||||
q.save_dirty()
|
||||
qrepo = q.qrepo()
|
||||
if qrepo:
|
||||
qrepo[None].add(q.added)
|
||||
|
||||
if opts.get('push') and not opts.get('rev'):
|
||||
return q.push(repo, None)
|
||||
|
@ -271,9 +271,9 @@ def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
|
||||
'Commit the changes and store useful information in extra'
|
||||
try:
|
||||
repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
|
||||
if commitmsg is None:
|
||||
commitmsg = repo[rev].description()
|
||||
ctx = repo[rev]
|
||||
if commitmsg is None:
|
||||
commitmsg = ctx.description()
|
||||
extra = {'rebase_source': ctx.hex()}
|
||||
if extrafn:
|
||||
extrafn(ctx, extra)
|
||||
@ -347,23 +347,25 @@ def isagitpatch(repo, patchname):
|
||||
def updatemq(repo, state, skipped, **opts):
|
||||
'Update rebased mq patches - finalize and then import them'
|
||||
mqrebase = {}
|
||||
for p in repo.mq.applied:
|
||||
if repo[p.node].rev() in state:
|
||||
mq = repo.mq
|
||||
for p in mq.applied:
|
||||
rev = repo[p.node].rev()
|
||||
if rev in state:
|
||||
repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
|
||||
(repo[p.node].rev(), p.name))
|
||||
mqrebase[repo[p.node].rev()] = (p.name, isagitpatch(repo, p.name))
|
||||
(rev, p.name))
|
||||
mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
|
||||
|
||||
if mqrebase:
|
||||
repo.mq.finish(repo, mqrebase.keys())
|
||||
mq.finish(repo, mqrebase.keys())
|
||||
|
||||
# We must start import from the newest revision
|
||||
for rev in sorted(mqrebase, reverse=True):
|
||||
if rev not in skipped:
|
||||
repo.ui.debug('import mq patch %d (%s)\n'
|
||||
% (state[rev], mqrebase[rev][0]))
|
||||
repo.mq.qimport(repo, (), patchname=mqrebase[rev][0],
|
||||
git=mqrebase[rev][1],rev=[str(state[rev])])
|
||||
repo.mq.save_dirty()
|
||||
name, isgit = mqrebase[rev]
|
||||
repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
|
||||
mq.qimport(repo, (), patchname=name, git=isgit,
|
||||
rev=[str(state[rev])])
|
||||
mq.save_dirty()
|
||||
|
||||
def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
|
||||
external):
|
||||
|
@ -353,6 +353,10 @@ class filectx(object):
|
||||
return self._filelog.size(self._filerev)
|
||||
|
||||
def cmp(self, text):
|
||||
"""compare text with stored file revision
|
||||
|
||||
returns True if text is different than what is stored.
|
||||
"""
|
||||
return self._filelog.cmp(self._filenode, text)
|
||||
|
||||
def renamed(self):
|
||||
@ -932,7 +936,11 @@ class workingfilectx(filectx):
|
||||
return (t, tz)
|
||||
|
||||
def cmp(self, text):
|
||||
return self._repo.wread(self._path) == text
|
||||
"""compare text with disk content
|
||||
|
||||
returns True if text is different than what is on disk.
|
||||
"""
|
||||
return self._repo.wread(self._path) != text
|
||||
|
||||
class memctx(object):
|
||||
"""Use memctx to perform in-memory commits via localrepo.commitctx().
|
||||
|
@ -53,14 +53,27 @@ class filelog(revlog.revlog):
|
||||
if self.renamed(node):
|
||||
return len(self.read(node))
|
||||
|
||||
# XXX if self.read(node).startswith("\1\n"), this returns (size+4)
|
||||
return revlog.revlog.size(self, rev)
|
||||
|
||||
def cmp(self, node, text):
|
||||
"""compare text with a given file revision"""
|
||||
"""compare text with a given file revision
|
||||
|
||||
# for renames, we have to go the slow way
|
||||
if text.startswith('\1\n') or self.renamed(node):
|
||||
returns True if text is different than what is stored.
|
||||
"""
|
||||
|
||||
t = text
|
||||
if text.startswith('\1\n'):
|
||||
t = '\1\n\1\n' + text
|
||||
|
||||
samehashes = not revlog.revlog.cmp(self, node, t)
|
||||
if samehashes:
|
||||
return False
|
||||
|
||||
# renaming a file produces a different hash, even if the data
|
||||
# remains unchanged. Check if it's the case (slow):
|
||||
if self.renamed(node):
|
||||
t2 = self.read(node)
|
||||
return t2 != text
|
||||
|
||||
return revlog.revlog.cmp(self, node, text)
|
||||
return True
|
||||
|
@ -221,7 +221,7 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True,
|
||||
src_repo = repository(ui, source)
|
||||
else:
|
||||
src_repo = source
|
||||
branch = None
|
||||
branch = (None, [])
|
||||
origsource = source = src_repo.url()
|
||||
rev, checkout = addbranchrevs(src_repo, src_repo, branch, rev)
|
||||
|
||||
|
@ -10,6 +10,26 @@ import util, encoding
|
||||
import os, smtplib, socket, quopri
|
||||
import email.Header, email.MIMEText, email.Utils
|
||||
|
||||
_oldheaderinit = email.Header.Header.__init__
|
||||
def _unifiedheaderinit(self, *args, **kw):
|
||||
"""
|
||||
Python2.7 introduces a backwards incompatible change
|
||||
(Python issue1974, r70772) in email.Generator.Generator code:
|
||||
pre-2.7 code passed "continuation_ws='\t'" to the Header
|
||||
constructor, and 2.7 removed this parameter.
|
||||
|
||||
Default argument is continuation_ws=' ', which means that the
|
||||
behaviour is different in <2.7 and 2.7
|
||||
|
||||
We consider the 2.7 behaviour to be preferable, but need
|
||||
to have an unified behaviour for versions 2.4 to 2.7
|
||||
"""
|
||||
# override continuation_ws
|
||||
kw['continuation_ws'] = ' '
|
||||
_oldheaderinit(self, *args, **kw)
|
||||
|
||||
email.Header.Header.__dict__['__init__'] = _unifiedheaderinit
|
||||
|
||||
def _smtp(ui):
|
||||
'''build an smtp connection and return a function to send mail'''
|
||||
local_hostname = ui.config('smtp', 'local_hostname')
|
||||
|
@ -943,7 +943,10 @@ class revlog(object):
|
||||
raise LookupError(id, self.indexfile, _('no match found'))
|
||||
|
||||
def cmp(self, node, text):
|
||||
"""compare text with a given file revision"""
|
||||
"""compare text with a given file revision
|
||||
|
||||
returns True if text is different than what is stored.
|
||||
"""
|
||||
p1, p2 = self.parents(node)
|
||||
return hash(text, p1, p2) != node
|
||||
|
||||
|
@ -137,21 +137,21 @@ hg ci -m "b3 (HN)"
|
||||
echo '% case NN: msg'
|
||||
hg up -q null
|
||||
hg branch -f b
|
||||
echo 1 > B
|
||||
echo 1 > bb
|
||||
hg ci -Am "b4 (NN): new topo root for branch b"
|
||||
|
||||
echo '% case HN: no msg'
|
||||
echo 2 >> B
|
||||
echo 2 >> bb
|
||||
hg ci -m "b5 (HN)"
|
||||
|
||||
echo '% case BN: msg'
|
||||
hg branch -f default
|
||||
echo 1 > A
|
||||
echo 1 > aa
|
||||
hg ci -Am "a6 (BN): new branch root"
|
||||
|
||||
echo '% case CN: msg'
|
||||
hg up -q 4
|
||||
echo 3 >> BB
|
||||
echo 3 >> bbb
|
||||
hg ci -Am "b7 (CN): regular new head"
|
||||
|
||||
echo '% case BB: msg'
|
||||
|
@ -187,15 +187,15 @@ marked working directory as branch b
|
||||
adding b
|
||||
% case NN: msg
|
||||
marked working directory as branch b
|
||||
adding B
|
||||
adding bb
|
||||
created new head
|
||||
% case HN: no msg
|
||||
% case BN: msg
|
||||
marked working directory as branch default
|
||||
adding A
|
||||
adding aa
|
||||
created new head
|
||||
% case CN: msg
|
||||
adding BB
|
||||
adding bbb
|
||||
created new head
|
||||
% case BB: msg
|
||||
marked working directory as branch default
|
||||
|
@ -199,4 +199,14 @@ hg -R a parents --template "{node|short}\n"
|
||||
hg -R ua parents --template "{node|short}\n"
|
||||
rm -r ua
|
||||
|
||||
cat <<EOF > simpleclone.py
|
||||
from mercurial import ui, hg
|
||||
myui = ui.ui()
|
||||
repo = hg.repository(myui, 'a')
|
||||
hg.clone(myui, repo, dest="ua")
|
||||
EOF
|
||||
|
||||
python simpleclone.py
|
||||
rm -r ua
|
||||
|
||||
exit 0
|
||||
|
@ -312,3 +312,5 @@ summary: hacked default
|
||||
% same revision checked out in repo a and ua
|
||||
e8ece76546a6
|
||||
e8ece76546a6
|
||||
updating to branch default
|
||||
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
|
50
tests/test-filelog
Normal file
50
tests/test-filelog
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Tests the behaviour of filelog w.r.t. data starting with '\1\n'
|
||||
"""
|
||||
from mercurial import ui, hg
|
||||
from mercurial.node import nullid, hex
|
||||
|
||||
myui = ui.ui()
|
||||
repo = hg.repository(myui, path='.', create=True)
|
||||
|
||||
fl = repo.file('foobar')
|
||||
|
||||
def addrev(text, renamed=False):
|
||||
if renamed:
|
||||
# data doesnt matter. Just make sure filelog.renamed() returns True
|
||||
meta = dict(copyrev=hex(nullid), copy='bar')
|
||||
else:
|
||||
meta = {}
|
||||
|
||||
t = repo.transaction('commit')
|
||||
try:
|
||||
node = fl.add(text, meta, t, 0, nullid, nullid)
|
||||
return node
|
||||
finally:
|
||||
t.close()
|
||||
|
||||
def error(text):
|
||||
print 'ERROR: ' + text
|
||||
|
||||
textwith = '\1\nfoo'
|
||||
without = 'foo'
|
||||
|
||||
node = addrev(textwith)
|
||||
if not textwith == fl.read(node):
|
||||
error('filelog.read for data starting with \\1\\n')
|
||||
if fl.cmp(node, textwith) or not fl.cmp(node, without):
|
||||
error('filelog.cmp for data starting with \\1\\n')
|
||||
if fl.size(0) != len(textwith):
|
||||
error('FIXME: This is a known failure of filelog.size for data starting '
|
||||
'with \\1\\n')
|
||||
|
||||
node = addrev(textwith, renamed=True)
|
||||
if not textwith == fl.read(node):
|
||||
error('filelog.read for a renaming + data starting with \\1\\n')
|
||||
if fl.cmp(node, textwith) or not fl.cmp(node, without):
|
||||
error('filelog.cmp for a renaming + data starting with \\1\\n')
|
||||
if fl.size(1) != len(textwith):
|
||||
error('filelog.size for a renaming + data starting with \\1\\n')
|
||||
|
||||
print 'OK.'
|
2
tests/test-filelog.out
Normal file
2
tests/test-filelog.out
Normal file
@ -0,0 +1,2 @@
|
||||
ERROR: FIXME: This is a known failure of filelog.size for data starting with \1\n
|
||||
OK.
|
@ -97,4 +97,17 @@ hg ci -m 'working'
|
||||
echo b >> 1844/foo
|
||||
hg ci 1844 -m 'broken'
|
||||
|
||||
# Test for issue884: "Build products not ignored until .hgignore is touched"
|
||||
echo '^build$' > .hgignore
|
||||
hg add .hgignore
|
||||
hg ci .hgignore -m 'ignorelist'
|
||||
|
||||
# Now, lets add some build products...
|
||||
mkdir build
|
||||
touch build/x
|
||||
touch build/y
|
||||
|
||||
# build/x & build/y shouldn't appear in "hg st"
|
||||
hg st
|
||||
|
||||
kill `cat hg.pid`
|
||||
|
@ -573,7 +573,7 @@ Displaying [PATCH 3 of 3] charset=utf-8; content-transfer-encoding: quoted-print
|
||||
Content-Type: multipart/mixed; boundary="===
|
||||
MIME-Version: 1.0
|
||||
Subject: [PATCH 3 of 3] charset=utf-8;
|
||||
content-transfer-encoding: quoted-printable
|
||||
content-transfer-encoding: quoted-printable
|
||||
X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
|
||||
Message-Id: <c655633f8c87700bb38c.63@
|
||||
In-Reply-To: <patchbomb.60@
|
||||
@ -836,7 +836,7 @@ Displaying [PATCH 3 of 3] charset=utf-8; content-transfer-encoding: quoted-print
|
||||
Content-Type: multipart/mixed; boundary="===
|
||||
MIME-Version: 1.0
|
||||
Subject: [PATCH 3 of 3] charset=utf-8;
|
||||
content-transfer-encoding: quoted-printable
|
||||
content-transfer-encoding: quoted-printable
|
||||
X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
|
||||
Message-Id: <c655633f8c87700bb38c.63@
|
||||
In-Reply-To: <patchbomb.60@
|
||||
@ -1730,7 +1730,7 @@ Content-Type: text/plain; charset="us-ascii"
|
||||
MIME-Version: 1.0
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
Subject: [PATCH 3 of 8] charset=utf-8;
|
||||
content-transfer-encoding: quoted-printable
|
||||
content-transfer-encoding: quoted-printable
|
||||
X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
|
||||
Message-Id: <c655633f8c87700bb38c.315532863@
|
||||
In-Reply-To: <patchbomb.315532860@
|
||||
|
@ -101,6 +101,11 @@ hg qref --git -m 'P0 (git)'
|
||||
hg qnew f.patch
|
||||
echo 'mq2' > p
|
||||
hg qref -m 'P1'
|
||||
hg qcommit -m 'save patch state'
|
||||
echo '% patch series step 1/2'
|
||||
hg qseries -s
|
||||
echo '% patch queue manifest step 1/2'
|
||||
hg -R .hg/patches manifest
|
||||
|
||||
echo '% Git patch'
|
||||
cat .hg/patches/f_git.patch | filterpatch
|
||||
@ -112,6 +117,11 @@ cat .hg/patches/f.patch | filterpatch
|
||||
echo
|
||||
echo '% Rebase the applied mq patches'
|
||||
hg rebase -s 2 -d 1 --quiet
|
||||
hg qcommit -m 'save patch state'
|
||||
echo '% patch series step 2/2'
|
||||
hg qseries -s
|
||||
echo '% patch queue manifest step 2/2'
|
||||
hg -R .hg/patches manifest
|
||||
|
||||
echo '% And the patches are correct'
|
||||
echo '% Git patch'
|
||||
|
@ -80,6 +80,14 @@ popping f2.patch
|
||||
popping f.patch
|
||||
patch queue now empty
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
% patch series step 1/2
|
||||
f_git.patch: P0 (git)
|
||||
f.patch: P1
|
||||
% patch queue manifest step 1/2
|
||||
.hgignore
|
||||
f.patch
|
||||
f_git.patch
|
||||
series
|
||||
% Git patch
|
||||
P0 (git)
|
||||
|
||||
@ -101,6 +109,14 @@ diff -r x p
|
||||
+mq2
|
||||
|
||||
% Rebase the applied mq patches
|
||||
% patch series step 2/2
|
||||
f_git.patch: P0 (git)
|
||||
f.patch: P1
|
||||
% patch queue manifest step 2/2
|
||||
.hgignore
|
||||
f.patch
|
||||
f_git.patch
|
||||
series
|
||||
% And the patches are correct
|
||||
% Git patch
|
||||
# HG changeset patch
|
||||
|
Loading…
Reference in New Issue
Block a user