diff options
Diffstat (limited to 'project.py')
-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, |