Ensure end of arguments marked clearly

Add '--' to end of list of arguments passed to rev-list command to
indicate end of program arguments.

If a value to be used as a commit also matches a path under the root of
a git repository, git will complain about the argument being ambiguous.
By delimiting the end of arguments and start of paths, this ensures
that any values passed are exclusively treated as commit references.

Change-Id: I6390bbdddb36ecadb8c338782ba0a9f14386590d
This commit is contained in:
Darragh Bailey
2016-01-22 15:37:14 +00:00
parent 098a5bf61b
commit 677c17aca4
2 changed files with 78 additions and 10 deletions

View File

@@ -149,7 +149,7 @@ class Searcher(GitMixin):
merge_list = list(Commit.iter_items(self.repo, revision_spec,
topo_order=True,
ancestry_path=True, merges=True))
ignore_args = []
extra_args = []
previous_import = False
for mergecommit, parent in ((mc, p)
for mc in merge_list
@@ -164,7 +164,7 @@ class Searcher(GitMixin):
Adding following to ignore list:
%s
""", "\n ".join(ignores))
ignore_args.extend(ignores)
extra_args.extend(ignores)
if previous_import:
self.log.info(
@@ -183,9 +183,9 @@ class Searcher(GitMixin):
previous_import = merge_list[-1]
for p in previous_import.parents:
if p.hexsha == self.commit.hexsha:
ignore_args.extend(["^%s" % ip
for ip in previous_import.parents
if ip != p])
extra_args.extend(["^%s" % ip
for ip in previous_import.parents
if ip != p])
# walk the tree and find all commits that lie in the path between the
# commit found by find() and head of the branch in two steps, to
@@ -203,6 +203,7 @@ class Searcher(GitMixin):
search_list = [(self.commit, self.branch)]
commit_list = []
extra_args.append('--')
for start, end in search_list:
revision_spec = "{0}..{1}".format(start, end)
@@ -212,13 +213,13 @@ class Searcher(GitMixin):
those behind the previous import or merged as an additional
branch during the previous import
git rev-list --topo-order %s %s
""", revision_spec, " ".join(ignore_args))
""", revision_spec, " ".join(extra_args))
commit_list.append(
Commit._iter_from_process_or_stream(
self.repo,
self.git.rev_list(revision_spec,
*ignore_args,
*extra_args,
as_process=True,
topo_order=True)))
@@ -340,6 +341,7 @@ class UpstreamMergeBaseSearcher(LogDedentMixin, Searcher):
git rev-list --min-parents=1 --no-walk \\
%s
""", (" \\\n" + " " * 8).join(rev_list_args))
rev_list_args.append("--")
search_list = set(self.git.rev_list(*rev_list_args,
min_parents=1,
no_walk=True).splitlines())
@@ -352,7 +354,8 @@ class UpstreamMergeBaseSearcher(LogDedentMixin, Searcher):
for rev in search_list:
# only root commits won't have at least one parent which have been
# excluded by the previous search
commit = self.git.rev_list(rev, parents=True, max_count=1).split()
commit = self.git.rev_list(rev, "--", parents=True,
max_count=1).split()
parents = commit[1:]
prune_list.extend(parents)
@@ -372,6 +375,7 @@ class UpstreamMergeBaseSearcher(LogDedentMixin, Searcher):
git rev-list \\
%s
""", " \\\n ".join(rev_list_args))
rev_list_args.append("--")
revsions = self.git.rev_list(*rev_list_args).splitlines()
# Running 'git merge-base' is relatively expensive to pruning the list
@@ -402,8 +406,8 @@ class UpstreamMergeBaseSearcher(LogDedentMixin, Searcher):
git rev-list --topo-order --max-count=1 --no-walk \\
%s
""", (" \\\n" + " " * 8).join(merge_bases))
sha1 = self.git.rev_list(
*merge_bases, topo_order=True, max_count=1)
args = list(merge_bases) + ["--"]
sha1 = self.git.rev_list(*args, topo_order=True, max_count=1)
# now that we have the sha1, make sure to save the commit object
self.commit = self.repo.commit(sha1)
self.log.debug("Most recent merge-base commit is: '%s'",

View File

@@ -0,0 +1,64 @@
#
# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
---
- desc: |
Construct a repo layout where using a simple layout of a single import
from upstream having been completed, test that the searcher correctly
delimits arguments and paths to the underlying git commands.
This is done by creating a file(s) with names that would match arguments
that are being passed to git, in this case a SHA1 that should be excluded
from the list of commits to process.
Repository layout being tested
B---C---F---G master
/ /
/ B1--C1 import/next
/ /
A---D---E upstream/master
tree:
- [A, []]
- [B, [A]]
- [C, [B]]
- [D, [A]]
- [E, [D]]
- [B1, [D]]
- [C1, [B1]]
- [F, [C, =C1]]
- [G, [F]]
branches:
head: [master, G]
upstream: [upstream/master, E]
expected_changes: [B1, C1, F, G]
pre-script: |
#!/bin/sh
# add a file with the same name as the SHA1 for node [C], which will
# trigger an error unless the arguments are correct delimited from
# paths when the searcher lists commits
git checkout master
touch $(git log -1 --format="%H" HEAD~2)
# add one the same name as a merge-base commit which will be included in
# a rev-list of all or the merge-bases to ensure correct ordering.
touch $(git merge-base master upstream/master)