views.actions: Fix action dialog when revprompt is true and argprompt is false
[git-cola.git] / cola / gitcmd.py
blobc22155414face5526868d3490debe841e8e4f6bf
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 not _instance:
12 _instance = GitCola()
13 return _instance
16 class GitCola(git.Git):
17 """
18 Subclass git.Git to provide search-for-git-dir
20 """
21 def __init__(self):
22 git.Git.__init__(self)
23 self.load_worktree(os.getcwd())
25 def load_worktree(self, path):
26 self._git_dir = path
27 self._worktree = None
28 self.worktree()
30 def worktree(self):
31 if self._worktree:
32 return self._worktree
33 self.git_dir()
34 if self._git_dir:
35 curdir = self._git_dir
36 else:
37 curdir = os.getcwd()
39 if self._is_git_dir(os.path.join(curdir, '.git')):
40 return curdir
42 # Handle bare repositories
43 if (len(os.path.basename(curdir)) > 4
44 and curdir.endswith('.git')):
45 return curdir
46 if 'GIT_WORK_TREE' in os.environ:
47 self._worktree = os.getenv('GIT_WORK_TREE')
48 if not self._worktree or not os.path.isdir(self._worktree):
49 if self._git_dir:
50 gitparent = os.path.join(os.path.abspath(self._git_dir), '..')
51 self._worktree = os.path.abspath(gitparent)
52 self.set_cwd(self._worktree)
53 return self._worktree
55 def is_valid(self):
56 return self._git_dir and self._is_git_dir(self._git_dir)
58 def git_path(self, *paths):
59 return os.path.join(self.git_dir(), *paths)
61 def git_dir(self):
62 if self.is_valid():
63 return self._git_dir
64 if 'GIT_DIR' in os.environ:
65 self._git_dir = os.getenv('GIT_DIR')
66 if self._git_dir:
67 curpath = os.path.abspath(self._git_dir)
68 else:
69 curpath = os.path.abspath(os.getcwd())
70 # Search for a .git directory
71 while curpath:
72 if self._is_git_dir(curpath):
73 self._git_dir = curpath
74 break
75 gitpath = os.path.join(curpath, '.git')
76 if self._is_git_dir(gitpath):
77 self._git_dir = gitpath
78 break
79 curpath, dummy = os.path.split(curpath)
80 if not dummy:
81 break
82 return self._git_dir
84 def _is_git_dir(self, d):
85 """From git's setup.c:is_git_directory()."""
86 if (os.path.isdir(d)
87 and os.path.isdir(os.path.join(d, 'objects'))
88 and os.path.isdir(os.path.join(d, 'refs'))):
89 headref = os.path.join(d, 'HEAD')
90 return (os.path.isfile(headref)
91 or (os.path.islink(headref)
92 and os.readlink(headref).startswith('refs')))
93 return False