[patch bugfix] Skip repositories not readable with current privileges; skip empty “.hg” directories, e.g. unmounted mountpoints
Roland Eggner
edvx1 at systemanalysen.net
Mon Dec 30 12:52:07 CST 2013
# HG changeset patch
# Parent ad445599010834299cb1d6cc7db0315df3b61923
# User Roland Eggner < odv at systomanalyson.not s/o/e/g >
# Date 1388261157 -3600
[bugfix] Skip repositories not readable with current privileges; skip empty “.hg” directories, e.g. unmounted mountpoints.
[bug] Existence of an unreadable “/.hg” directory causes run-tests.py failures.
[bugfix] Skip repositories not readable with current privileges; skip empty “.hg” directories.
By this bugfix empty “.hg” directories are no more considered valid mercurial repositories.
In case of an unmounted mount point mercurial does no more write repository data _silently_ to the wrong filesystem.
Bug reported at
http://thread.gmane.org/gmane.comp.version-control.mercurial.devel/51339
diff --git a/contrib/bash_completion b/contrib/bash_completion
--- a/contrib/bash_completion
+++ b/contrib/bash_completion
@@ -75,8 +75,10 @@ shopt -s extglob
_hg_repos()
{
local i
- for i in $(compgen -d -- "$cur"); do
- test ! -d "$i"/.hg || COMPREPLY=(${COMPREPLY[@]:-} "$i")
+ for i in $( compgen -d -- "$cur" ) ; do
+ [[ -r "$i/.hg/requires" \
+ || -r "$i/.hg/00changelog.i" ]] \
+ && COMPREPLY+=( "$i" )
done
}
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -9,6 +9,7 @@ from node import hex, nullid, nullrev, s
from i18n import _
import os, sys, errno, re, tempfile
import util, scmutil, templater, patch, error, templatekw, revlog, copies
+from readable_repository import readable_repository
import match as matchmod
import subrepo, context, repair, graphmod, revset, phases, obsolete
import changelog
@@ -72,7 +73,7 @@ def findcmd(cmd, table, strict=True):
raise error.UnknownCommand(cmd)
def findrepo(p):
- while not os.path.isdir(os.path.join(p, ".hg")):
+ while not readable_repository(p):
oldp, p = p, os.path.dirname(p)
if p == oldp:
return None
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -10,6 +10,7 @@ import peer, changegroup, subrepo, disco
import changelog, dirstate, filelog, manifest, context, bookmarks, phases
import lock, transaction, store, encoding
import scmutil, util, extensions, hook, error, revset
+from readable_repository import readable_repository
import match as matchmod
import merge as mergemod
import tags as tagsmod
@@ -191,7 +192,7 @@ class localrepository(object):
else:
self.supported = self._basesupported
- if not self.vfs.isdir():
+ if not readable_repository(self.root):
if create:
if not self.wvfs.exists():
self.wvfs.makedirs()
diff --git a/mercurial/readable_repository.py b/mercurial/readable_repository.py
new file mode 100644
--- /dev/null
+++ b/mercurial/readable_repository.py
@@ -0,0 +1,23 @@
+# readable_repository.py
+# check if there is a readable, valid mercurial repository in the
+# given "reporoot" directory
+#
+# Copyright 2013 Matt Mackall <mpm at selenic.com>, Roland Eggner <edv at systemanalysen.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+import os
+
+def readable_repository(reporoot):
+ # Assumptions:
+ # In valid revlogv1 and later repositories there is always a readable file '.hg/requires'.
+ # In valid revlogv0 repositories there is always a readable file '.hg/00changelog.i'.
+ # Targets:
+ # Skip empty '.hg' directories, e.g. currently not mounted mount points.
+ # Skip repositories unreadable with current privileges.
+ reporoot_hg = os.path.join(reporoot, '.hg')
+ return (os.path.isdir(reporoot_hg)
+ and ((os.path.isfile(os.path.join(reporoot_hg, 'requires' )) and os.access(os.path.join(reporoot_hg, 'requires' ), os.R_OK))
+ or (os.path.isfile(os.path.join(reporoot_hg, '00changelog.i')) and os.access(os.path.join(reporoot_hg, '00changelog.i'), os.R_OK))))
+
diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py
--- a/mercurial/scmutil.py
+++ b/mercurial/scmutil.py
@@ -8,6 +8,7 @@
from i18n import _
from mercurial.node import nullrev
import util, error, osutil, revset, similar, encoding, phases, parsers
+from readable_repository import readable_repository
import match as matchmod
import os, errno, re, stat, glob
@@ -516,7 +517,7 @@ def walkrepos(path, followsym=False, see
adddir(seen_dirs, path)
for root, dirs, files in os.walk(path, topdown=True, onerror=errhandler):
dirs.sort()
- if '.hg' in dirs:
+ if readable_repository(root):
yield root # found a repository
qroot = os.path.join(root, '.hg', 'patches')
if os.path.isdir(os.path.join(qroot, '.hg')):
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://selenic.com/pipermail/mercurial-devel/attachments/20131230/b11a6828/attachment.pgp>
More information about the Mercurial-devel
mailing list