Fuse the given commits onto this branch. Args: src: the branch (Branch obj) to fuse commits from. ip: id of the commit to act as the insertion point. The commits to fuse are inserted after this commit. ip has to correspond to one of the divergent commits from self or
(self, src, ip, only=None, exclude=None, op_cb=None)
| 1024 | os.remove(self._fuse_commits_fp) |
| 1025 | |
| 1026 | def fuse(self, src, ip, only=None, exclude=None, op_cb=None): |
| 1027 | """Fuse the given commits onto this branch. |
| 1028 | |
| 1029 | Args: |
| 1030 | src: the branch (Branch obj) to fuse commits from. |
| 1031 | ip: id of the commit to act as the insertion point. The commits to fuse |
| 1032 | are inserted after this commit. ip has to correspond to one of the |
| 1033 | divergent commits from self or the divergent point. |
| 1034 | only: ids of commits to use only. |
| 1035 | exclude: ids of commtis to exclude. |
| 1036 | op_cb: see OpCb. |
| 1037 | """ |
| 1038 | self._check_is_current() |
| 1039 | self._check_op_not_in_progress() |
| 1040 | |
| 1041 | save_fn = op_cb.save if op_cb else None |
| 1042 | repo = self.gl_repo |
| 1043 | |
| 1044 | ip_to_src = src.history(reverse=True) |
| 1045 | ip_to_src.hide(ip) |
| 1046 | divergent_commits, fuse_commits = itertools.tee(ip_to_src, 2) |
| 1047 | |
| 1048 | if only: |
| 1049 | fuse_commits = (ci for ci in fuse_commits if ci.id in only) |
| 1050 | elif exclude: |
| 1051 | fuse_commits = (ci for ci in fuse_commits if ci.id not in exclude) |
| 1052 | |
| 1053 | fuse_commits, _fuse_commits = itertools.tee(fuse_commits, 2) |
| 1054 | if not any(_fuse_commits): |
| 1055 | raise GlError('No commits to fuse') |
| 1056 | |
| 1057 | # Figure out where to detach head |
| 1058 | # If the ip is not the mb, then we need to detach at the ip, because the |
| 1059 | # first div commit won't have the ip as its parent |
| 1060 | # But, if the ip **is** the merge base we can advance the head until the div |
| 1061 | # commits and the commits to fuse diverge |
| 1062 | detach_point = ip |
| 1063 | if ip == repo.merge_base(self, src): |
| 1064 | for ci, fuse_ci in zip(divergent_commits, fuse_commits): |
| 1065 | if ci.id != fuse_ci.id: |
| 1066 | fuse_commits = itertools.chain([fuse_ci], fuse_commits) |
| 1067 | break |
| 1068 | detach_point = ci.id |
| 1069 | if op_cb and op_cb.apply_ok: |
| 1070 | op_cb.apply_ok(ci) |
| 1071 | |
| 1072 | after_commits = self.history(reverse=True) |
| 1073 | after_commits.hide(ip) |
| 1074 | commits = itertools.chain(fuse_commits, after_commits) |
| 1075 | commits, _commits = itertools.tee(commits, 2) |
| 1076 | if not any(_commits): # it's a ff |
| 1077 | self._safe_reset(detach_point, _stash_msg_fuse, save_fn=save_fn) |
| 1078 | restore_fn = op_cb.restore_ok if op_cb else None |
| 1079 | self._safe_restore(_stash_msg_fuse, restore_fn=restore_fn) |
| 1080 | return |
| 1081 | |
| 1082 | # We are going to have to do some cherry-picking |
| 1083 |