| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -73,7 +73,7 @@ Refs | |||
| 73 | 73 | * Ability to create new heads and tags in the Repository ( but using the respective | |
| 74 | 74 | Reference Type ), i.e. Head.create(repo, name, commit = 'HEAD') or | |
| 75 | 75 | TagReference.create(repo, name | |
| 76 | - * Ability to rename references and tags | ||
| 76 | + * Ability to rename references and tagsre | ||
| 77 | 77 | * Ability to remove references and tags | |
| 78 | 78 | * Ability to checkout a reference - | |
| 79 | 79 | * Check whether we are the active reference HEAD.commit == self.commit | |
@@ -83,6 +83,8 @@ Remote | |||
| 83 | 83 | * 'push' method needs a test, a true test repository is required though, a fork | |
| 84 | 84 | of a fork would do :)! | |
| 85 | 85 | * Fetch should return heads that where updated, pull as well. | |
| 86 | + * Creation and deletion methods for references should be part of the interface, allowing | ||
| 87 | + repo.create_head(...) instaed of Head.create(repo, ...). Its a convenience thing, clearly | ||
| 86 | 88 | ||
| 87 | 89 | Repo | |
| 88 | 90 | ---- | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -19,7 +19,7 @@ class Reference(LazyMixin, Iterable): | |||
| 19 | 19 | _common_path_default = "refs" | |
| 20 | 20 | _id_attribute_ = "name" | |
| 21 | 21 | ||
| 22 | - def __init__(self, repo, path, object = None): | ||
| 22 | + def __init__(self, repo, path): | ||
| 23 | 23 | """ | |
| 24 | 24 | Initialize this instance | |
| 25 | 25 | ``repo`` | |
@@ -29,16 +29,12 @@ def __init__(self, repo, path, object = None): | |||
| 29 | 29 | Path relative to the .git/ directory pointing to the ref in question, i.e. | |
| 30 | 30 | refs/heads/master | |
| 31 | 31 | ||
| 32 | - ``object`` | ||
| 33 | - Object instance, will be retrieved on demand if None | ||
| 34 | 32 | """ | |
| 35 | 33 | if not path.startswith(self._common_path_default): | |
| 36 | 34 | raise ValueError("Cannot instantiate %s Reference from path %s" % ( self.__class__.__name__, path )) | |
| 37 | 35 | ||
| 38 | 36 | self.repo = repo | |
| 39 | 37 | self.path = path | |
| 40 | - if object is not None: | ||
| 41 | - self.object = object | ||
| 42 | 38 | ||
| 43 | 39 | def __str__(self): | |
| 44 | 40 | return self.name | |
@@ -386,7 +382,7 @@ class Head(Reference): | |||
| 386 | 382 | _common_path_default = "refs/heads" | |
| 387 | 383 | ||
| 388 | 384 | @classmethod | |
| 389 | - def create(cls, repo, path, commit=HEAD(), **kwargs ): | ||
| 385 | + def create(cls, repo, path, commit='HEAD', force=False, **kwargs ): | ||
| 390 | 386 | """ | |
| 391 | 387 | Create a new head. | |
| 392 | 388 | ``repo`` | |
@@ -399,30 +395,42 @@ def create(cls, repo, path, commit=HEAD(), **kwargs ): | |||
| 399 | 395 | ``commit`` | |
| 400 | 396 | Commit to which the new head should point, defaults to the | |
| 401 | 397 | current HEAD | |
| 398 | + | ||
| 399 | + ``force`` | ||
| 400 | + if True, force creation even if branch with that name already exists. | ||
| 402 | 401 | ||
| 403 | 402 | ``**kwargs`` | |
| 404 | 403 | Additional keyword arguments to be passed to git-branch, i.e. | |
| 405 | - track, no-track, l, f to force creation even if branch with that | ||
| 406 | - name already exists. | ||
| 404 | + track, no-track, l | ||
| 407 | 405 | ||
| 408 | 406 | Returns | |
| 409 | 407 | Newly created Head | |
| 410 | 408 | ||
| 411 | 409 | Note | |
| 412 | 410 | This does not alter the current HEAD, index or Working Tree | |
| 413 | 411 | """ | |
| 414 | - raise NotImplementedError("todo") | ||
| 412 | + if cls is not Head: | ||
| 413 | + raise TypeError("Only Heads can be created explicitly, not objects of type %s" % cls.__name__) | ||
| 414 | + | ||
| 415 | + args = ( path, commit ) | ||
| 416 | + if force: | ||
| 417 | + kwargs['f'] = True | ||
| 418 | + | ||
| 419 | + repo.git.branch(*args, **kwargs) | ||
| 420 | + return cls(repo, "%s/%s" % ( cls._common_path_default, path)) | ||
| 415 | 421 | ||
| 416 | 422 | ||
| 417 | 423 | @classmethod | |
| 418 | - def delete(cls, repo, *heads, force=False): | ||
| 424 | + def delete(cls, repo, *heads, **kwargs): | ||
| 419 | 425 | """ | |
| 420 | 426 | Delete the given heads | |
| 421 | 427 | ||
| 422 | 428 | ``force`` | |
| 423 | 429 | If True, the heads will be deleted even if they are not yet merged into | |
| 424 | - the main development stream | ||
| 430 | + the main development stream. | ||
| 431 | + Default False | ||
| 425 | 432 | """ | |
| 433 | + force = kwargs.get("force", False) | ||
| 426 | 434 | flag = "-d" | |
| 427 | 435 | if force: | |
| 428 | 436 | flag = "-D" | |
@@ -448,7 +456,7 @@ def rename(self, new_path, force=False): | |||
| 448 | 456 | if force: | |
| 449 | 457 | flag = "-M" | |
| 450 | 458 | ||
| 451 | - self.repo.git.branch(flag, new_path) | ||
| 459 | + self.repo.git.branch(flag, self, new_path) | ||
| 452 | 460 | self.path = "%s/%s" % (self._common_path_default, new_path) | |
| 453 | 461 | return self | |
| 454 | 462 | ||
@@ -568,7 +576,7 @@ def remote_branch(self): | |||
| 568 | 576 | return '/'.join(tokens[3:]) | |
| 569 | 577 | ||
| 570 | 578 | @classmethod | |
| 571 | - def delete(cls, repo, *remotes): | ||
| 579 | + def delete(cls, repo, *remotes, **kwargs): | ||
| 572 | 580 | """ | |
| 573 | 581 | Delete the given remote references. | |
| 574 | 582 | """ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -109,10 +109,39 @@ def test_head_reset(self, rw_repo): | |||
| 109 | 109 | # type check | |
| 110 | 110 | self.failUnlessRaises(ValueError, setattr, cur_head, "reference", "that") | |
| 111 | 111 | ||
| 112 | + # head handling | ||
| 113 | + commit = 'HEAD' | ||
| 114 | + prev_head_commit = cur_head.commit | ||
| 115 | + for count, new_name in enumerate(("my_new_head", "feature/feature1")): | ||
| 116 | + actual_commit = commit+"^"*count | ||
| 117 | + new_head = Head.create(rw_repo, new_name, actual_commit) | ||
| 118 | + assert cur_head.commit == prev_head_commit | ||
| 119 | + assert isinstance(new_head, Head) | ||
| 120 | + # already exists | ||
| 121 | + self.failUnlessRaises(GitCommandError, Head.create, rw_repo, new_name) | ||
| 122 | + | ||
| 123 | + # force it | ||
| 124 | + new_head = Head.create(rw_repo, new_name, actual_commit, force=True) | ||
| 125 | + old_path = new_head.path | ||
| 126 | + old_name = new_head.name | ||
| 127 | + | ||
| 128 | + assert new_head.rename("hello").name == "hello" | ||
| 129 | + assert new_head.rename("hello/world").name == "hello/world" | ||
| 130 | + assert new_head.rename(old_name).name == old_name and new_head.path == old_path | ||
| 131 | + | ||
| 132 | + # rename with force | ||
| 133 | + tmp_head = Head.create(rw_repo, "tmphead") | ||
| 134 | + self.failUnlessRaises(GitCommandError, tmp_head.rename, new_head) | ||
| 135 | + tmp_head.rename(new_head, force=True) | ||
| 136 | + assert tmp_head == new_head and tmp_head.object == new_head.object | ||
| 137 | + | ||
| 138 | + Head.delete(rw_repo, tmp_head) | ||
| 139 | + heads = rw_repo.heads | ||
| 140 | + assert tmp_head not in heads and new_head not in heads | ||
| 141 | + # force on deletion testing would be missing here, code looks okay though ;) | ||
| 142 | + # END for each new head name | ||
| 143 | + self.failUnlessRaises(TypeError, RemoteReference.create, rw_repo, "some_name") | ||
| 112 | 144 | ||
| 113 | - self.fail("head creation") | ||
| 114 | - self.fail("head renaming") | ||
| 115 | - self.fail("head removal") | ||
| 116 | 145 | self.fail("tag creation") | |
| 117 | 146 | self.fail("tag deletion") | |
| 118 | 147 | self.fail("remote deletion") | |
| Back | FazBrowse Home | New Git URL |
0 commit comments