Merge "Fix order of commits from previous imports"
This commit is contained in:
commit
098a5bf61b
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
from abc import ABCMeta
|
from abc import ABCMeta
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
import itertools
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from git_upstream.lib.pygitcompat import Commit
|
from git_upstream.lib.pygitcompat import Commit
|
||||||
|
@ -78,7 +79,7 @@ class Searcher(GitMixin):
|
||||||
# included as it contributes changes to the tree.
|
# included as it contributes changes to the tree.
|
||||||
if (self.git.rev_parse("%s^{tree}" % parent) !=
|
if (self.git.rev_parse("%s^{tree}" % parent) !=
|
||||||
self.git.rev_parse("%s^{tree}" % mergecommit)):
|
self.git.rev_parse("%s^{tree}" % mergecommit)):
|
||||||
return False, []
|
return None, []
|
||||||
|
|
||||||
mergebase = self.git.merge_base(parent, self.commit,
|
mergebase = self.git.merge_base(parent, self.commit,
|
||||||
with_exceptions=False)
|
with_exceptions=False)
|
||||||
|
@ -97,7 +98,7 @@ class Searcher(GitMixin):
|
||||||
Found merge of additional branch:
|
Found merge of additional branch:
|
||||||
%s
|
%s
|
||||||
""", mergecommit)
|
""", mergecommit)
|
||||||
return False, ["^%s" % parent]
|
return None, ["^%s" % parent]
|
||||||
|
|
||||||
# otherwise we have a descendant commit with the same tree that
|
# otherwise we have a descendant commit with the same tree that
|
||||||
# requires further inspection to determine if it is really the
|
# requires further inspection to determine if it is really the
|
||||||
|
@ -110,18 +111,18 @@ class Searcher(GitMixin):
|
||||||
# the previous mainline that was replaced and should ignore
|
# the previous mainline that was replaced and should ignore
|
||||||
if mergecommit == last_merge:
|
if mergecommit == last_merge:
|
||||||
# also means we've found the previous import
|
# also means we've found the previous import
|
||||||
return True, ["^%s" % parent]
|
return mergecommit, ["^%s" % parent]
|
||||||
|
|
||||||
# otherwise this an unusual state where we are looking at the
|
# otherwise this an unusual state where we are looking at the
|
||||||
# merge of the previous import with a change that landed on the
|
# merge of the previous import with a change that landed on the
|
||||||
# previous target mainline but was not included in the changes
|
# previous target mainline but was not included in the changes
|
||||||
# that where on the previous import. This can occur due to a
|
# that where on the previous import. This can occur due to a
|
||||||
# change being approved/landed after the import was performed
|
# change being approved/landed after the import was performed
|
||||||
return False, []
|
return None, []
|
||||||
|
|
||||||
# otherwise looking at the previous import merge commit and the parent
|
# otherwise looking at the previous import merge commit and the parent
|
||||||
# from the previous import branch, so exclude all other parents.
|
# from the previous import branch, so exclude all other parents.
|
||||||
return True, ["^%s" % ip
|
return mergecommit, ["^%s" % ip
|
||||||
for ip in mergecommit.parents if ip != parent]
|
for ip in mergecommit.parents if ip != parent]
|
||||||
|
|
||||||
def list(self):
|
def list(self):
|
||||||
|
@ -179,29 +180,51 @@ class Searcher(GitMixin):
|
||||||
# an import branch and only merging the final result of upstream +
|
# an import branch and only merging the final result of upstream +
|
||||||
# local changes.
|
# local changes.
|
||||||
if merge_list and not previous_import:
|
if merge_list and not previous_import:
|
||||||
for p in merge_list[-1].parents:
|
previous_import = merge_list[-1]
|
||||||
|
for p in previous_import.parents:
|
||||||
if p.hexsha == self.commit.hexsha:
|
if p.hexsha == self.commit.hexsha:
|
||||||
ignore_args.extend(["^%s" % ip
|
ignore_args.extend(["^%s" % ip
|
||||||
for ip in merge_list[-1].parents
|
for ip in previous_import.parents
|
||||||
if ip != p])
|
if ip != p])
|
||||||
|
|
||||||
# walk the tree and find all commits that lie in the path between the
|
# walk the tree and find all commits that lie in the path between the
|
||||||
# commit found by find() and head of the branch to provide a list of
|
# commit found by find() and head of the branch in two steps, to
|
||||||
# commits to the caller
|
# ensure a deterministic order between what is from the previous
|
||||||
|
# upstream to the last import, and from that import to what is on
|
||||||
|
# the tip of the head to avoid inversion where older commits
|
||||||
|
# started before the previous import merge and approved afterwards
|
||||||
|
# are not sorted by 'rev-list' predictably.
|
||||||
|
if previous_import:
|
||||||
|
search_list = [
|
||||||
|
(previous_import, self.branch),
|
||||||
|
(self.commit, previous_import),
|
||||||
|
]
|
||||||
|
else:
|
||||||
|
search_list = [(self.commit, self.branch)]
|
||||||
|
|
||||||
|
commit_list = []
|
||||||
|
for start, end in search_list:
|
||||||
|
revision_spec = "{0}..{1}".format(start, end)
|
||||||
|
|
||||||
self.log.info(
|
self.log.info(
|
||||||
"""
|
"""
|
||||||
Walking the changes between found commit and target, excluding
|
Walking the changes between found commit and target, excluding
|
||||||
those behind the previous import or merged as an additional branch
|
those behind the previous import or merged as an additional
|
||||||
during the previous import
|
branch during the previous import
|
||||||
git rev-list --topo-order %s %s
|
git rev-list --topo-order %s %s
|
||||||
""", revision_spec, " ".join(ignore_args))
|
""", revision_spec, " ".join(ignore_args))
|
||||||
|
|
||||||
commit_list = Commit._iter_from_process_or_stream(
|
commit_list.append(
|
||||||
self.repo, self.git.rev_list(revision_spec, *ignore_args,
|
Commit._iter_from_process_or_stream(
|
||||||
as_process=True, topo_order=True))
|
self.repo,
|
||||||
|
self.git.rev_list(revision_spec,
|
||||||
|
*ignore_args,
|
||||||
|
as_process=True,
|
||||||
|
topo_order=True)))
|
||||||
|
|
||||||
# chain the filters as generators so that we don't need to allocate new
|
# chain the filters as generators so that we don't need to allocate new
|
||||||
# lists for each step in the filter chain.
|
# lists for each step in the filter chain.
|
||||||
|
commit_list = itertools.chain(*commit_list)
|
||||||
for f in self.filters:
|
for f in self.filters:
|
||||||
commit_list = f.filter(commit_list)
|
commit_list = f.filter(commit_list)
|
||||||
|
|
||||||
|
|
|
@ -60,4 +60,4 @@
|
||||||
head: [master, K]
|
head: [master, K]
|
||||||
upstream: [upstream/master, M]
|
upstream: [upstream/master, M]
|
||||||
|
|
||||||
expected_changes: [O, H, B1, C1, D1, G, I, J, K]
|
expected_changes: [B1, C1, D1, G, O, H, I, J, K]
|
||||||
|
|
|
@ -55,4 +55,4 @@
|
||||||
head: [master, K]
|
head: [master, K]
|
||||||
upstream: [upstream/master, M]
|
upstream: [upstream/master, M]
|
||||||
|
|
||||||
expected_changes: [I, B1, C1, D1, G1, H, J, K]
|
expected_changes: [B1, C1, D1, G1, H, I, J, K]
|
||||||
|
|
|
@ -59,4 +59,4 @@
|
||||||
head: [master, K]
|
head: [master, K]
|
||||||
upstream: [upstream/master, M]
|
upstream: [upstream/master, M]
|
||||||
|
|
||||||
expected_changes: [O, B1, C1, D1, J, K]
|
expected_changes: [B1, C1, D1, O, J, K]
|
||||||
|
|
Loading…
Reference in New Issue