diff --git a/git_cl.py b/git_cl.py index ab6ad7337..1afa70911 100755 --- a/git_cl.py +++ b/git_cl.py @@ -2991,18 +2991,45 @@ class Changelist(object): return print('No upstream branch set. Continuing upload with Gerrit merge base.') + external_parent_last_uploaded = self._GetChangeCommit( + revision=local_ps)['parents'][0] + external_base_last_uploaded = external_parent_last_uploaded['commit'] + + if external_base != external_base_last_uploaded: + print('\nPatch set merge bases are different (%s, %s).\n' % + (external_base_last_uploaded, external_base)) + confirm_or_exit('Can\'t apply the latest changes from Gerrit.\n' + 'Continue with upload and override the latest changes?') + return + # Fetch Gerrit's CL base if it doesn't exist locally. remote, _ = self.GetRemoteBranch() if not scm.GIT.IsValidRevision(settings.GetRoot(), external_base): RunGitSilent(['fetch', remote, external_base]) # Get the diff between local_ps and external_ps. + print('Fetching changes...') issue = self.GetIssue() changes_ref = 'refs/changes/%02d/%d/' % (issue % 100, issue) RunGitSilent(['fetch', remote, changes_ref + str(local_ps)]) last_uploaded = RunGitSilent(['rev-parse', 'FETCH_HEAD']).strip() RunGitSilent(['fetch', remote, changes_ref + str(external_ps)]) latest_external = RunGitSilent(['rev-parse', 'FETCH_HEAD']).strip() + + # If the commit parents are different, don't apply the diff as it very + # likely contains many more changes not relevant to this CL. + parents = RunGitSilent( + ['rev-parse', + '%s~1' % (last_uploaded), + '%s~1' % (latest_external)]).strip().split() + assert len(parents) == 2, 'Expected two parents.' + if parents[0] != parents[1]: + confirm_or_exit( + 'Can\'t apply the latest changes from Gerrit (parent mismatch ' + 'between PS).\n' + 'Continue with upload and override the latest changes?') + return + diff = RunGitSilent(['diff', '%s..%s' % (last_uploaded, latest_external)]) # Diff can be empty in the case of trivial rebases.