@@ -15,40 +15,59 @@ class Git(MethodMissingMixin):
1515 def __init__ (self , git_dir = None ):
1616 super (Git , self ).__init__ ()
1717 if git_dir :
18- self .find_git_dir (git_dir )
18+ self ._location = os . path . abspath (git_dir )
1919 else :
20- self .find_git_dir (os .getcwd ())
21-
22- def find_git_dir (self , path ):
23- """Find the best value for self.git_dir.
24- For bare repositories, this is the path to the bare repository.
25- For repositories with work trees, this is the work tree path.
26-
27- When barerepo.git is passed in, self.git_dir = barerepo.git
28- When worktree/.git is passed in, self.git_dir = worktree
29- When worktree is passed in, self.git_dir = worktree
30- """
31-
32- path = os .path .abspath (path )
33- self .git_dir = path
34-
35- cdup = self .execute (["git" , "rev-parse" , "--show-cdup" ])
36- if cdup :
37- path = os .path .abspath (os .path .join (self .git_dir , cdup ))
38- else :
39- is_bare_repository = \
40- self .rev_parse (is_bare_repository = True ) == "true"
41- is_inside_git_dir = \
42- self .rev_parse (is_inside_git_dir = True ) == "true"
43-
44- if not is_bare_repository and is_inside_git_dir :
45- path = os .path .dirname (self .git_dir )
46-
47- self .git_dir = path
20+ self ._location = os .getcwd ()
21+ self .refresh ()
22+
23+ def refresh (self ):
24+ self ._git_dir = None
25+ self ._is_in_repo = not not self .get_git_dir ()
26+ self ._work_tree = None
27+
28+ def _is_git_dir (self , d ):
29+ """ This is taken from the git setup.c:is_git_directory
30+ function."""
31+
32+ if os .path .isdir (d ) and \
33+ os .path .isdir (os .path .join (d , 'objects' )) and \
34+ os .path .isdir (os .path .join (d , 'refs' )):
35+ headref = os .path .join (d , 'HEAD' )
36+ return os .path .isfile (headref ) or \
37+ (os .path .islink (headref ) and
38+ os .readlink (headref ).startswith ('refs' ))
39+ return False
40+
41+ def get_git_dir (self ):
42+ if not self ._git_dir :
43+ self ._git_dir = os .getenv ('GIT_DIR' )
44+ if self ._git_dir and self ._is_git_dir (self ._git_dir ):
45+ return self ._git_dir
46+ curpath = self ._location
47+ while curpath :
48+ if self ._is_git_dir (curpath ):
49+ self ._git_dir = curpath
50+ break
51+ gitpath = os .path .join (curpath , '.git' )
52+ if self ._is_git_dir (gitpath ):
53+ self ._git_dir = gitpath
54+ break
55+ curpath , dummy = os .path .split (curpath )
56+ if not dummy :
57+ break
58+ return self ._git_dir
59+
60+ def get_work_tree (self ):
61+ if not self ._work_tree :
62+ self ._work_tree = os .getenv ('GIT_WORK_TREE' )
63+ if not self ._work_tree or not os .path .isdir (self ._work_tree ):
64+ self ._work_tree = os .path .abspath (
65+ os .path .join (self ._git_dir , '..' ))
66+ return self ._work_tree
4867
4968 @property
5069 def get_dir (self ):
51- return self .git_dir
70+ return self ._git_dir
5271
5372 def execute (self , command ,
5473 istream = None ,
@@ -96,7 +115,7 @@ def execute(self, command,
96115
97116 # Start the process
98117 proc = subprocess .Popen (command ,
99- cwd = self .git_dir ,
118+ cwd = self ._git_dir ,
100119 stdin = istream ,
101120 stderr = stderr ,
102121 stdout = subprocess .PIPE
0 commit comments