Skip to content

Commit 0c97ba8

Browse files
committed
ciq-cherry-pick.py: Add option to ignore if one of the 'Fixes' commits are not in the tree
This can be useful in cases where there are multiple commits this one is trying to fix, and only one if of interest for us. Signed-off-by: Roxana Nicolescu <rnicolescu@ciq.com>
1 parent 44039bf commit 0c97ba8

2 files changed

Lines changed: 49 additions & 10 deletions

File tree

ciq-cherry-pick.py

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
CIQ_fixes_references,
1616
CIQ_get_full_hash,
1717
CIQ_original_commit_author_to_tag_string,
18+
CIQ_raise_or_warn,
1819
CIQ_reset_HEAD,
1920
CIQ_run_git,
2021
)
@@ -27,7 +28,7 @@ class CherryPickException(Exception):
2728
pass
2829

2930

30-
def check_fixes(sha):
31+
def check_fixes(sha, ignore_fixes_check):
3132
"""
3233
Checks if commit has "Fixes:" references and if so, it checks if the
3334
commit(s) that it tries to fix are part of the current branch
@@ -38,9 +39,13 @@ def check_fixes(sha):
3839
logging.warning("The commit you try to cherry pick has no Fixes: reference; review it carefully")
3940
return
4041

42+
not_present_fixes = []
4143
for fix in fixes:
4244
if not CIQ_commit_exists_in_current_branch(os.getcwd(), fix):
43-
raise RuntimeError(f"The commit you want to cherry pick references a Fixes: {fix} but this is not here")
45+
not_present_fixes.append(fix)
46+
47+
err = f"The commit you want to cherry pick has the following Fixes: references that are not part of the tree {not_present_fixes}"
48+
CIQ_raise_or_warn(cond=not_present_fixes, error_msg=err, warn=ignore_fixes_check)
4449

4550

4651
def manage_commit_message(full_sha, ciq_tags, jira_ticket, commit_successful):
@@ -85,7 +90,7 @@ def manage_commit_message(full_sha, ciq_tags, jira_ticket, commit_successful):
8590
raise RuntimeError(f"Failed to write commit message to {MERGE_MSG}: {e}") from e
8691

8792

88-
def cherry_pick(sha, ciq_tags, jira_ticket):
93+
def cherry_pick(sha, ciq_tags, jira_ticket, ignore_fixes_check):
8994
"""
9095
Cherry picks a commit and it adds the ciq standardized format
9196
In case of error (cherry pick conflict):
@@ -107,7 +112,7 @@ def cherry_pick(sha, ciq_tags, jira_ticket):
107112
except RuntimeError as e:
108113
raise RuntimeError(f"Invalid commit SHA {sha}: {e}") from e
109114

110-
check_fixes(sha=full_sha)
115+
check_fixes(sha=full_sha, ignore_fixes_check=ignore_fixes_check)
111116

112117
# Commit message is in MERGE_MSG
113118
commit_successful = True
@@ -134,7 +139,7 @@ def cherry_pick(sha, ciq_tags, jira_ticket):
134139
CIQ_run_git(repo_path=os.getcwd(), args=["commit", "-F", MERGE_MSG])
135140

136141

137-
def cherry_pick_fixes(sha, ciq_tags, jira_ticket, upstream_ref):
142+
def cherry_pick_fixes(sha, ciq_tags, jira_ticket, upstream_ref, ignore_fixes_check):
138143
"""
139144
Check upstream_ref for commits that have this reference:
140145
Fixes: <sha>. If any, these will also be cherry picked with the ciq
@@ -147,21 +152,33 @@ def cherry_pick_fixes(sha, ciq_tags, jira_ticket, upstream_ref):
147152
bf_ciq_tags = [re.sub(r"^cve ", "cve-bf ", tag.strip()) for tag in ciq_tags]
148153
for full_hash, display_str in fixes_in_mainline:
149154
print(f"Extra cherry picking {display_str}")
150-
full_cherry_pick(sha=full_hash, ciq_tags=bf_ciq_tags, jira_ticket=jira_ticket, upstream_ref=upstream_ref)
155+
full_cherry_pick(
156+
sha=full_hash,
157+
ciq_tags=bf_ciq_tags,
158+
jira_ticket=jira_ticket,
159+
upstream_ref=upstream_ref,
160+
ignore_fixes_check=ignore_fixes_check,
161+
)
151162

152163

153-
def full_cherry_pick(sha, ciq_tags, jira_ticket, upstream_ref):
164+
def full_cherry_pick(sha, ciq_tags, jira_ticket, upstream_ref, ignore_fixes_check):
154165
"""
155166
Cherry picks a commit from upstream-ref along with its Fixes: references.
156167
If cherry-pick or cherry_pick_fixes fail, the exception is propagated
157168
If one of the cherry picks fails, an exception is returned and the previous
158169
successful cherry picks are left as they are.
159170
"""
160171
# Cherry pick the commit
161-
cherry_pick(sha=sha, ciq_tags=ciq_tags, jira_ticket=jira_ticket)
172+
cherry_pick(sha=sha, ciq_tags=ciq_tags, jira_ticket=jira_ticket, ignore_fixes_check=ignore_fixes_check)
162173

163174
# Cherry pick the fixed-by dependencies
164-
cherry_pick_fixes(sha=sha, ciq_tags=ciq_tags, jira_ticket=jira_ticket, upstream_ref=upstream_ref)
175+
cherry_pick_fixes(
176+
sha=sha,
177+
ciq_tags=ciq_tags,
178+
jira_ticket=jira_ticket,
179+
upstream_ref=upstream_ref,
180+
ignore_fixes_check=ignore_fixes_check,
181+
)
165182

166183

167184
if __name__ == "__main__":
@@ -185,6 +202,11 @@ def full_cherry_pick(sha, ciq_tags, jira_ticket, upstream_ref):
185202
default="origin/kernel-mainline",
186203
help="Reference to upstream mainline branch (default: origin/kernel-mainline)",
187204
)
205+
parser.add_argument(
206+
"--ignore-fixes-check",
207+
action="store_true",
208+
help="Continue even if the commit(s) referenced in Fixes: tags are not present in the current branch",
209+
)
188210

189211
args = parser.parse_args()
190212

@@ -203,7 +225,13 @@ def full_cherry_pick(sha, ciq_tags, jira_ticket, upstream_ref):
203225
tags = args.ciq_tag.split(",")
204226

205227
try:
206-
full_cherry_pick(sha=args.sha, ciq_tags=tags, jira_ticket=args.ticket, upstream_ref=args.upstream_ref)
228+
full_cherry_pick(
229+
sha=args.sha,
230+
ciq_tags=tags,
231+
jira_ticket=args.ticket,
232+
upstream_ref=args.upstream_ref,
233+
ignore_fixes_check=args.ignore_fixes_check,
234+
)
207235
except CherryPickException as e:
208236
logging.error(e)
209237
sys.exit(1)

ciq_helpers.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
# CIQ Kernel Tools function library
55

6+
import logging
67
import os
78
import re
89
import subprocess
@@ -309,6 +310,16 @@ def CIQ_reset_HEAD(repo):
309310
return CIQ_run_git(repo_path=repo, args=["reset", "--hard", "HEAD"])
310311

311312

313+
def CIQ_raise_or_warn(cond, error_msg, warn):
314+
if not cond:
315+
return
316+
317+
if not warn:
318+
raise RuntimeError(error_msg)
319+
320+
logging.warning(error_msg)
321+
322+
312323
def repo_init(repo):
313324
"""Initialize a git repo object.
314325

0 commit comments

Comments
 (0)