diff options
| -rw-r--r-- | project.py | 74 |
1 files changed, 39 insertions, 35 deletions
| @@ -708,28 +708,28 @@ class Project(object): | |||
| 708 | syncbuf.later1(self, _doff) | 708 | syncbuf.later1(self, _doff) |
| 709 | return | 709 | return |
| 710 | 710 | ||
| 711 | if merge == rev: | 711 | # If the upstream switched on us, warn the user. |
| 712 | try: | 712 | # |
| 713 | old_merge = self.bare_git.rev_parse('%s@{1}' % merge) | 713 | if merge != rev: |
| 714 | except GitError: | ||
| 715 | old_merge = merge | ||
| 716 | if old_merge == '0000000000000000000000000000000000000000' \ | ||
| 717 | or old_merge == '': | ||
| 718 | old_merge = merge | ||
| 719 | else: | ||
| 720 | # The upstream switched on us. Time to cross our fingers | ||
| 721 | # and pray that the old upstream also wasn't in the habit | ||
| 722 | # of rebasing itself. | ||
| 723 | # | ||
| 724 | syncbuf.info(self, "manifest switched %s...%s", merge, rev) | 714 | syncbuf.info(self, "manifest switched %s...%s", merge, rev) |
| 725 | old_merge = merge | ||
| 726 | 715 | ||
| 727 | if rev == old_merge: | 716 | # Examine the local commits not in the remote. Find the |
| 728 | upstream_lost = [] | 717 | # last one attributed to this user, if any. |
| 729 | else: | 718 | # |
| 730 | upstream_lost = self._revlist(not_rev(rev), old_merge) | 719 | local_changes = self._revlist( |
| 731 | 720 | not_rev(merge), | |
| 732 | if not upstream_lost and not upstream_gain: | 721 | HEAD, |
| 722 | format='%H %ce') | ||
| 723 | |||
| 724 | last_mine = None | ||
| 725 | cnt_mine = 0 | ||
| 726 | for commit in local_changes: | ||
| 727 | commit_id, committer_email = commit.split(' ', 2) | ||
| 728 | if committer_email == self.UserEmail: | ||
| 729 | last_mine = commit_id | ||
| 730 | cnt_mine += 1 | ||
| 731 | |||
| 732 | if not local_changes and not upstream_gain: | ||
| 733 | # Trivially no changes caused by the upstream. | 733 | # Trivially no changes caused by the upstream. |
| 734 | # | 734 | # |
| 735 | return | 735 | return |
| @@ -738,25 +738,24 @@ class Project(object): | |||
| 738 | syncbuf.fail(self, _DirtyError()) | 738 | syncbuf.fail(self, _DirtyError()) |
| 739 | return | 739 | return |
| 740 | 740 | ||
| 741 | if upstream_lost: | 741 | if cnt_mine < len(local_changes): |
| 742 | # Upstream rebased. Not everything in HEAD | 742 | # Upstream rebased. Not everything in HEAD |
| 743 | # may have been caused by the user. | 743 | # was created by this user. |
| 744 | # | 744 | # |
| 745 | syncbuf.info(self, | 745 | syncbuf.info(self, |
| 746 | "discarding %d commits removed from upstream", | 746 | "discarding %d commits removed from upstream", |
| 747 | len(upstream_lost)) | 747 | len(local_changes) - cnt_mine) |
| 748 | 748 | ||
| 749 | branch.remote = rem | 749 | branch.remote = rem |
| 750 | branch.merge = self.revision | 750 | branch.merge = self.revision |
| 751 | branch.Save() | 751 | branch.Save() |
| 752 | 752 | ||
| 753 | my_changes = self._revlist(not_rev(old_merge), HEAD) | 753 | if cnt_mine > 0: |
| 754 | if my_changes: | ||
| 755 | def _dorebase(): | 754 | def _dorebase(): |
| 756 | self._Rebase(upstream = old_merge, onto = rev) | 755 | self._Rebase(upstream = '%s^1' % last_mine, onto = rev) |
| 757 | self._CopyFiles() | 756 | self._CopyFiles() |
| 758 | syncbuf.later2(self, _dorebase) | 757 | syncbuf.later2(self, _dorebase) |
| 759 | elif upstream_lost: | 758 | elif local_changes: |
| 760 | try: | 759 | try: |
| 761 | self._ResetHard(rev) | 760 | self._ResetHard(rev) |
| 762 | self._CopyFiles() | 761 | self._CopyFiles() |
| @@ -1141,11 +1140,11 @@ class Project(object): | |||
| 1141 | def _gitdir_path(self, path): | 1140 | def _gitdir_path(self, path): |
| 1142 | return os.path.join(self.gitdir, path) | 1141 | return os.path.join(self.gitdir, path) |
| 1143 | 1142 | ||
| 1144 | def _revlist(self, *args): | 1143 | def _revlist(self, *args, **kw): |
| 1145 | cmd = [] | 1144 | a = [] |
| 1146 | cmd.extend(args) | 1145 | a.extend(args) |
| 1147 | cmd.append('--') | 1146 | a.append('--') |
| 1148 | return self.work_git.rev_list(*args) | 1147 | return self.work_git.rev_list(*a, **kw) |
| 1149 | 1148 | ||
| 1150 | @property | 1149 | @property |
| 1151 | def _allrefs(self): | 1150 | def _allrefs(self): |
| @@ -1270,8 +1269,11 @@ class Project(object): | |||
| 1270 | self.update_ref('-d', name, old) | 1269 | self.update_ref('-d', name, old) |
| 1271 | self._project.bare_ref.deleted(name) | 1270 | self._project.bare_ref.deleted(name) |
| 1272 | 1271 | ||
| 1273 | def rev_list(self, *args): | 1272 | def rev_list(self, *args, **kw): |
| 1274 | cmdv = ['rev-list'] | 1273 | if 'format' in kw: |
| 1274 | cmdv = ['log', '--pretty=format:%s' % kw['format']] | ||
| 1275 | else: | ||
| 1276 | cmdv = ['rev-list'] | ||
| 1275 | cmdv.extend(args) | 1277 | cmdv.extend(args) |
| 1276 | p = GitCommand(self._project, | 1278 | p = GitCommand(self._project, |
| 1277 | cmdv, | 1279 | cmdv, |
| @@ -1280,7 +1282,9 @@ class Project(object): | |||
| 1280 | capture_stderr = True) | 1282 | capture_stderr = True) |
| 1281 | r = [] | 1283 | r = [] |
| 1282 | for line in p.process.stdout: | 1284 | for line in p.process.stdout: |
| 1283 | r.append(line[:-1]) | 1285 | if line[-1] == '\n': |
| 1286 | line = line[:-1] | ||
| 1287 | r.append(line) | ||
| 1284 | if p.Wait() != 0: | 1288 | if p.Wait() != 0: |
| 1285 | raise GitError('%s rev-list %s: %s' % ( | 1289 | raise GitError('%s rev-list %s: %s' % ( |
| 1286 | self._project.name, | 1290 | self._project.name, |
