44# This module is part of GitPython and is released under
55# the BSD License: http://www.opensource.org/licenses/bsd-license.php
66
7- from exc import InvalidGitRepositoryError , NoSuchPathError
8- from cmd import Git
9- from objects import Actor
10- from refs import *
11- from index import IndexFile
12- from objects import *
13- from config import GitConfigParser
14- from remote import Remote
15-
16- from db import (
7+ from git .exc import InvalidGitRepositoryError , NoSuchPathError
8+ from git .cmd import Git
9+ from git .objects import Actor
10+ from git .refs import *
11+ from git .index import IndexFile
12+ from git .objects import *
13+ from git .config import GitConfigParser
14+ from git .remote import Remote
15+ from git .db import (
1716 GitCmdObjectDB ,
1817 GitDB
1918 )
2019
20+
2121from gitdb .util import (
2222 join ,
23- isdir ,
2423 isfile ,
25- join ,
2624 hex_to_bin
2725 )
26+
27+ from fun import (
28+ rev_parse ,
29+ is_git_dir ,
30+ touch
31+ )
32+
2833import os
2934import sys
3035import re
3136
3237
3338__all__ = ('Repo' , )
3439
35- def touch (filename ):
36- fp = open (filename , "a" )
37- fp .close ()
38-
39- def is_git_dir (d ):
40- """ This is taken from the git setup.c:is_git_directory
41- function."""
42-
43- if isdir (d ) and \
44- isdir (join (d , 'objects' )) and \
45- isdir (join (d , 'refs' )):
46- headref = join (d , 'HEAD' )
47- return isfile (headref ) or \
48- (os .path .islink (headref ) and
49- os .readlink (headref ).startswith ('refs' ))
50- return False
51-
5240
5341class Repo (object ):
5442 """Represents a git repository and allows you to query references,
@@ -70,6 +58,7 @@ class Repo(object):
7058 # precompiled regex
7159 re_whitespace = re .compile (r'\s+' )
7260 re_hexsha_only = re .compile ('^[0-9A-Fa-f]{40}$' )
61+ re_hexsha_shortened = re .compile ('^[0-9A-Fa-f]{4,40}$' )
7362 re_author_committer_start = re .compile (r'^(author|committer)' )
7463 re_tab_full_line = re .compile (r'^\t(.*)$' )
7564
@@ -109,7 +98,7 @@ def __init__(self, path=None, odbt = GitDB):
10998 self .git_dir = curpath
11099 self ._working_tree_dir = os .path .dirname (curpath )
111100 break
112- gitpath = os . path . join (curpath , '.git' )
101+ gitpath = join (curpath , '.git' )
113102 if is_git_dir (gitpath ):
114103 self .git_dir = gitpath
115104 self ._working_tree_dir = curpath
@@ -139,7 +128,7 @@ def __init__(self, path=None, odbt = GitDB):
139128 self .git = Git (self .working_dir )
140129
141130 # special handling, in special times
142- args = [os . path . join (self .git_dir , 'objects' )]
131+ args = [join (self .git_dir , 'objects' )]
143132 if issubclass (odbt , GitCmdObjectDB ):
144133 args .append (self .git )
145134 self .odb = odbt (* args )
@@ -160,11 +149,11 @@ def __repr__(self):
160149
161150 # Description property
162151 def _get_description (self ):
163- filename = os . path . join (self .git_dir , 'description' )
152+ filename = join (self .git_dir , 'description' )
164153 return file (filename ).read ().rstrip ()
165154
166155 def _set_description (self , descr ):
167- filename = os . path . join (self .git_dir , 'description' )
156+ filename = join (self .git_dir , 'description' )
168157 file (filename , 'w' ).write (descr + '\n ' )
169158
170159 description = property (_get_description , _set_description ,
@@ -334,11 +323,9 @@ def commit(self, rev=None):
334323 :param rev: revision specifier, see git-rev-parse for viable options.
335324 :return: ``git.Commit``"""
336325 if rev is None :
337- rev = self .active_branch
338-
339- c = Object .new (self , rev )
340- assert c .type == "commit" , "Revision %s did not point to a commit, but to %s" % (rev , c )
341- return c
326+ return self .active_branch .commit
327+ else :
328+ return self .rev_parse (str (rev )+ "^0" )
342329
343330 def iter_trees (self , * args , ** kwargs ):
344331 """:return: Iterator yielding Tree objects
@@ -359,14 +346,9 @@ def tree(self, rev=None):
359346 it cannot know about its path relative to the repository root and subsequent
360347 operations might have unexpected results."""
361348 if rev is None :
362- rev = self .active_branch
363-
364- c = Object .new (self , rev )
365- if c .type == "commit" :
366- return c .tree
367- elif c .type == "tree" :
368- return c
369- raise ValueError ( "Revision %s did not point to a treeish, but to %s" % (rev , c ))
349+ return self .active_branch .commit .tree
350+ else :
351+ return self .rev_parse (str (rev )+ "^{tree}" )
370352
371353 def iter_commits (self , rev = None , paths = '' , ** kwargs ):
372354 """A list of Commit objects representing the history of a given ref/commit
@@ -393,11 +375,11 @@ def iter_commits(self, rev=None, paths='', **kwargs):
393375 return Commit .iter_items (self , rev , paths , ** kwargs )
394376
395377 def _get_daemon_export (self ):
396- filename = os . path . join (self .git_dir , self .DAEMON_EXPORT_FILE )
378+ filename = join (self .git_dir , self .DAEMON_EXPORT_FILE )
397379 return os .path .exists (filename )
398380
399381 def _set_daemon_export (self , value ):
400- filename = os . path . join (self .git_dir , self .DAEMON_EXPORT_FILE )
382+ filename = join (self .git_dir , self .DAEMON_EXPORT_FILE )
401383 fileexists = os .path .exists (filename )
402384 if value and not fileexists :
403385 touch (filename )
@@ -413,7 +395,7 @@ def _get_alternates(self):
413395 """The list of alternates for this repo from which objects can be retrieved
414396
415397 :return: list of strings being pathnames of alternates"""
416- alternates_path = os . path . join (self .git_dir , 'objects' , 'info' , 'alternates' )
398+ alternates_path = join (self .git_dir , 'objects' , 'info' , 'alternates' )
417399
418400 if os .path .exists (alternates_path ):
419401 try :
@@ -436,9 +418,9 @@ def _set_alternates(self, alts):
436418 :note:
437419 The method does not check for the existance of the paths in alts
438420 as the caller is responsible."""
439- alternates_path = os . path . join (self .git_dir , 'objects' , 'info' , 'alternates' )
421+ alternates_path = join (self .git_dir , 'objects' , 'info' , 'alternates' )
440422 if not alts :
441- if os . path . isfile (alternates_path ):
423+ if isfile (alternates_path ):
442424 os .remove (alternates_path )
443425 else :
444426 try :
@@ -466,7 +448,7 @@ def is_dirty(self, index=True, working_tree=True, untracked_files=False):
466448 default_args = ('--abbrev=40' , '--full-index' , '--raw' )
467449 if index :
468450 # diff index against HEAD
469- if os . path . isfile (self .index .path ) and self .head .is_valid () and \
451+ if isfile (self .index .path ) and self .head .is_valid () and \
470452 len (self .git .diff ('HEAD' , '--cached' , * default_args )):
471453 return True
472454 # END index handling
@@ -674,7 +656,7 @@ def clone(self, path, **kwargs):
674656 # our git command could have a different working dir than our actual
675657 # environment, hence we prepend its working dir if required
676658 if not os .path .isabs (path ) and self .git .working_dir :
677- path = os . path . join (self .git ._working_dir , path )
659+ path = join (self .git ._working_dir , path )
678660 return Repo (os .path .abspath (path ), odbt = odbt )
679661
680662
@@ -693,11 +675,13 @@ def archive(self, ostream, treeish=None, prefix=None, **kwargs):
693675 if treeish is None :
694676 treeish = self .active_branch
695677 if prefix and 'prefix' not in kwargs :
696- kwargs ['prefix' ] = prefix
678+ kwargs ['prefix' ] = prefix
697679 kwargs ['output_stream' ] = ostream
698680
699681 self .git .archive (treeish , ** kwargs )
700682 return self
701-
683+
684+ rev_parse = rev_parse
685+
702686 def __repr__ (self ):
703687 return '<git.Repo "%s">' % self .git_dir
0 commit comments