views.main: Use gitcmds.log_helper()
[git-cola.git] / cola / gitcmd.py
blobf48cc86b3d9b62a4284565d0278d5d3771a1439a
1 import os
3 from cola import git
6 # Provides access to a global GitCola instance
7 _instance = None
8 def instance():
9 """Return the GitCola singleton"""
10 global _instance
11 if _instance:
12 return _instance
13 _instance = GitCola()
14 return _instance
17 class GitCola(git.Git):
18 """
19 Subclass git.Git to provide custom behaviors.
21 GitPython throws exceptions by default.
22 We suppress exceptions in favor of return values.
24 """
25 def __init__(self):
26 git.Git.__init__(self)
27 self.load_worktree(os.getcwd())
29 def load_worktree(self, path):
30 self._git_dir = path
31 self._worktree = None
32 self.worktree()
34 def worktree(self):
35 if self._worktree:
36 return self._worktree
37 self.git_dir()
38 if self._git_dir:
39 curdir = self._git_dir
40 else:
41 curdir = os.getcwd()
43 if self._is_git_dir(os.path.join(curdir, '.git')):
44 return curdir
46 # Handle bare repositories
47 if (len(os.path.basename(curdir)) > 4
48 and curdir.endswith('.git')):
49 return curdir
50 if 'GIT_WORK_TREE' in os.environ:
51 self._worktree = os.getenv('GIT_WORK_TREE')
52 if not self._worktree or not os.path.isdir(self._worktree):
53 if self._git_dir:
54 gitparent = os.path.join(os.path.abspath(self._git_dir), '..')
55 self._worktree = os.path.abspath(gitparent)
56 self.set_cwd(self._worktree)
57 return self._worktree
59 def is_valid(self):
60 return self._git_dir and self._is_git_dir(self._git_dir)
62 def git_dir(self):
63 if self.is_valid():
64 return self._git_dir
65 if 'GIT_DIR' in os.environ:
66 self._git_dir = os.getenv('GIT_DIR')
67 if self._git_dir:
68 curpath = os.path.abspath(self._git_dir)
69 else:
70 curpath = os.path.abspath(os.getcwd())
71 # Search for a .git directory
72 while curpath:
73 if self._is_git_dir(curpath):
74 self._git_dir = curpath
75 break
76 gitpath = os.path.join(curpath, '.git')
77 if self._is_git_dir(gitpath):
78 self._git_dir = gitpath
79 break
80 curpath, dummy = os.path.split(curpath)
81 if not dummy:
82 break
83 return self._git_dir
85 def _is_git_dir(self, d):
86 """From git's setup.c:is_git_directory()."""
87 if (os.path.isdir(d)
88 and os.path.isdir(os.path.join(d, 'objects'))
89 and os.path.isdir(os.path.join(d, 'refs'))):
90 headref = os.path.join(d, 'HEAD')
91 return (os.path.isfile(headref)
92 or (os.path.islink(headref)
93 and os.readlink(headref).startswith('refs')))
94 return False