@@ -41,9 +41,19 @@ class Repo(object):
41
41
Represents a git repository and allows you to query references,
42
42
gather commit information, generate diffs, create and clone repositories query
43
43
the log.
44
+
45
+ The following attributes are worth using:
46
+
47
+ 'working_dir' is the working directory of the git command, wich is the working tree
48
+ directory if available or the .git directory in case of bare repositories
49
+
50
+ 'working_tree_dir' is the working tree directory, but will raise AssertionError
51
+ if we are a bare repository.
52
+
53
+ 'git_dir' is the .git repository directoy, which is always set.
44
54
"""
45
55
DAEMON_EXPORT_FILE = 'git-daemon-export-ok'
46
- __slots__ = ( "wd " , "path " , "_bare" , "git" )
56
+ __slots__ = ( "working_dir " , "_working_tree_dir" , "git_dir " , "_bare" , "git" )
47
57
48
58
# precompiled regex
49
59
re_whitespace = re .compile (r'\s+' )
@@ -81,26 +91,28 @@ def __init__(self, path=None):
81
91
if not os .path .exists (epath ):
82
92
raise NoSuchPathError (epath )
83
93
84
- self .path = None
94
+ self .working_dir = None
95
+ self ._working_tree_dir = None
96
+ self .git_dir = None
85
97
curpath = epath
86
98
87
99
# walk up the path to find the .git dir
88
100
while curpath :
89
101
if is_git_dir (curpath ):
90
- self .path = curpath
91
- self .wd = os .path .dirname (curpath )
102
+ self .git_dir = curpath
103
+ self ._working_tree_dir = os .path .dirname (curpath )
92
104
break
93
105
gitpath = os .path .join (curpath , '.git' )
94
106
if is_git_dir (gitpath ):
95
- self .path = gitpath
96
- self .wd = curpath
107
+ self .git_dir = gitpath
108
+ self ._working_tree_dir = curpath
97
109
break
98
110
curpath , dummy = os .path .split (curpath )
99
111
if not dummy :
100
112
break
101
113
# END while curpath
102
114
103
- if self .path is None :
115
+ if self .git_dir is None :
104
116
raise InvalidGitRepositoryError (epath )
105
117
106
118
self ._bare = False
@@ -113,24 +125,38 @@ def __init__(self, path=None):
113
125
# adjust the wd in case we are actually bare - we didn't know that
114
126
# in the first place
115
127
if self ._bare :
116
- self .wd = self .path
117
-
118
- self .git = Git (self .wd )
128
+ self ._working_tree_dir = None
129
+ # END working dir handling
130
+
131
+ self .working_dir = self ._working_tree_dir or self .git_dir
132
+ self .git = Git (self .working_dir )
119
133
120
134
# Description property
121
135
def _get_description (self ):
122
- filename = os .path .join (self .path , 'description' )
136
+ filename = os .path .join (self .git_dir , 'description' )
123
137
return file (filename ).read ().rstrip ()
124
138
125
139
def _set_description (self , descr ):
126
- filename = os .path .join (self .path , 'description' )
140
+ filename = os .path .join (self .git_dir , 'description' )
127
141
file (filename , 'w' ).write (descr + '\n ' )
128
142
129
143
description = property (_get_description , _set_description ,
130
144
doc = "the project's description" )
131
145
del _get_description
132
146
del _set_description
133
147
148
+ @property
149
+ def working_tree_dir (self ):
150
+ """
151
+ Returns
152
+ The working tree directory of our git repository
153
+
154
+ Raises AssertionError
155
+ If we are a bare repository
156
+ """
157
+ if self ._working_tree_dir is None :
158
+ raise AssertionError ( "Repository at %r is bare and does not have a working tree directory" % self .git_dir )
159
+ return self ._working_tree_dir
134
160
135
161
@property
136
162
def bare (self ):
@@ -286,7 +312,7 @@ def _get_config_path(self, config_level ):
286
312
elif config_level == "global" :
287
313
return os .path .expanduser ("~/.gitconfig" )
288
314
elif config_level == "repository" :
289
- return "%s/config" % self .path
315
+ return "%s/config" % self .git_dir
290
316
291
317
raise ValueError ( "Invalid configuration level: %r" % config_level )
292
318
@@ -413,11 +439,11 @@ def iter_commits(self, rev=None, paths='', **kwargs):
413
439
return Commit .iter_items (self , rev , paths , ** kwargs )
414
440
415
441
def _get_daemon_export (self ):
416
- filename = os .path .join (self .path , self .DAEMON_EXPORT_FILE )
442
+ filename = os .path .join (self .git_dir , self .DAEMON_EXPORT_FILE )
417
443
return os .path .exists (filename )
418
444
419
445
def _set_daemon_export (self , value ):
420
- filename = os .path .join (self .path , self .DAEMON_EXPORT_FILE )
446
+ filename = os .path .join (self .git_dir , self .DAEMON_EXPORT_FILE )
421
447
fileexists = os .path .exists (filename )
422
448
if value and not fileexists :
423
449
touch (filename )
@@ -436,7 +462,7 @@ def _get_alternates(self):
436
462
Returns
437
463
list of strings being pathnames of alternates
438
464
"""
439
- alternates_path = os .path .join (self .path , 'objects' , 'info' , 'alternates' )
465
+ alternates_path = os .path .join (self .git_dir , 'objects' , 'info' , 'alternates' )
440
466
441
467
if os .path .exists (alternates_path ):
442
468
try :
@@ -466,7 +492,7 @@ def _set_alternates(self, alts):
466
492
Returns
467
493
None
468
494
"""
469
- alternates_path = os .path .join (self .path , 'objects' , 'info' , 'alternates' )
495
+ alternates_path = os .path .join (self .git_dir , 'objects' , 'info' , 'alternates' )
470
496
if not alts :
471
497
if os .path .isfile (alternates_path ):
472
498
os .remove (alternates_path )
@@ -706,7 +732,7 @@ def clone(self, path, **kwargs):
706
732
# END windows handling
707
733
708
734
try :
709
- self .git .clone (self .path , path , ** kwargs )
735
+ self .git .clone (self .git_dir , path , ** kwargs )
710
736
finally :
711
737
if prev_cwd is not None :
712
738
os .chdir (prev_cwd )
@@ -754,4 +780,4 @@ def archive(self, ostream, treeish=None, prefix=None, **kwargs):
754
780
return self
755
781
756
782
def __repr__ (self ):
757
- return '<git.Repo "%s">' % self .path
783
+ return '<git.Repo "%s">' % self .git_dir
0 commit comments