push: make locking of source optional (issue3684)
Having the permission to lock the source repo on push is now optional. When the
repo cannot be locked, phase are not changed locally. A status message is issue
when some actual phase movement are skipped:
cannot lock source repo, skipping local public phase update
A debug message with the exact reason of the locking failure is issued in all
case.
--- a/mercurial/localrepo.py Tue Apr 30 10:51:25 2013 +0200
+++ b/mercurial/localrepo.py Tue Apr 30 21:19:56 2013 +0200
@@ -1764,9 +1764,29 @@
unfi = self.unfiltered()
def localphasemove(nodes, phase=phases.public):
"""move <nodes> to <phase> in the local source repo"""
- phases.advanceboundary(self, phase, nodes)
+ if locallock is not None:
+ phases.advanceboundary(self, phase, nodes)
+ else:
+ # repo is not locked, do not change any phases!
+ # Informs the user that phases should have been moved when
+ # applicable.
+ actualmoves = [n for n in nodes if phase < self[n].phase()]
+ phasestr = phases.phasenames[phase]
+ if actualmoves:
+ self.ui.status(_('cannot lock source repo, skipping local'
+ ' %s phase update\n') % phasestr)
# get local lock as we might write phase data
- locallock = self.lock()
+ locallock = None
+ try:
+ locallock = self.lock()
+ except IOError, err:
+ if err.errno != errno.EACCES:
+ raise
+ # source repo cannot be locked.
+ # We do not abort the push, but just disable the local phase
+ # synchronisation.
+ msg = 'cannot lock source repository: %s\n' % err
+ self.ui.debug(msg)
try:
self.checkpush(force, revs)
lock = None
@@ -1918,7 +1938,8 @@
if lock is not None:
lock.release()
finally:
- locallock.release()
+ if locallock is not None:
+ locallock.release()
self.ui.debug("checking for updated bookmarks\n")
rb = remote.listkeys('bookmarks')
--- a/tests/test-phases-exchange.t Tue Apr 30 10:51:25 2013 +0200
+++ b/tests/test-phases-exchange.t Tue Apr 30 21:19:56 2013 +0200
@@ -1062,5 +1062,43 @@
|
o 0 public a-A - 054250a37db4
+
+Pushing From an unlockable repo
+--------------------------------
+(issue3684)
+
+Unability to lock the source repo should not prevent the push. It will prevent
+the retrieval of remote phase during push. For example, pushing to a publishing
+server won't turn changeset public.
+
+1. Test that push is not prevented
+
+ $ hg init Phi
+ $ cd Upsilon
+ $ chmod -R -w .hg
+ $ hg push ../Phi
+ pushing to ../Phi
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 14 changesets with 14 changes to 14 files (+3 heads)
+ $ chmod -R +w .hg
+
+2. Test that failed phases movement are reported
+
+ $ hg phase --force --draft 3
+ $ chmod -R -w .hg
+ $ hg push ../Phi
+ pushing to ../Phi
+ searching for changes
+ no changes found
+ cannot lock source repo, skipping local public phase update
+ [1]
+ $ chmod -R +w .hg
+ $ hgph Upsilon
+
+ $ cd ..
+
$ "$TESTDIR/killdaemons.py" $DAEMON_PIDS