models.gitrepo: Use a custom event type for GitRepoInfoEvents
[git-cola.git] / cola / gitcola.py
blob92cd3b322173dd771682664cfb13842f7740127e
1 import os
3 from cola import git
6 class GitCola(git.Git):
7 """
8 Subclass git.Git to provide custom behaviors.
10 GitPython throws exceptions by default.
11 We suppress exceptions in favor of return values.
12 """
13 def __init__(self):
14 git.Git.__init__(self)
15 self.load_worktree(os.getcwd())
17 def load_worktree(self, path):
18 self._git_dir = path
19 self._worktree = None
20 self.worktree()
22 def worktree(self):
23 if self._worktree:
24 return self._worktree
25 self.git_dir()
26 if self._git_dir:
27 curdir = self._git_dir
28 else:
29 curdir = os.getcwd()
31 if self._is_git_dir(os.path.join(curdir, '.git')):
32 return curdir
34 # Handle bare repositories
35 if (len(os.path.basename(curdir)) > 4
36 and curdir.endswith('.git')):
37 return curdir
38 if 'GIT_WORK_TREE' in os.environ:
39 self._worktree = os.getenv('GIT_WORK_TREE')
40 if not self._worktree or not os.path.isdir(self._worktree):
41 if self._git_dir:
42 gitparent = os.path.join(os.path.abspath(self._git_dir), '..')
43 self._worktree = os.path.abspath(gitparent)
44 self.set_cwd(self._worktree)
45 return self._worktree
47 def is_valid(self):
48 return self._git_dir and self._is_git_dir(self._git_dir)
50 def git_dir(self):
51 if self.is_valid():
52 return self._git_dir
53 if 'GIT_DIR' in os.environ:
54 self._git_dir = os.getenv('GIT_DIR')
55 if self._git_dir:
56 curpath = os.path.abspath(self._git_dir)
57 else:
58 curpath = os.path.abspath(os.getcwd())
59 # Search for a .git directory
60 while curpath:
61 if self._is_git_dir(curpath):
62 self._git_dir = curpath
63 break
64 gitpath = os.path.join(curpath, '.git')
65 if self._is_git_dir(gitpath):
66 self._git_dir = gitpath
67 break
68 curpath, dummy = os.path.split(curpath)
69 if not dummy:
70 break
71 return self._git_dir
73 def _is_git_dir(self, d):
74 """ This is taken from the git setup.c:is_git_directory
75 function."""
76 if (os.path.isdir(d)
77 and os.path.isdir(os.path.join(d, 'objects'))
78 and os.path.isdir(os.path.join(d, 'refs'))):
79 headref = os.path.join(d, 'HEAD')
80 return (os.path.isfile(headref)
81 or (os.path.islink(headref)
82 and os.readlink(headref).startswith('refs')))
83 return False