merge crew and main

This commit is contained in:
Henrik Stuart 2010-07-14 19:43:31 +02:00
commit c5ab8c0508
18 changed files with 186 additions and 34 deletions

View File

@ -213,7 +213,9 @@ class repowatcher(object):
if time != int(st_mtime): if time != int(st_mtime):
return 'l' return 'l'
return 'n' 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 'i'
return type_ return type_

View File

@ -476,6 +476,11 @@ class queue(object):
write_list(self.full_series, self.series_path) write_list(self.full_series, self.series_path)
if self.guards_dirty: if self.guards_dirty:
write_list(self.active_guards, self.guards_path) 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): def removeundo(self, repo):
undo = repo.sjoin('undo') undo = repo.sjoin('undo')
@ -1623,7 +1628,6 @@ class queue(object):
if (len(files) > 1 or len(rev) > 1) and patchname: if (len(files) > 1 or len(rev) > 1) and patchname:
raise util.Abort(_('option "-n" not valid when importing multiple ' raise util.Abort(_('option "-n" not valid when importing multiple '
'patches')) 'patches'))
self.added = []
if rev: if rev:
# If mq patches are applied, we can only import revisions # If mq patches are applied, we can only import revisions
# that form a linear path to qbase. # that form a linear path to qbase.
@ -1810,9 +1814,6 @@ def qimport(ui, repo, *filename, **opts):
git=opts['git']) git=opts['git'])
finally: finally:
q.save_dirty() q.save_dirty()
qrepo = q.qrepo()
if qrepo:
qrepo[None].add(q.added)
if opts.get('push') and not opts.get('rev'): if opts.get('push') and not opts.get('rev'):
return q.push(repo, None) return q.push(repo, None)

View File

@ -271,9 +271,9 @@ def concludenode(repo, rev, p1, p2, commitmsg=None, extrafn=None):
'Commit the changes and store useful information in extra' 'Commit the changes and store useful information in extra'
try: try:
repo.dirstate.setparents(repo[p1].node(), repo[p2].node()) repo.dirstate.setparents(repo[p1].node(), repo[p2].node())
if commitmsg is None:
commitmsg = repo[rev].description()
ctx = repo[rev] ctx = repo[rev]
if commitmsg is None:
commitmsg = ctx.description()
extra = {'rebase_source': ctx.hex()} extra = {'rebase_source': ctx.hex()}
if extrafn: if extrafn:
extrafn(ctx, extra) extrafn(ctx, extra)
@ -347,23 +347,25 @@ def isagitpatch(repo, patchname):
def updatemq(repo, state, skipped, **opts): def updatemq(repo, state, skipped, **opts):
'Update rebased mq patches - finalize and then import them' 'Update rebased mq patches - finalize and then import them'
mqrebase = {} mqrebase = {}
for p in repo.mq.applied: mq = repo.mq
if repo[p.node].rev() in state: 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.ui.debug('revision %d is an mq patch (%s), finalize it.\n' %
(repo[p.node].rev(), p.name)) (rev, p.name))
mqrebase[repo[p.node].rev()] = (p.name, isagitpatch(repo, p.name)) mqrebase[rev] = (p.name, isagitpatch(repo, p.name))
if mqrebase: if mqrebase:
repo.mq.finish(repo, mqrebase.keys()) mq.finish(repo, mqrebase.keys())
# We must start import from the newest revision # We must start import from the newest revision
for rev in sorted(mqrebase, reverse=True): for rev in sorted(mqrebase, reverse=True):
if rev not in skipped: if rev not in skipped:
repo.ui.debug('import mq patch %d (%s)\n' name, isgit = mqrebase[rev]
% (state[rev], mqrebase[rev][0])) repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name))
repo.mq.qimport(repo, (), patchname=mqrebase[rev][0], mq.qimport(repo, (), patchname=name, git=isgit,
git=mqrebase[rev][1],rev=[str(state[rev])]) rev=[str(state[rev])])
repo.mq.save_dirty() mq.save_dirty()
def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches, def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches,
external): external):

View File

@ -353,6 +353,10 @@ class filectx(object):
return self._filelog.size(self._filerev) return self._filelog.size(self._filerev)
def cmp(self, text): 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) return self._filelog.cmp(self._filenode, text)
def renamed(self): def renamed(self):
@ -932,7 +936,11 @@ class workingfilectx(filectx):
return (t, tz) return (t, tz)
def cmp(self, text): 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): class memctx(object):
"""Use memctx to perform in-memory commits via localrepo.commitctx(). """Use memctx to perform in-memory commits via localrepo.commitctx().

View File

@ -53,14 +53,27 @@ class filelog(revlog.revlog):
if self.renamed(node): if self.renamed(node):
return len(self.read(node)) return len(self.read(node))
# XXX if self.read(node).startswith("\1\n"), this returns (size+4)
return revlog.revlog.size(self, rev) return revlog.revlog.size(self, rev)
def cmp(self, node, text): 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 returns True if text is different than what is stored.
if text.startswith('\1\n') or self.renamed(node): """
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) t2 = self.read(node)
return t2 != text return t2 != text
return revlog.revlog.cmp(self, node, text) return True

View File

@ -221,7 +221,7 @@ def clone(ui, source, dest=None, pull=False, rev=None, update=True,
src_repo = repository(ui, source) src_repo = repository(ui, source)
else: else:
src_repo = source src_repo = source
branch = None branch = (None, [])
origsource = source = src_repo.url() origsource = source = src_repo.url()
rev, checkout = addbranchrevs(src_repo, src_repo, branch, rev) rev, checkout = addbranchrevs(src_repo, src_repo, branch, rev)

View File

@ -10,6 +10,26 @@ import util, encoding
import os, smtplib, socket, quopri import os, smtplib, socket, quopri
import email.Header, email.MIMEText, email.Utils 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): def _smtp(ui):
'''build an smtp connection and return a function to send mail''' '''build an smtp connection and return a function to send mail'''
local_hostname = ui.config('smtp', 'local_hostname') local_hostname = ui.config('smtp', 'local_hostname')

View File

@ -943,7 +943,10 @@ class revlog(object):
raise LookupError(id, self.indexfile, _('no match found')) raise LookupError(id, self.indexfile, _('no match found'))
def cmp(self, node, text): 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) p1, p2 = self.parents(node)
return hash(text, p1, p2) != node return hash(text, p1, p2) != node

View File

@ -137,21 +137,21 @@ hg ci -m "b3 (HN)"
echo '% case NN: msg' echo '% case NN: msg'
hg up -q null hg up -q null
hg branch -f b hg branch -f b
echo 1 > B echo 1 > bb
hg ci -Am "b4 (NN): new topo root for branch b" hg ci -Am "b4 (NN): new topo root for branch b"
echo '% case HN: no msg' echo '% case HN: no msg'
echo 2 >> B echo 2 >> bb
hg ci -m "b5 (HN)" hg ci -m "b5 (HN)"
echo '% case BN: msg' echo '% case BN: msg'
hg branch -f default hg branch -f default
echo 1 > A echo 1 > aa
hg ci -Am "a6 (BN): new branch root" hg ci -Am "a6 (BN): new branch root"
echo '% case CN: msg' echo '% case CN: msg'
hg up -q 4 hg up -q 4
echo 3 >> BB echo 3 >> bbb
hg ci -Am "b7 (CN): regular new head" hg ci -Am "b7 (CN): regular new head"
echo '% case BB: msg' echo '% case BB: msg'

View File

@ -187,15 +187,15 @@ marked working directory as branch b
adding b adding b
% case NN: msg % case NN: msg
marked working directory as branch b marked working directory as branch b
adding B adding bb
created new head created new head
% case HN: no msg % case HN: no msg
% case BN: msg % case BN: msg
marked working directory as branch default marked working directory as branch default
adding A adding aa
created new head created new head
% case CN: msg % case CN: msg
adding BB adding bbb
created new head created new head
% case BB: msg % case BB: msg
marked working directory as branch default marked working directory as branch default

View File

@ -199,4 +199,14 @@ hg -R a parents --template "{node|short}\n"
hg -R ua parents --template "{node|short}\n" hg -R ua parents --template "{node|short}\n"
rm -r ua 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 exit 0

View File

@ -312,3 +312,5 @@ summary: hacked default
% same revision checked out in repo a and ua % same revision checked out in repo a and ua
e8ece76546a6 e8ece76546a6
e8ece76546a6 e8ece76546a6
updating to branch default
3 files updated, 0 files merged, 0 files removed, 0 files unresolved

50
tests/test-filelog Normal file
View 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
View File

@ -0,0 +1,2 @@
ERROR: FIXME: This is a known failure of filelog.size for data starting with \1\n
OK.

View File

@ -97,4 +97,17 @@ hg ci -m 'working'
echo b >> 1844/foo echo b >> 1844/foo
hg ci 1844 -m 'broken' 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` kill `cat hg.pid`

View File

@ -573,7 +573,7 @@ Displaying [PATCH 3 of 3] charset=utf-8; content-transfer-encoding: quoted-print
Content-Type: multipart/mixed; boundary="=== Content-Type: multipart/mixed; boundary="===
MIME-Version: 1.0 MIME-Version: 1.0
Subject: [PATCH 3 of 3] charset=utf-8; Subject: [PATCH 3 of 3] charset=utf-8;
content-transfer-encoding: quoted-printable content-transfer-encoding: quoted-printable
X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376 X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
Message-Id: <c655633f8c87700bb38c.63@ Message-Id: <c655633f8c87700bb38c.63@
In-Reply-To: <patchbomb.60@ 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="=== Content-Type: multipart/mixed; boundary="===
MIME-Version: 1.0 MIME-Version: 1.0
Subject: [PATCH 3 of 3] charset=utf-8; Subject: [PATCH 3 of 3] charset=utf-8;
content-transfer-encoding: quoted-printable content-transfer-encoding: quoted-printable
X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376 X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
Message-Id: <c655633f8c87700bb38c.63@ Message-Id: <c655633f8c87700bb38c.63@
In-Reply-To: <patchbomb.60@ In-Reply-To: <patchbomb.60@
@ -1730,7 +1730,7 @@ Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0 MIME-Version: 1.0
Content-Transfer-Encoding: quoted-printable Content-Transfer-Encoding: quoted-printable
Subject: [PATCH 3 of 8] charset=utf-8; Subject: [PATCH 3 of 8] charset=utf-8;
content-transfer-encoding: quoted-printable content-transfer-encoding: quoted-printable
X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376 X-Mercurial-Node: c655633f8c87700bb38cc6a59a2753bdc5a6c376
Message-Id: <c655633f8c87700bb38c.315532863@ Message-Id: <c655633f8c87700bb38c.315532863@
In-Reply-To: <patchbomb.315532860@ In-Reply-To: <patchbomb.315532860@

View File

@ -101,6 +101,11 @@ hg qref --git -m 'P0 (git)'
hg qnew f.patch hg qnew f.patch
echo 'mq2' > p echo 'mq2' > p
hg qref -m 'P1' 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' echo '% Git patch'
cat .hg/patches/f_git.patch | filterpatch cat .hg/patches/f_git.patch | filterpatch
@ -112,6 +117,11 @@ cat .hg/patches/f.patch | filterpatch
echo echo
echo '% Rebase the applied mq patches' echo '% Rebase the applied mq patches'
hg rebase -s 2 -d 1 --quiet 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 '% And the patches are correct'
echo '% Git patch' echo '% Git patch'

View File

@ -80,6 +80,14 @@ popping f2.patch
popping f.patch popping f.patch
patch queue now empty patch queue now empty
1 files updated, 0 files merged, 0 files removed, 0 files unresolved 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 % Git patch
P0 (git) P0 (git)
@ -101,6 +109,14 @@ diff -r x p
+mq2 +mq2
% Rebase the applied mq patches % 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 % And the patches are correct
% Git patch % Git patch
# HG changeset patch # HG changeset patch