| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,6 +57,7 @@ GitCommand | |||
| 57 | 57 | * git.subcommand call scheme now prunes out None from the argument list, allowing | |
| 58 | 58 | to be called more confortably as None can never be a valid to the git command | |
| 59 | 59 | if converted to a string. | |
| 60 | + * Renamed 'git_dir' attribute to 'working_dir' which is exactly how it is used | ||
| 60 | 61 | ||
| 61 | 62 | Commit | |
| 62 | 63 | ------ | |
@@ -135,6 +136,11 @@ Repo | |||
| 135 | 136 | - 'config_reader' method | |
| 136 | 137 | - 'config_writer' method | |
| 137 | 138 | - 'bare' property, previously it was a simple attribute that could be written | |
| 139 | + * Renamed the following attributes | ||
| 140 | + - 'path' is now 'git_dir' | ||
| 141 | + - 'wd' is now 'working_dir' | ||
| 142 | + * Added attribute | ||
| 143 | + - 'working_tree_dir' which may be None in case of bare repositories | ||
| 138 | 144 | ||
| 139 | 145 | Remote | |
| 140 | 146 | ------ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -43,6 +43,8 @@ class Git(object): | |||
| 43 | 43 | of the command to stdout. | |
| 44 | 44 | Set its value to 'full' to see details about the returned values. | |
| 45 | 45 | """ | |
| 46 | + __slots__ = ("_working_dir", "cat_file_all", "cat_file_header") | ||
| 47 | + | ||
| 46 | 48 | class AutoInterrupt(object): | |
| 47 | 49 | """ | |
| 48 | 50 | Kill/Interrupt the stored process instance once this instance goes out of scope. It is | |
@@ -92,18 +94,18 @@ def wait(self): | |||
| 92 | 94 | ||
| 93 | 95 | ||
| 94 | 96 | ||
| 95 | - def __init__(self, git_dir=None): | ||
| 97 | + def __init__(self, working_dir=None): | ||
| 96 | 98 | """ | |
| 97 | 99 | Initialize this instance with: | |
| 98 | 100 | ||
| 99 | - ``git_dir`` | ||
| 101 | + ``working_dir`` | ||
| 100 | 102 | Git directory we should work in. If None, we always work in the current | |
| 101 | 103 | directory as returned by os.getcwd(). | |
| 102 | 104 | It is meant to be the working tree directory if available, or the | |
| 103 | 105 | .git directory in case of bare repositories. | |
| 104 | 106 | """ | |
| 105 | 107 | super(Git, self).__init__() | |
| 106 | - self.git_dir = git_dir | ||
| 108 | + self._working_dir = working_dir | ||
| 107 | 109 | ||
| 108 | 110 | # cached command slots | |
| 109 | 111 | self.cat_file_header = None | |
@@ -121,12 +123,12 @@ def __getattr__(self, name): | |||
| 121 | 123 | return lambda *args, **kwargs: self._call_process(name, *args, **kwargs) | |
| 122 | 124 | ||
| 123 | 125 | @property | |
| 124 | - def get_dir(self): | ||
| 126 | + def working_dir(self): | ||
| 125 | 127 | """ | |
| 126 | 128 | Returns | |
| 127 | 129 | Git directory we are working on | |
| 128 | 130 | """ | |
| 129 | - return self.git_dir | ||
| 131 | + return self._working_dir | ||
| 130 | 132 | ||
| 131 | 133 | def execute(self, command, | |
| 132 | 134 | istream=None, | |
@@ -150,8 +152,8 @@ def execute(self, command, | |||
| 150 | 152 | ||
| 151 | 153 | ``with_keep_cwd`` | |
| 152 | 154 | Whether to use the current working directory from os.getcwd(). | |
| 153 | - GitPython uses get_work_tree() as its working directory by | ||
| 154 | - default and get_git_dir() for bare repositories. | ||
| 155 | + The cmd otherwise uses its own working_dir that it has been initialized | ||
| 156 | + with if possible. | ||
| 155 | 157 | ||
| 156 | 158 | ``with_extended_output`` | |
| 157 | 159 | Whether to return a (status, stdout, stderr) tuple. | |
@@ -198,10 +200,10 @@ def execute(self, command, | |||
| 198 | 200 | print ' '.join(command) | |
| 199 | 201 | ||
| 200 | 202 | # Allow the user to have the command executed in their working dir. | |
| 201 | - if with_keep_cwd or self.git_dir is None: | ||
| 203 | + if with_keep_cwd or self._working_dir is None: | ||
| 202 | 204 | cwd = os.getcwd() | |
| 203 | 205 | else: | |
| 204 | - cwd=self.git_dir | ||
| 206 | + cwd=self._working_dir | ||
| 205 | 207 | ||
| 206 | 208 | # Start the process | |
| 207 | 209 | proc = subprocess.Popen(command, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -325,7 +325,7 @@ def _set_cache_(self, attr): | |||
| 325 | 325 | super(IndexFile, self)._set_cache_(attr) | |
| 326 | 326 | ||
| 327 | 327 | def _index_path(self): | |
| 328 | - return join_path_native(self.repo.path, "index") | ||
| 328 | + return join_path_native(self.repo.git_dir, "index") | ||
| 329 | 329 | ||
| 330 | 330 | ||
| 331 | 331 | @property | |
@@ -539,15 +539,15 @@ def from_tree(cls, repo, *treeish, **kwargs): | |||
| 539 | 539 | ||
| 540 | 540 | # tmp file created in git home directory to be sure renaming | |
| 541 | 541 | # works - /tmp/ dirs could be on another device | |
| 542 | - tmp_index = tempfile.mktemp('','',repo.path) | ||
| 542 | + tmp_index = tempfile.mktemp('','',repo.git_dir) | ||
| 543 | 543 | arg_list.append("--index-output=%s" % tmp_index) | |
| 544 | 544 | arg_list.extend(treeish) | |
| 545 | 545 | ||
| 546 | 546 | # move current index out of the way - otherwise the merge may fail | |
| 547 | 547 | # as it considers existing entries. moving it essentially clears the index. | |
| 548 | 548 | # Unfortunately there is no 'soft' way to do it. | |
| 549 | 549 | # The _TemporaryFileSwap assure the original file get put back | |
| 550 | - index_handler = _TemporaryFileSwap(join_path_native(repo.path, 'index')) | ||
| 550 | + index_handler = _TemporaryFileSwap(join_path_native(repo.git_dir, 'index')) | ||
| 551 | 551 | try: | |
| 552 | 552 | repo.git.read_tree(*arg_list, **kwargs) | |
| 553 | 553 | index = cls(repo, tmp_index) | |
@@ -579,7 +579,7 @@ def _index_mode_to_tree_index_mode(cls, index_mode): | |||
| 579 | 579 | return ret | |
| 580 | 580 | ||
| 581 | 581 | ||
| 582 | - # UTILITIES | ||
| 582 | + # UTILITIES | ||
| 583 | 583 | def _iter_expand_paths(self, paths): | |
| 584 | 584 | """Expand the directories in list of paths to the corresponding paths accordingly, | |
| 585 | 585 | ||
@@ -588,7 +588,7 @@ def _iter_expand_paths(self, paths): | |||
| 588 | 588 | times - we respect that and do not prune""" | |
| 589 | 589 | def raise_exc(e): | |
| 590 | 590 | raise e | |
| 591 | - r = self.repo.git.git_dir | ||
| 591 | + r = self.repo.working_tree_dir | ||
| 592 | 592 | rs = r + '/' | |
| 593 | 593 | for path in paths: | |
| 594 | 594 | abs_path = path | |
@@ -798,9 +798,9 @@ def _to_relative_path(self, path): | |||
| 798 | 798 | """ | |
| 799 | 799 | if not os.path.isabs(path): | |
| 800 | 800 | return path | |
| 801 | - relative_path = path.replace(self.repo.git.git_dir+os.sep, "") | ||
| 801 | + relative_path = path.replace(self.repo.working_tree_dir+os.sep, "") | ||
| 802 | 802 | if relative_path == path: | |
| 803 | - raise ValueError("Absolute path %r is not in git repository at %r" % (path,self.repo.git.git_dir)) | ||
| 803 | + raise ValueError("Absolute path %r is not in git repository at %r" % (path,self.repo.working_tree_dir)) | ||
| 804 | 804 | return relative_path | |
| 805 | 805 | ||
| 806 | 806 | def _preprocess_add_items(self, items): | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -223,5 +223,5 @@ def abspath(self): | |||
| 223 | 223 | ||
| 224 | 224 | The returned path will be native to the system and contains '\' on windows. | |
| 225 | 225 | """ | |
| 226 | - return join_path_native(self.repo.git.git_dir, self.path) | ||
| 226 | + return join_path_native(self.repo.working_tree_dir, self.path) | ||
| 227 | 227 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -52,15 +52,15 @@ def name(self): | |||
| 52 | 52 | return self.path | |
| 53 | 53 | ||
| 54 | 54 | def _get_path(self): | |
| 55 | - return join_path_native(self.repo.path, self.path) | ||
| 55 | + return join_path_native(self.repo.git_dir, self.path) | ||
| 56 | 56 | ||
| 57 | 57 | @classmethod | |
| 58 | 58 | def _iter_packed_refs(cls, repo): | |
| 59 | 59 | """Returns an iterator yielding pairs of sha1/path pairs for the corresponding | |
| 60 | 60 | refs. | |
| 61 | 61 | NOTE: The packed refs file will be kept open as long as we iterate""" | |
| 62 | 62 | try: | |
| 63 | - fp = open(os.path.join(repo.path, 'packed-refs'), 'r') | ||
| 63 | + fp = open(os.path.join(repo.git_dir, 'packed-refs'), 'r') | ||
| 64 | 64 | for line in fp: | |
| 65 | 65 | line = line.strip() | |
| 66 | 66 | if not line: | |
@@ -258,7 +258,7 @@ def delete(cls, repo, path): | |||
| 258 | 258 | Alternatively the symbolic reference to be deleted | |
| 259 | 259 | """ | |
| 260 | 260 | full_ref_path = cls._to_full_path(repo, path) | |
| 261 | - abs_path = os.path.join(repo.path, full_ref_path) | ||
| 261 | + abs_path = os.path.join(repo.git_dir, full_ref_path) | ||
| 262 | 262 | if os.path.exists(abs_path): | |
| 263 | 263 | os.remove(abs_path) | |
| 264 | 264 | ||
@@ -271,7 +271,7 @@ def _create(cls, repo, path, resolve, reference, force): | |||
| 271 | 271 | instead""" | |
| 272 | 272 | full_ref_path = cls._to_full_path(repo, path) | |
| 273 | 273 | ||
| 274 | - abs_ref_path = os.path.join(repo.path, full_ref_path) | ||
| 274 | + abs_ref_path = os.path.join(repo.git_dir, full_ref_path) | ||
| 275 | 275 | if not force and os.path.isfile(abs_ref_path): | |
| 276 | 276 | raise OSError("Reference at %s does already exist" % full_ref_path) | |
| 277 | 277 | ||
@@ -401,10 +401,10 @@ def iter_items(cls, repo, common_path = None, **kwargs): | |||
| 401 | 401 | ||
| 402 | 402 | # walk loose refs | |
| 403 | 403 | # Currently we do not follow links | |
| 404 | - for root, dirs, files in os.walk(join_path_native(repo.path, common_path)): | ||
| 404 | + for root, dirs, files in os.walk(join_path_native(repo.git_dir, common_path)): | ||
| 405 | 405 | for f in files: | |
| 406 | 406 | abs_path = to_native_path_linux(join_path(root, f)) | |
| 407 | - rela_paths.add(abs_path.replace(to_native_path_linux(repo.path) + '/', "")) | ||
| 407 | + rela_paths.add(abs_path.replace(to_native_path_linux(repo.git_dir) + '/', "")) | ||
| 408 | 408 | # END for each file in root directory | |
| 409 | 409 | # END for each directory to walk | |
| 410 | 410 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -575,7 +575,7 @@ def _get_fetch_info_from_stderr(self, stderr): | |||
| 575 | 575 | err_info = stderr.splitlines()[1:] | |
| 576 | 576 | ||
| 577 | 577 | # read head information | |
| 578 | - fp = open(os.path.join(self.repo.path, 'FETCH_HEAD'),'r') | ||
| 578 | + fp = open(os.path.join(self.repo.git_dir, 'FETCH_HEAD'),'r') | ||
| 579 | 579 | fetch_head_info = fp.readlines() | |
| 580 | 580 | fp.close() | |
| 581 | 581 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -362,3 +362,18 @@ def iter_items(cls, repo, *args, **kwargs): | |||
| 362 | 362 | """ | |
| 363 | 363 | raise NotImplementedError("To be implemented by Subclass") | |
| 364 | 364 | ||
| 365 | + def needs_working_tree(func): | ||
| 366 | + """ | ||
| 367 | + Decorator assuring the wrapped method may only run if the repository has a | ||
| 368 | + working tree, hence it is not bare. | ||
| 369 | + """ | ||
| 370 | + def check_default_index(self, *args, **kwargs): | ||
| 371 | + if self.repo.working_tree_dir is None: | ||
| 372 | + raise AssertionError( "Cannot call %r bare git repositories" % func.__name__ ) | ||
| 373 | + return func(self, *args, **kwargs) | ||
| 374 | + # END wrpaper method | ||
| 375 | + | ||
| 376 | + check_default_index.__name__ = func.__name__ | ||
| 377 | + return check_default_index | ||
| 378 | + | ||
| 379 | + | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments