fetch: hold lock and wlock across all operations
authorVadim Gelfer <vadim.gelfer@gmail.com>
Tue, 08 Aug 2006 17:08:59 -0700
changeset 2827 2a0c599f7bb0
parent 2826 bce6918b0474
child 2828 12139eedd6a0
fetch: hold lock and wlock across all operations
hgext/fetch.py
mercurial/localrepo.py
--- a/hgext/fetch.py	Wed Aug 09 02:04:49 2006 -0700
+++ b/hgext/fetch.py	Tue Aug 08 17:08:59 2006 -0700
@@ -24,29 +24,30 @@
         if modheads == 0:
             return 0
         if modheads == 1:
-            return hg.update(repo, repo.changelog.tip())
+            return hg.update(repo, repo.changelog.tip(), wlock=wlock)
         newheads = repo.heads(parent)
         newchildren = [n for n in repo.heads(parent) if n != parent]
         newparent = parent
         if newchildren:
             newparent = newchildren[0]
-            hg.update(repo, newparent)
+            hg.update(repo, newparent, wlock=wlock)
         newheads = [n for n in repo.heads() if n != newparent]
         err = False
         if newheads:
             ui.status(_('merging with new head %d:%s\n') %
                       (repo.changelog.rev(newheads[0]), short(newheads[0])))
-            err = hg.update(repo, newheads[0], allow=True, remind=False)
+            err = hg.update(repo, newheads[0], allow=True, remind=False,
+                            wlock=wlock)
         if not err and len(newheads) > 1:
             ui.status(_('not merging with %d other new heads '
                         '(use "hg heads" and "hg merge" to merge them)') %
                       (len(newheads) - 1))
         if not err:
-            mod, add, rem = repo.status()[:3]
+            mod, add, rem = repo.status(wlock=wlock)[:3]
             message = (commands.logmessage(opts) or
                        (_('Automated merge with %s') % other.url()))
             n = repo.commit(mod + add + rem, message,
-                            opts['user'], opts['date'], lock=lock,
+                            opts['user'], opts['date'], lock=lock, wlock=wlock,
                             force_editor=opts.get('force_editor'))
             ui.status(_('new changeset %d:%s merges remote changes '
                         'with local\n') % (repo.changelog.rev(n),
@@ -55,7 +56,7 @@
         commands.setremoteconfig(ui, opts)
 
         other = hg.repository(ui, ui.expandpath(source))
-        ui.status(_('pulling from %s\n') % source)
+        ui.status(_('pulling from %s\n') % ui.expandpath(source))
         revs = None
         if opts['rev'] and not other.local():
             raise util.Abort(_("fetch -r doesn't work for remote repositories yet"))
@@ -70,17 +71,19 @@
                            '(use "hg update" to check out tip)'))
     if p2 != nullid:
         raise util.Abort(_('outstanding uncommitted merge'))
-    mod, add, rem = repo.status()[:3]
-    if mod or add or rem:
-        raise util.Abort(_('outstanding uncommitted changes'))
-    if len(repo.heads()) > 1:
-        raise util.Abort(_('multiple heads in this repository '
-                           '(use "hg heads" and "hg merge" to merge them)'))
+    wlock = repo.wlock()
     lock = repo.lock()
     try:
+        mod, add, rem = repo.status(wlock=wlock)[:3]
+        if mod or add or rem:
+            raise util.Abort(_('outstanding uncommitted changes'))
+        if len(repo.heads()) > 1:
+            raise util.Abort(_('multiple heads in this repository '
+                               '(use "hg heads" and "hg merge" to merge)'))
         return pull()
     finally:
         lock.release()
+        wlock.release()
 
 cmdtable = {
     'fetch':
--- a/mercurial/localrepo.py	Wed Aug 09 02:04:49 2006 -0700
+++ b/mercurial/localrepo.py	Tue Aug 08 17:08:59 2006 -0700
@@ -1177,22 +1177,29 @@
         else:
             return subset
 
-    def pull(self, remote, heads=None, force=False):
-        l = self.lock()
+    def pull(self, remote, heads=None, force=False, lock=None):
+        mylock = False
+        if not lock:
+            lock = self.lock()
+            mylock = True
 
-        fetch = self.findincoming(remote, force=force)
-        if fetch == [nullid]:
-            self.ui.status(_("requesting all changes\n"))
+        try:
+            fetch = self.findincoming(remote, force=force)
+            if fetch == [nullid]:
+                self.ui.status(_("requesting all changes\n"))
 
-        if not fetch:
-            self.ui.status(_("no changes found\n"))
-            return 0
+            if not fetch:
+                self.ui.status(_("no changes found\n"))
+                return 0
 
-        if heads is None:
-            cg = remote.changegroup(fetch, 'pull')
-        else:
-            cg = remote.changegroupsubset(fetch, heads, 'pull')
-        return self.addchangegroup(cg, 'pull', remote.url())
+            if heads is None:
+                cg = remote.changegroup(fetch, 'pull')
+            else:
+                cg = remote.changegroupsubset(fetch, heads, 'pull')
+            return self.addchangegroup(cg, 'pull', remote.url())
+        finally:
+            if mylock:
+                lock.release()
 
     def push(self, remote, force=False, revs=None):
         # there are two ways to push to remote repo: