[PATCH 3/3] vc: Add ability to check if version control repos are valid



Sometimes meld may be ran in a directory that contains invalid or
corrupt version control information.  (eg run 'mkdir .svn; meld .' in a
git repository).  Previously meld would not gracefully handle invalid
repositories.  This patch attempts to add a quick sanity check
to most version control systems.  The checks are meant to be
as quick as possible to reduce startup time.

Signed-off-by: Peter Tyser <ptyser gmail com>
---
Note: I implemented the valid_repo() for a number of version control tools
but only really feel confident about the svn and git changes.  It'd be
appreciated if others could test if they use darcs, hg, etc as I don't.
I didn't see an easy, quick way to implement valid_repo() for rcs or
arch, so feel free to add them if someone uses them.

 meld/vc/_vc.py       |    4 ++++
 meld/vc/bzr.py       |    5 +++++
 meld/vc/cvs.py       |    5 +++++
 meld/vc/darcs.py     |    6 ++++++
 meld/vc/git.py       |    5 +++++
 meld/vc/mercurial.py |    5 +++++
 meld/vc/monotone.py  |    5 +++++
 meld/vc/svn.py       |    5 +++++
 meld/vc/tla.py       |    6 ++++++
 meld/vcview.py       |   24 +++++++++++++++---------
 10 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/meld/vc/_vc.py b/meld/vc/_vc.py
index 27844d6..621a527 100644
--- a/meld/vc/_vc.py
+++ b/meld/vc/_vc.py
@@ -141,6 +141,10 @@ class Vc(object):
     def listdir_filter(self, entries):
         return [f for f in entries if f != self.VC_DIR]
 
+    # Determine if a directory is a valid git/svn/hg/cvs/etc repository
+    def valid_repo(self):
+        return True
+
     def listdir(self, start):
         if start=="": start="."
         cfiles = []
diff --git a/meld/vc/bzr.py b/meld/vc/bzr.py
index f6de97c..3ad7720 100644
--- a/meld/vc/bzr.py
+++ b/meld/vc/bzr.py
@@ -57,6 +57,11 @@ class Vc(_vc.CachedVc):
         return [self.CMD] + self.CMDARGS + ["revert"]
     def resolved_command(self):
         return [self.CMD] + self.CMDARGS + ["resolve"]
+    def valid_repo(self):
+        if _vc.call([self.CMD, "check"]):
+            return False
+        else:
+            return True
     def get_working_directory(self, workdir):
         return self.root
 
diff --git a/meld/vc/cvs.py b/meld/vc/cvs.py
index 4cde7be..14071e0 100644
--- a/meld/vc/cvs.py
+++ b/meld/vc/cvs.py
@@ -49,6 +49,11 @@ class Vc(_vc.Vc):
         return [self.CMD,"rm","-f"]
     def revert_command(self):
         return [self.CMD,"update","-C"]
+    def valid_repo(self):
+        if _vc.call([self.CMD, "version"]):
+            return False
+        else:
+            return True
 
     def _get_dirsandfiles(self, directory, dirs, files):
 
diff --git a/meld/vc/darcs.py b/meld/vc/darcs.py
index 6853dd0..6c1070c 100644
--- a/meld/vc/darcs.py
+++ b/meld/vc/darcs.py
@@ -70,6 +70,12 @@ class Vc(_vc.CachedVc):
         # untested
         return [self.CMD, "resolve"]
 
+    def valid_repo(self):
+        if _vc.call([self.CMD, "query", "tags"]):
+            return False
+        else:
+            return True
+
     def get_working_directory(self, workdir):
         return self.root
 
diff --git a/meld/vc/git.py b/meld/vc/git.py
index 4cc2cd4..3986db2 100644
--- a/meld/vc/git.py
+++ b/meld/vc/git.py
@@ -66,6 +66,11 @@ class Vc(_vc.CachedVc):
         return [self.CMD,"rm"]
     def revert_command(self):
         return [self.CMD,"checkout"]
+    def valid_repo(self):
+        if _vc.call([self.CMD, "describe"]):
+            return False
+        else:
+            return True
     def get_working_directory(self, workdir):
         if workdir.startswith("/"):
             return self.root
