| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,11 @@ General | |||
| 23 | 23 | * All dates, like authored_date and committer_date, are stored as seconds since epoc | |
| 24 | 24 | to consume less memory - they can be converted using time.gmtime in a more suitable | |
| 25 | 25 | presentation format if needed. | |
| 26 | + * Named method parameters changed on a wide scale to unify their use. Now git specific | ||
| 27 | + terms are used everywhere, such as "Reference" ( ref ) and "Revision" ( rev ). | ||
| 28 | + Prevously multiple terms where used making it harder to know which type was allowed | ||
| 29 | + or not. | ||
| 30 | + | ||
| 26 | 31 | ||
| 27 | 32 | Item Iteration | |
| 28 | 33 | -------------- | |
@@ -48,6 +53,8 @@ Repo | |||
| 48 | 53 | - 'log' method as it as effectively the same as the 'commits' method | |
| 49 | 54 | - 'commits_since' as it is just a flag given to rev-list in Commit.iter_items | |
| 50 | 55 | - 'commit_count' as it was just a redirection to the respective commit method | |
| 56 | + * Renamed commits to iter_commits to improve the performance, adjusted signature | ||
| 57 | + to be more versatile | ||
| 51 | 58 | * 'commits' method has no max-count of returned commits anymore, it now behaves | |
| 52 | 59 | like git-rev-list | |
| 53 | 60 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -100,17 +100,39 @@ def summary(self): | |||
| 100 | 100 | First line of the commit message. | |
| 101 | 101 | """ | |
| 102 | 102 | return self.message.split('\n', 1)[0] | |
| 103 | + | ||
| 104 | + def iter_parents(self, paths='', **kwargs): | ||
| 105 | + """ | ||
| 106 | + Iterate _all_ parents of this commit. | ||
| 107 | + | ||
| 108 | + ``paths`` | ||
| 109 | + Optional path or list of paths limiting the Commits to those that | ||
| 110 | + contain at least one of the paths | ||
| 111 | + | ||
| 112 | + ``kwargs`` | ||
| 113 | + All arguments allowed by git-rev-list | ||
| 114 | + | ||
| 115 | + Return: | ||
| 116 | + Iterator yielding Commit objects which are parents of self | ||
| 117 | + """ | ||
| 118 | + # skip ourselves | ||
| 119 | + skip = kwargs.get("skip", 1) | ||
| 120 | + if skip == 0: # skip ourselves | ||
| 121 | + skip = 1 | ||
| 122 | + kwargs['skip'] = skip | ||
| 123 | + | ||
| 124 | + return self.iter_items( self.repo, self, paths, **kwargs ) | ||
| 103 | 125 | ||
| 104 | 126 | @classmethod | |
| 105 | - def count(cls, repo, ref, paths=''): | ||
| 127 | + def count(cls, repo, rev, paths=''): | ||
| 106 | 128 | """ | |
| 107 | - Count the number of commits reachable from this ref | ||
| 129 | + Count the number of commits reachable from this revision | ||
| 108 | 130 | ||
| 109 | 131 | ``repo`` | |
| 110 | 132 | is the Repo | |
| 111 | 133 | ||
| 112 | - ``ref`` | ||
| 113 | - is the ref from which to begin (SHA1 or name) | ||
| 134 | + ``rev`` | ||
| 135 | + revision specifier, see git-rev-parse for viable options | ||
| 114 | 136 | ||
| 115 | 137 | ``paths`` | |
| 116 | 138 | is an optinal path or a list of paths restricting the return value | |
@@ -119,18 +141,18 @@ def count(cls, repo, ref, paths=''): | |||
| 119 | 141 | Returns | |
| 120 | 142 | int | |
| 121 | 143 | """ | |
| 122 | - return len(repo.git.rev_list(ref, '--', paths).strip().splitlines()) | ||
| 144 | + return len(repo.git.rev_list(rev, '--', paths).strip().splitlines()) | ||
| 123 | 145 | ||
| 124 | 146 | @classmethod | |
| 125 | - def iter_items(cls, repo, ref, paths='', **kwargs): | ||
| 147 | + def iter_items(cls, repo, rev, paths='', **kwargs): | ||
| 126 | 148 | """ | |
| 127 | 149 | Find all commits matching the given criteria. | |
| 128 | 150 | ||
| 129 | 151 | ``repo`` | |
| 130 | 152 | is the Repo | |
| 131 | 153 | ||
| 132 | - ``ref`` | ||
| 133 | - is the ref from which to begin (SHA1, Head or name) | ||
| 154 | + ``rev`` | ||
| 155 | + revision specifier, see git-rev-parse for viable options | ||
| 134 | 156 | ||
| 135 | 157 | ``paths`` | |
| 136 | 158 | is an optinal path or list of paths, if set only Commits that include the path | |
@@ -149,7 +171,7 @@ def iter_items(cls, repo, ref, paths='', **kwargs): | |||
| 149 | 171 | options.update(kwargs) | |
| 150 | 172 | ||
| 151 | 173 | # the test system might confront us with string values - | |
| 152 | - proc = repo.git.rev_list(ref, '--', paths, **options) | ||
| 174 | + proc = repo.git.rev_list(rev, '--', paths, **options) | ||
| 153 | 175 | return cls._iter_from_process_or_stream(repo, proc) | |
| 154 | 176 | ||
| 155 | 177 | @classmethod | |
@@ -201,7 +223,7 @@ def _iter_from_process_or_stream(cls, repo, proc_or_stream): | |||
| 201 | 223 | # END while there are message lines | |
| 202 | 224 | message = '\n'.join(message_lines) | |
| 203 | 225 | ||
| 204 | - yield Commit(repo, id=id, parents=parents, tree=tree, author=author, authored_date=authored_date, | ||
| 226 | + yield Commit(repo, id=id, parents=tuple(parents), tree=tree, author=author, authored_date=authored_date, | ||
| 205 | 227 | committer=committer, committed_date=committed_date, message=message) | |
| 206 | 228 | # END for each line in stream | |
| 207 | 229 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,7 +10,7 @@ | |||
| 10 | 10 | from objects.utils import get_object_type_by_name | |
| 11 | 11 | from utils import LazyMixin, Iterable | |
| 12 | 12 | ||
| 13 | - class Ref(LazyMixin, Iterable): | ||
| 13 | + class Reference(LazyMixin, Iterable): | ||
| 14 | 14 | """ | |
| 15 | 15 | Represents a named reference to any object | |
| 16 | 16 | """ | |
@@ -138,7 +138,7 @@ def _from_string(cls, repo, line): | |||
| 138 | 138 | # return cls(repo, full_path, obj) | |
| 139 | 139 | ||
| 140 | 140 | ||
| 141 | - class Head(Ref): | ||
| 141 | + class Head(Reference): | ||
| 142 | 142 | """ | |
| 143 | 143 | A Head is a named reference to a Commit. Every Head instance contains a name | |
| 144 | 144 | and a Commit object. | |
@@ -181,7 +181,7 @@ def __repr__(self): | |||
| 181 | 181 | ||
| 182 | 182 | ||
| 183 | 183 | ||
| 184 | - class TagRef(Ref): | ||
| 184 | + class TagRef(Reference): | ||
| 185 | 185 | """ | |
| 186 | 186 | Class representing a lightweight tag reference which either points to a commit | |
| 187 | 187 | or to a tag object. In the latter case additional information, like the signature | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -116,12 +116,12 @@ def tags(self): | |||
| 116 | 116 | """ | |
| 117 | 117 | return Tag.list_items(self) | |
| 118 | 118 | ||
| 119 | - def blame(self, ref, file): | ||
| 119 | + def blame(self, rev, file): | ||
| 120 | 120 | """ | |
| 121 | - The blame information for the given file at the given ref. | ||
| 121 | + The blame information for the given file at the given revision. | ||
| 122 | 122 | ||
| 123 | - ``ref`` | ||
| 124 | - Ref object or Commit | ||
| 123 | + ``rev`` | ||
| 124 | + revision specifier, see git-rev-parse for viable options. | ||
| 125 | 125 | ||
| 126 | 126 | Returns | |
| 127 | 127 | list: [git.Commit, list: [<line>]] | |
@@ -199,37 +199,29 @@ def blame(self, ref, file): | |||
| 199 | 199 | # END distinguish hexsha vs other information | |
| 200 | 200 | return blames | |
| 201 | 201 | ||
| 202 | - def commits(self, start=None, paths='', max_count=None, skip=0): | ||
| 202 | + def iter_commits(self, rev=None, paths='', **kwargs): | ||
| 203 | 203 | """ | |
| 204 | 204 | A list of Commit objects representing the history of a given ref/commit | |
| 205 | 205 | ||
| 206 | - ``start`` | ||
| 207 | - is a Ref or Commit to start the commits from. If start is None, | ||
| 208 | - the active branch will be used | ||
| 206 | + ``rev`` | ||
| 207 | + revision specifier, see git-rev-parse for viable options. | ||
| 208 | + If None, the active branch will be used. | ||
| 209 | 209 | ||
| 210 | 210 | ``paths`` | |
| 211 | 211 | is an optional path or a list of paths to limit the returned commits to | |
| 212 | 212 | Commits that do not contain that path or the paths will not be returned. | |
| 213 | - | ||
| 214 | - ``max_count`` | ||
| 215 | - is the maximum number of commits to return (default None) | ||
| 216 | - | ||
| 217 | - ``skip`` | ||
| 218 | - is the number of commits to skip (default 0) which will effectively | ||
| 219 | - move your commit-window by the given number. | ||
| 213 | + | ||
| 214 | + ``kwargs`` | ||
| 215 | + Arguments to be passed to git-rev-parse - common ones are | ||
| 216 | + max_count and skip | ||
| 220 | 217 | ||
| 221 | 218 | Returns | |
| 222 | 219 | ``git.Commit[]`` | |
| 223 | 220 | """ | |
| 224 | - options = {'max_count': max_count, | ||
| 225 | - 'skip': skip} | ||
| 226 | - | ||
| 227 | - if max_count is None: | ||
| 228 | - options.pop('max_count') | ||
| 229 | - if start is None: | ||
| 230 | - start = self.active_branch | ||
| 221 | + if rev is None: | ||
| 222 | + rev = self.active_branch | ||
| 231 | 223 | ||
| 232 | - return Commit.list_items(self, start, paths, **options) | ||
| 224 | + return Commit.list_items(self, rev, paths, **kwargs) | ||
| 233 | 225 | ||
| 234 | 226 | def commits_between(self, frm, to, *args, **kwargs): | |
| 235 | 227 | """ | |
@@ -248,50 +240,31 @@ def commits_between(self, frm, to, *args, **kwargs): | |||
| 248 | 240 | return reversed(Commit.list_items(self, "%s..%s" % (frm, to))) | |
| 249 | 241 | ||
| 250 | 242 | ||
| 251 | - def commit(self, id=None, paths = ''): | ||
| 243 | + def commit(self, rev=None): | ||
| 252 | 244 | """ | |
| 253 | - The Commit object for the specified id | ||
| 245 | + The Commit object for the specified revision | ||
| 254 | 246 | ||
| 255 | - ``id`` | ||
| 256 | - is the SHA1 identifier of the commit or a ref or a ref name | ||
| 257 | - if None, it defaults to the active branch | ||
| 247 | + ``rev`` | ||
| 248 | + revision specifier, see git-rev-parse for viable options. | ||
| 258 | 249 | ||
| 259 | - | ||
| 260 | - ``paths`` | ||
| 261 | - is an optional path or a list of paths, | ||
| 262 | - if set the returned commit must contain the path or paths | ||
| 263 | - | ||
| 264 | 250 | Returns | |
| 265 | 251 | ``git.Commit`` | |
| 266 | 252 | """ | |
| 267 | - if id is None: | ||
| 268 | - id = self.active_branch | ||
| 269 | - options = {'max_count': 1} | ||
| 270 | - | ||
| 271 | - commits = Commit.list_items(self, id, paths, **options) | ||
| 272 | - | ||
| 273 | - if not commits: | ||
| 274 | - raise ValueError, "Invalid identifier %s, or given path '%s' too restrictive" % ( id, path ) | ||
| 275 | - return commits[0] | ||
| 276 | - | ||
| 277 | - def commit_deltas_from(self, other_repo, ref='master', other_ref='master'): | ||
| 278 | - """ | ||
| 279 | - Returns a list of commits that is in ``other_repo`` but not in self | ||
| 280 | - | ||
| 281 | - Returns | ||
| 282 | - git.Commit[] | ||
| 283 | - """ | ||
| 284 | - repo_refs = self.git.rev_list(ref, '--').strip().splitlines() | ||
| 285 | - other_repo_refs = other_repo.git.rev_list(other_ref, '--').strip().splitlines() | ||
| 253 | + if rev is None: | ||
| 254 | + rev = self.active_branch | ||
| 255 | + | ||
| 256 | + # NOTE: currently we are not checking wheter rev really points to a commit | ||
| 257 | + # If not, the system will barf on access of the object, but we don't do that | ||
| 258 | + # here to safe cycles | ||
| 259 | + c = Commit(self, rev) | ||
| 260 | + return c | ||
| 286 | 261 | ||
| 287 | - diff_refs = list(set(other_repo_refs) - set(repo_refs)) | ||
| 288 | - return map(lambda ref: Commit(other_repo, ref ), diff_refs) | ||
| 289 | 262 | ||
| 290 | - def tree(self, treeish=None): | ||
| 263 | + def tree(self, ref=None): | ||
| 291 | 264 | """ | |
| 292 | 265 | The Tree object for the given treeish reference | |
| 293 | 266 | ||
| 294 | - ``treeish`` | ||
| 267 | + ``ref`` | ||
| 295 | 268 | is a Ref instance defaulting to the active_branch if None. | |
| 296 | 269 | ||
| 297 | 270 | Examples:: | |
@@ -305,27 +278,42 @@ def tree(self, treeish=None): | |||
| 305 | 278 | A ref is requried here to assure you point to a commit or tag. Otherwise | |
| 306 | 279 | it is not garantueed that you point to the root-level tree. | |
| 307 | 280 | ||
| 308 | - If you need a non-root level tree, find it by iterating the root tree. | ||
| 309 | - """ | ||
| 310 | - if treeish is None: | ||
| 311 | - treeish = self.active_branch | ||
| 312 | - if not isinstance(treeish, Ref): | ||
| 313 | - raise ValueError( "Treeish reference required, got %r" % treeish ) | ||
| 281 | + If you need a non-root level tree, find it by iterating the root tree. Otherwise | ||
| 282 | + it cannot know about its path relative to the repository root and subsequent | ||
| 283 | + operations might have unexpected results. | ||
| 284 | + """ | ||
| 285 | + if ref is None: | ||
| 286 | + ref = self.active_branch | ||
| 287 | + if not isinstance(ref, Reference): | ||
| 288 | + raise ValueError( "Reference required, got %r" % ref ) | ||
| 314 | 289 | ||
| 315 | 290 | ||
| 316 | 291 | # As we are directly reading object information, we must make sure | |
| 317 | 292 | # we truly point to a tree object. We resolve the ref to a sha in all cases | |
| 318 | 293 | # to assure the returned tree can be compared properly. Except for | |
| 319 | 294 | # heads, ids should always be hexshas | |
| 320 | - hexsha, typename, size = self.git.get_object_header( treeish ) | ||
| 295 | + hexsha, typename, size = self.git.get_object_header( ref ) | ||
| 321 | 296 | if typename != "tree": | |
| 322 | - hexsha, typename, size = self.git.get_object_header( str(treeish)+'^{tree}' ) | ||
| 297 | + # will raise if this is not a valid tree | ||
| 298 | + hexsha, typename, size = self.git.get_object_header( str(ref)+'^{tree}' ) | ||
| 323 | 299 | # END tree handling | |
| 324 | - treeish = hexsha | ||
| 300 | + ref = hexsha | ||
| 325 | 301 | ||
| 326 | 302 | # the root has an empty relative path and the default mode | |
| 327 | - return Tree(self, treeish, 0, '') | ||
| 303 | + return Tree(self, ref, 0, '') | ||
| 304 | + | ||
| 305 | + def commit_deltas_from(self, other_repo, ref='master', other_ref='master'): | ||
| 306 | + """ | ||
| 307 | + Returns a list of commits that is in ``other_repo`` but not in self | ||
| 328 | 308 | ||
| 309 | + Returns | ||
| 310 | + git.Commit[] | ||
| 311 | + """ | ||
| 312 | + repo_refs = self.git.rev_list(ref, '--').strip().splitlines() | ||
| 313 | + other_repo_refs = other_repo.git.rev_list(other_ref, '--').strip().splitlines() | ||
| 314 | + | ||
| 315 | + diff_refs = list(set(other_repo_refs) - set(repo_refs)) | ||
| 316 | + return map(lambda ref: Commit(other_repo, ref ), diff_refs) | ||
| 329 | 317 | ||
| 330 | 318 | def diff(self, a, b, *paths): | |
| 331 | 319 | """ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -62,7 +62,7 @@ def test_tags(self): | |||
| 62 | 62 | ref_count = 0 | |
| 63 | 63 | for ref in chain(self.repo.tags, self.repo.heads): | |
| 64 | 64 | ref_count += 1 | |
| 65 | - assert isinstance(ref, refs.Ref) | ||
| 65 | + assert isinstance(ref, refs.Reference) | ||
| 66 | 66 | assert str(ref) == ref.name | |
| 67 | 67 | assert repr(ref) | |
| 68 | 68 | assert ref == ref | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -233,3 +233,13 @@ def test_equality(self): | |||
| 233 | 233 | assert_equal(commit1, commit2) | |
| 234 | 234 | assert_not_equal(commit2, commit3) | |
| 235 | 235 | ||
| 236 | + def test_iter_parents(self): | ||
| 237 | + # should return all but ourselves, even if skip is defined | ||
| 238 | + c = self.repo.commit('0.1.5') | ||
| 239 | + for skip in (0, 1): | ||
| 240 | + piter = c.iter_parents(skip=skip) | ||
| 241 | + first_parent = piter.next() | ||
| 242 | + assert first_parent != c | ||
| 243 | + assert first_parent == c.parents[0] | ||
| 244 | + # END for each | ||
| 245 | + | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,7 +21,7 @@ def test_iteration(self): | |||
| 21 | 21 | # return quite a lot of commits, we just take one and hence abort the operation | |
| 22 | 22 | ||
| 23 | 23 | st = time() | |
| 24 | - for c in self.repo.commits(): | ||
| 24 | + for c in self.repo.iter_commits('0.1.6'): | ||
| 25 | 25 | num_commits += 1 | |
| 26 | 26 | c.author | |
| 27 | 27 | c.authored_date | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -42,7 +42,7 @@ def test_heads_should_populate_head_data(self): | |||
| 42 | 42 | def test_commits(self, git): | |
| 43 | 43 | git.return_value = ListProcessAdapter(fixture('rev_list')) | |
| 44 | 44 | ||
| 45 | - commits = self.repo.commits('master', max_count=10) | ||
| 45 | + commits = list( self.repo.iter_commits('master', max_count=10) ) | ||
| 46 | 46 | ||
| 47 | 47 | c = commits[0] | |
| 48 | 48 | assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id) | |
@@ -73,8 +73,6 @@ def test_commit(self, git): | |||
| 73 | 73 | ||
| 74 | 74 | assert_equal("4c8124ffcf4039d292442eeccabdeca5af5c5017", commit.id) | |
| 75 | 75 | ||
| 76 | - assert_true(git.called) | ||
| 77 | - | ||
| 78 | 76 | @patch_object(Repo, '__init__') | |
| 79 | 77 | @patch_object(Git, '_call_process') | |
| 80 | 78 | def test_init_bare(self, git, repo): | |
| Back | FazBrowse Home | New Git URL |
0 commit comments