Mercurial > hg > mercurial-crew-with-dirclash
changeset 1791:1ed9e97d9d6d
Merge with jeffpc's hg-static
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Wed, 22 Feb 2006 08:11:52 +0100 |
parents | d5248726d22f (diff) 88f0345d82e9 (current diff) |
children | a161c61ba8ed |
files | |
diffstat | 13 files changed, 388 insertions(+), 32 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/hgrc.5.txt +++ b/doc/hgrc.5.txt @@ -247,6 +247,9 @@ ui:: remote command to use for clone/push/pull operations. Default is 'hg'. ssh;; command to use for SSH connections. Default is 'ssh'. + timeout;; + The timeout used when a lock is held (in seconds), a negative value + means no timeout. Default is 600. username;; The committer of a changeset created when running "commit". Typically a person's name and email address, e.g. "Fred Widget
--- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1800,7 +1800,7 @@ def pull(ui, repo, source="default", **o return r -def push(ui, repo, dest="default-push", force=False, ssh=None, remotecmd=None): +def push(ui, repo, dest="default-push", **opts): """push changes to the specified destination Push changes from the local repository to the given destination. @@ -1825,13 +1825,16 @@ def push(ui, repo, dest="default-push", dest = ui.expandpath(dest, repo.root) ui.status('pushing to %s\n' % (dest)) - if ssh: - ui.setconfig("ui", "ssh", ssh) - if remotecmd: - ui.setconfig("ui", "remotecmd", remotecmd) + if opts['ssh']: + ui.setconfig("ui", "ssh", opts['ssh']) + if opts['remotecmd']: + ui.setconfig("ui", "remotecmd", opts['remotecmd']) other = hg.repository(ui, dest) - r = repo.push(other, force) + revs = None + if opts['rev']: + revs = [repo.lookup(rev) for rev in opts['rev']] + r = repo.push(other, opts['force'], revs=revs) return r def rawcommit(ui, repo, *flist, **rc): @@ -2505,14 +2508,15 @@ table = { ('r', 'rev', [], _('a specific revision you would like to pull')), ('', 'remotecmd', '', _('specify hg command to run on the remote side'))], - _('hg pull [-u] [-e FILE] [-r rev] [--remotecmd FILE] [SOURCE]')), + _('hg pull [-u] [-e FILE] [-r rev]... [--remotecmd FILE] [SOURCE]')), "^push": (push, [('f', 'force', None, _('force push')), ('e', 'ssh', '', _('specify ssh command to use')), + ('r', 'rev', [], _('a specific revision you would like to push')), ('', 'remotecmd', '', _('specify hg command to run on the remote side'))], - _('hg push [-f] [-e FILE] [--remotecmd FILE] [DEST]')), + _('hg push [-f] [-e FILE] [-r rev]... [--remotecmd FILE] [DEST]')), "rawcommit": (rawcommit, [('p', 'parent', [], _('parent')),
--- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -235,8 +235,7 @@ class localrepository(object): if os.path.exists(self.join("journal")): self.ui.status(_("rolling back interrupted transaction\n")) transaction.rollback(self.opener, self.join("journal")) - self.manifest = manifest.manifest(self.opener) - self.changelog = changelog.changelog(self.opener) + self.reload() return True else: self.ui.warn(_("no interrupted transaction available\n")) @@ -250,10 +249,20 @@ class localrepository(object): self.ui.status(_("rolling back last transaction\n")) transaction.rollback(self.opener, self.join("undo")) util.rename(self.join("undo.dirstate"), self.join("dirstate")) - self.dirstate.read() + self.reload() + self.wreload() else: self.ui.warn(_("no undo information available\n")) + def wreload(self): + self.dirstate.read() + + def reload(self): + self.changelog.load() + self.manifest.load() + self.tagscache = None + self.nodetagscache = None + def do_lock(self, lockname, wait, releasefn=None, acquirefn=None): try: l = lock.lock(self.join(lockname), 0, releasefn) @@ -261,18 +270,25 @@ class localrepository(object): if not wait: raise inst self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) - l = lock.lock(self.join(lockname), wait, releasefn) + try: + # default to 600 seconds timeout + l = lock.lock(self.join(lockname), + int(self.ui.config("ui", "timeout") or 600), + releasefn) + except lock.LockHeld, inst: + raise util.Abort(_("timeout while waiting for " + "lock held by %s") % inst.args[0]) if acquirefn: acquirefn() return l def lock(self, wait=1): - return self.do_lock("lock", wait) + return self.do_lock("lock", wait, acquirefn=self.reload) def wlock(self, wait=1): return self.do_lock("wlock", wait, self.dirstate.write, - self.dirstate.read) + self.wreload) def checkfilemerge(self, filename, text, filelog, manifest1, manifest2): "determine whether a new filenode is needed" @@ -950,8 +966,8 @@ class localrepository(object): cg = remote.changegroupsubset(fetch, heads, 'pull') return self.addchangegroup(cg) - def push(self, remote, force=False): - l = remote.lock() + def push(self, remote, force=False, revs=None): + lock = remote.lock() base = {} heads = remote.heads() @@ -962,17 +978,25 @@ class localrepository(object): return 1 update = self.findoutgoing(remote, base) - if not update: + if revs is not None: + msng_cl, bases, heads = self.changelog.nodesbetween(update, revs) + else: + bases, heads = update, self.changelog.heads() + + if not bases: self.ui.status(_("no changes found\n")) return 1 elif not force: - if len(heads) < len(self.changelog.heads()): + if len(bases) < len(heads): self.ui.warn(_("abort: push creates new remote branches!\n")) self.ui.status(_("(did you forget to merge?" " use push -f to force)\n")) return 1 - cg = self.changegroup(update, 'push') + if revs is None: + cg = self.changegroup(update, 'push') + else: + cg = self.changegroupsubset(update, revs, 'push') return remote.addchangegroup(cg) def changegroupsubset(self, bases, heads, source):
--- a/mercurial/lock.py +++ b/mercurial/lock.py @@ -16,10 +16,10 @@ class LockUnavailable(LockException): pass class lock(object): - def __init__(self, file, wait=1, releasefn=None): + def __init__(self, file, timeout=-1, releasefn=None): self.f = file self.held = 0 - self.wait = wait + self.timeout = timeout self.releasefn = releasefn self.lock() @@ -27,13 +27,16 @@ class lock(object): self.release() def lock(self): + timeout = self.timeout while 1: try: self.trylock() return 1 except LockHeld, inst: - if self.wait: + if timeout != 0: time.sleep(1) + if timeout > 0: + timeout -= 1 continue raise inst
--- a/mercurial/revlog.py +++ b/mercurial/revlog.py @@ -13,7 +13,7 @@ of the GNU General Public License, incor from node import * from i18n import gettext as _ from demandload import demandload -demandload(globals(), "binascii errno heapq mdiff sha struct zlib") +demandload(globals(), "binascii errno heapq mdiff os sha struct zlib") def hash(text, p1, p2): """generate a hash from the given text and its parent hashes @@ -187,15 +187,33 @@ class revlog(object): self.indexfile = indexfile self.datafile = datafile self.opener = opener + + self.indexstat = None self.cache = None self.chunkcache = None + self.load() + def load(self): try: - i = self.opener(self.indexfile).read() + f = self.opener(self.indexfile) except IOError, inst: if inst.errno != errno.ENOENT: raise i = "" + else: + try: + st = os.fstat(f.fileno()) + except AttributeError, inst: + st = None + else: + oldst = self.indexstat + if (oldst and st.st_dev == oldst.st_dev + and st.st_ino == oldst.st_ino + and st.st_mtime == oldst.st_mtime + and st.st_ctime == oldst.st_ctime): + return + self.indexstat = st + i = f.read() if i and i[:4] != "\0\0\0\0": raise RevlogError(_("incompatible revlog signature on %s") %
--- a/tests/test-archive +++ b/tests/test-archive @@ -18,8 +18,7 @@ echo "name = test-archive" >> .hg/hgrc echo "allowzip = true" >> .hg/hgrc echo "allowgz = true" >> .hg/hgrc echo "allowbz2 = true" >> .hg/hgrc -serverpid=`mktemp` -hg serve -p 20059 -d --pid-file=$serverpid +hg serve -p 20059 -d --pid-file=hg.pid TIP=`hg id -v | cut -f1 -d' '` QTIP=`hg id -q` @@ -35,5 +34,4 @@ http_proxy= python getarchive.py "$TIP" http_proxy= python getarchive.py "$TIP" zip > archive.zip unzip -t archive.zip | sed "s/$QTIP/TIP/" -kill `cat $serverpid` -rm $serverpid +kill `cat hg.pid`
new file mode 100755 --- /dev/null +++ b/tests/test-clone-pull-corruption @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Corrupt an hg repo with a pull started during an aborted commit +# + +# Create two repos, so that one of them can pull from the other one. +hg init source +cd source +touch foo +hg add foo +hg ci -m 'add foo' +hg clone . ../corrupted +echo >> foo +hg ci -m 'change foo' + +# Add a hook to wait 5 seconds and then abort the commit +cd ../corrupted +echo '[hooks]' >> .hg/hgrc +echo 'pretxncommit = sleep 5; exit 1' >> .hg/hgrc + +# start a commit... +touch bar +hg add bar +hg ci -m 'add bar' & + +# ... and start a pull while the commit is still running +sleep 1 +hg pull ../source 2>/dev/null + +# see what happened +wait +hg verify
new file mode 100644 --- /dev/null +++ b/tests/test-clone-pull-corruption.out @@ -0,0 +1,15 @@ +pulling from ../source +abort: pretxncommit hook exited with status 1 +transaction abort! +rollback completed +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +(run 'hg update' to get a working copy) +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 2 changesets, 2 total revisions
--- a/tests/test-pull +++ b/tests/test-pull @@ -7,8 +7,7 @@ hg init hg addremove hg commit -m 1 hg verify -serverpid=`mktemp` -hg serve -p 20059 -d --pid-file=$serverpid +hg serve -p 20059 -d --pid-file=hg.pid cd .. hg clone http://localhost:20059/ copy @@ -19,5 +18,4 @@ cat foo hg manifest hg pull -kill `cat $serverpid` -rm $serverpid +kill `cat ../test/hg.pid`
new file mode 100755 --- /dev/null +++ b/tests/test-pull-pull-corruption @@ -0,0 +1,41 @@ +#!/bin/sh +# +# Corrupt an hg repo with two pulls. +# + +# create one repo with a long history +hg init source1 +cd source1 +touch foo +hg add foo +for i in 1 2 3 4 5 6 7 8 9 10; do + echo $i >> foo + hg ci -m $i +done +cd .. + +# create one repo with a shorter history +hg clone -r 0 source1 source2 +cd source2 +echo a >> foo +hg ci -m a +cd .. + +# create a third repo to pull both other repos into it +hg init corrupted +cd corrupted +# use a hook to make the second pull start while the first one is still running +echo '[hooks]' >> .hg/hgrc +echo 'prechangegroup = sleep 5' >> .hg/hgrc + +# start a pull... +hg pull ../source1 & + +# ... and start another pull before the first one has finished +sleep 1 +hg pull ../source2 2>/dev/null + +# see the result +wait +hg verify +
new file mode 100644 --- /dev/null +++ b/tests/test-pull-pull-corruption.out @@ -0,0 +1,24 @@ +requesting all changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +pulling from ../source2 +pulling from ../source1 +requesting all changes +adding changesets +adding manifests +adding file changes +added 10 changesets with 10 changes to 1 files +(run 'hg update' to get a working copy) +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files (+1 heads) +(run 'hg update' to get a working copy) +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 11 changesets, 11 total revisions
new file mode 100755 --- /dev/null +++ b/tests/test-push-r @@ -0,0 +1,61 @@ +#!/bin/bash + +hg init test +cd test +cat >>afile <<EOF +0 +EOF +hg add afile +hg commit -m "0.0" +cat >>afile <<EOF +1 +EOF +hg commit -m "0.1" +cat >>afile <<EOF +2 +EOF +hg commit -m "0.2" +cat >>afile <<EOF +3 +EOF +hg commit -m "0.3" +hg update -C 0 +cat >>afile <<EOF +1 +EOF +hg commit -m "1.1" +cat >>afile <<EOF +2 +EOF +hg commit -m "1.2" +cat >fred <<EOF +a line +EOF +cat >>afile <<EOF +3 +EOF +hg add fred +hg commit -m "1.3" +hg mv afile adifferentfile +hg commit -m "1.3m" +hg update -C 3 +hg mv afile anotherfile +hg commit -m "0.3m" +hg debugindex .hg/data/afile.i +hg debugindex .hg/data/adifferentfile.i +hg debugindex .hg/data/anotherfile.i +hg debugindex .hg/data/fred.i +hg debugindex .hg/00manifest.i +hg verify +cd .. +for i in 0 1 2 3 4 5 6 7 8; do + mkdir test-"$i" + hg --cwd test-"$i" init + hg -R test push -r "$i" test-"$i" + cd test-"$i" + hg verify + cd .. +done +cd test-8 +hg pull ../test-7 +hg verify
new file mode 100644 --- /dev/null +++ b/tests/test-push-r.out @@ -0,0 +1,135 @@ + rev offset length base linkrev nodeid p1 p2 + 0 0 3 0 0 362fef284ce2 000000000000 000000000000 + 1 3 5 1 1 125144f7e028 362fef284ce2 000000000000 + 2 8 7 2 2 4c982badb186 125144f7e028 000000000000 + 3 15 9 3 3 19b1fc555737 4c982badb186 000000000000 + rev offset length base linkrev nodeid p1 p2 + 0 0 75 0 7 905359268f77 000000000000 000000000000 + rev offset length base linkrev nodeid p1 p2 + 0 0 75 0 8 905359268f77 000000000000 000000000000 + rev offset length base linkrev nodeid p1 p2 + 0 0 8 0 6 12ab3bcc5ea4 000000000000 000000000000 + rev offset length base linkrev nodeid p1 p2 + 0 0 48 0 0 43eadb1d2d06 000000000000 000000000000 + 1 48 48 1 1 8b89697eba2c 43eadb1d2d06 000000000000 + 2 96 48 2 2 626a32663c2f 8b89697eba2c 000000000000 + 3 144 48 3 3 f54c32f13478 626a32663c2f 000000000000 + 4 192 58 3 6 de68e904d169 626a32663c2f 000000000000 + 5 250 68 3 7 3b45cc2ab868 de68e904d169 000000000000 + 6 318 54 6 8 24d86153a002 f54c32f13478 000000000000 +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +4 files, 9 changesets, 7 total revisions +pushing to test-0 +searching for changes +adding changesets +adding manifests +adding file changes +added 1 changesets with 1 changes to 1 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 1 changesets, 1 total revisions +pushing to test-1 +searching for changes +adding changesets +adding manifests +adding file changes +added 2 changesets with 2 changes to 1 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 2 changesets, 2 total revisions +pushing to test-2 +searching for changes +adding changesets +adding manifests +adding file changes +added 3 changesets with 3 changes to 1 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 3 changesets, 3 total revisions +pushing to test-3 +searching for changes +adding changesets +adding manifests +adding file changes +added 4 changesets with 4 changes to 1 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 4 changesets, 4 total revisions +pushing to test-4 +searching for changes +adding changesets +adding manifests +adding file changes +added 2 changesets with 2 changes to 1 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 2 changesets, 2 total revisions +pushing to test-5 +searching for changes +adding changesets +adding manifests +adding file changes +added 3 changesets with 3 changes to 1 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +1 files, 3 changesets, 3 total revisions +pushing to test-6 +searching for changes +adding changesets +adding manifests +adding file changes +added 4 changesets with 5 changes to 2 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +2 files, 4 changesets, 5 total revisions +pushing to test-7 +searching for changes +adding changesets +adding manifests +adding file changes +added 5 changesets with 6 changes to 3 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +3 files, 5 changesets, 6 total revisions +pushing to test-8 +searching for changes +adding changesets +adding manifests +adding file changes +added 5 changesets with 5 changes to 2 files +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +2 files, 5 changesets, 5 total revisions +pulling from ../test-7 +searching for changes +adding changesets +adding manifests +adding file changes +added 4 changesets with 2 changes to 3 files (+1 heads) +(run 'hg update' to get a working copy) +checking changesets +checking manifests +crosschecking files in changesets and manifests +checking files +4 files, 9 changesets, 7 total revisions