From 6a07e8aab7367e54a0232255af534fba1ff1d2ac Mon Sep 17 00:00:00 2001 From: nixon Date: Thu, 2 Jun 2011 19:47:42 -0500 Subject: [PATCH] better repository directory detection Fix git-goggles to work from git sub-directories instead of just the top level directory. Add a method to Repository that checks that the current directory is actually a git repository as well as being the git repository that was used in initialization. --- bin/git-goggles | 3 +- gitgoggles/git.py | 9 ++++- gitgoggles/tests/__init__.py | 0 gitgoggles/tests/test_in_repo.py | 61 ++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 gitgoggles/tests/__init__.py create mode 100644 gitgoggles/tests/test_in_repo.py diff --git a/bin/git-goggles b/bin/git-goggles index 9d496f7..47d3a2f 100755 --- a/bin/git-goggles +++ b/bin/git-goggles @@ -5,9 +5,10 @@ import os from gitgoggles.codereview import get_status, complete_review, start_review, update_branches from gitgoggles.progress import enable_progress +from gitgoggles.git import Repository def handle_command(): - if not os.path.exists('.git'): + if not Repository().in_repo(): print 'Not within a git repository.' sys.exit(1) diff --git a/gitgoggles/git.py b/gitgoggles/git.py index 877e08b..21dfa5c 100644 --- a/gitgoggles/git.py +++ b/gitgoggles/git.py @@ -147,7 +147,7 @@ class Tag(Ref): class Repository(object): def __init__(self, path=None): - self.path = os.path.abspath(path or os.path.curdir) + self.path = os.path.realpath(path or os.path.curdir) # Hack, make configurable self.master = 'master' master_sha = self.shell('git', 'log', '-1', '--pretty=format:%H', self.master).split @@ -202,6 +202,13 @@ def configs(self): return dict([ x.partition('=')[0::2] for x in self.shell('git', 'config', '--list').split ]) configs = property(memoize(configs)) + def in_repo(self): + """Is the current directory in a git repo and is it our repo?""" + rc = self.shell('git', 'rev-parse', '--git-dir').returncode + if rc == 0 and os.path.realpath(os.getcwd()).startswith(self.path): + return True + return False + def fetch(self): log.info('Fetching updates.') self.shell('git', 'remote', 'update', '--prune') diff --git a/gitgoggles/tests/__init__.py b/gitgoggles/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gitgoggles/tests/test_in_repo.py b/gitgoggles/tests/test_in_repo.py new file mode 100644 index 0000000..43b78ea --- /dev/null +++ b/gitgoggles/tests/test_in_repo.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python + +import unittest +import os +import tempfile +import shutil + +from ..git import Repository + + +class TestInRepo(unittest.TestCase): + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + os.chdir(self.tmpdir) + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + def test_in_repo_true_top(self): + """test that in_repo() returns True when in a git repo""" + os.chdir(self.tmpdir) + repo = Repository(self.tmpdir) + repo.shell("git", "init") + + self.assertTrue(repo.in_repo()) + + def test_in_repo_true_subdir(self): + """test that in_repo() returns True when in a git repo subdir""" + os.chdir(self.tmpdir) + repo = Repository(self.tmpdir) + repo.shell("git", "init") + + subdir = os.path.join(self.tmpdir, "subdir") + os.mkdir(subdir) + os.chdir(subdir) + + self.assertTrue(repo.in_repo()) + + def test_in_repo_false_another_repo(self): + """ + test that in_repo() returns False when in a git repo that isnt + ours + """ + repo1_dir = os.path.join(self.tmpdir, "repo1") + os.mkdir(repo1_dir) + repo2_dir = os.path.join(self.tmpdir, "repo2") + os.mkdir(repo2_dir) + + os.chdir(repo1_dir) + repo1 = Repository(repo1_dir) + repo1.shell("git", "init") + + os.chdir(repo2_dir) + repo2 = Repository(repo2_dir) + repo2.shell("git", "init") + + self.assertFalse(repo1.in_repo()) + + def test_in_repo_false(self): + """test that in_repo() returns False when not in a git repo""" + self.assertFalse(Repository(self.tmpdir).in_repo())