diff --git a/meld/vc/mercurial.py b/meld/vc/mercurial.py
index 0879636..77665cc 100644
--- a/meld/vc/mercurial.py
+++ b/meld/vc/mercurial.py
@@ -59,6 +59,11 @@ class Vc(_vc.Vc):
         return [self.CMD,"rm"]
     def revert_command(self):
         return [self.CMD,"revert"]
+    def valid_repo(self):
+        if _vc.call([self.CMD, "root"]):
+            return False
+        else:
+            return True
     def get_working_directory(self, workdir):
         return self.root
 
diff --git a/meld/vc/monotone.py b/meld/vc/monotone.py
index 69cde5f..7d504c8 100644
--- a/meld/vc/monotone.py
+++ b/meld/vc/monotone.py
@@ -143,6 +143,11 @@ class Vc(_vc.CachedVc):
         return [self.CMD,"revert"]
     def resolved_command(self):
         return [self.CMD,"resolved"]
+    def valid_repo(self):
+        if _vc.call([self.CMD, "list", "tags"]):
+            return False
+        else:
+            return True
     def get_working_directory(self, workdir):
         return self.root
 
diff --git a/meld/vc/svn.py b/meld/vc/svn.py
index 5091578..8b49ab1 100644
--- a/meld/vc/svn.py
+++ b/meld/vc/svn.py
@@ -63,6 +63,11 @@ class Vc(_vc.Vc):
         return [self.CMD,"revert"]
     def resolved_command(self):
         return [self.CMD,"resolved"]
+    def valid_repo(self):
+        if _vc.call([self.CMD, "info"]):
+            return False
+        else:
+            return True
 
     def _get_matches(self, directory):
         """return a list of tuples (file_path, status_code, revision)"""
diff --git a/meld/vc/tla.py b/meld/vc/tla.py
index f66fdac..82744a0 100644
--- a/meld/vc/tla.py
+++ b/meld/vc/tla.py
@@ -85,6 +85,12 @@ class Vc(_vc.CachedVc):
         # Will only work on later versions of tla
         return [self.CMD, "undo", "--"]
 
+    def valid_repo(self):
+        if _vc.call([self.CMD, "tree-version"]):
+            return False
+        else:
+            return True
+
     def get_working_directory(self, workdir):
         return self.root
 
diff --git a/meld/vcview.py b/meld/vcview.py
index 559e250..3d37331 100644
--- a/meld/vcview.py
+++ b/meld/vcview.py
@@ -233,17 +233,23 @@ class VcView(melddoc.MeldDoc, gnomeglade.Component):
         default_active = 0
         # Try to keep the same VC plugin active on refresh()
         for idx, avc in enumerate(vcs):
-            if (self.vc is not None and
-                self.vc.__class__ == avc.__class__):
-                default_active = idx
-
-            # See if the necessary version control command exists.  If not,
-            # make the version control choice non-selectable.
+            # See if the necessary version control command exists.  If so,
+            # make sure what we're diffing is a valid respository.  If either
+            # check fails don't let the user select the that version control
+            # tool and display a basic error message in the drop-down menu.
+            err_str = ""
             if vc._vc.call(["which", avc.CMD]):
-                self.combobox_vcs.get_model().append( \
-                    [avc.NAME + " (" + avc.CMD + " Not Installed)", avc, False])
+                err_str = " (" + avc.CMD + " Not Installed)"
+            elif avc.valid_repo():
+                if (self.vc is not None and
+                     self.vc.__class__ == avc.__class__):
+                     default_active = idx
             else:
-                self.combobox_vcs.get_model().append([avc.NAME, avc, True])
+                err_str = " (Invalid Repository)"
+
+            self.combobox_vcs.get_model().append( \
+                    [avc.NAME + err_str, avc, len(err_str) == 0])
+
         if gtk.pygtk_version >= (2, 12, 0):
             self.combobox_vcs.set_tooltip_text(tooltip_texts[len(vcs) == 1])
         self.combobox_vcs.set_sensitive(len(vcs) > 1)
-- 
1.7.1.13.gcfb88



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]