blob: 5b86f0ccc013478781bf113cdab036a48bc766e2 [file] [log] [blame]
Hirthanan Subenderanb1866552020-03-20 14:01:14 -07001#!/usr/bin/env python3
2# -*- coding: utf-8 -*-"
3#
4# Copyright 2020 The Chromium OS Authors. All rights reserved.
5# Use of this source code is governed by a BSD-style license that can be
6# found in the LICENSE file.
7
8"""Module containing methods interfacing with git
9
10i.e Parsing git logs for change-id, full commit sha's, etc.
11"""
12
13from __future__ import print_function
14import os
15import re
16import subprocess
17import common
18
19
20def get_upstream_fullsha(abbrev_sha):
21 """Returns the full upstream sha for an abbreviated 12 digit sha using git cli"""
22 upstream_absolute_path = common.get_kernel_absolute_path(common.UPSTREAM_PATH)
23 try:
24 cmd = ['git', '-C', upstream_absolute_path, 'rev-parse', abbrev_sha]
Hirthanan Subenderanaffcc4a2020-03-25 14:42:33 -070025 full_sha = subprocess.check_output(cmd, encoding='utf-8')
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070026 return full_sha.rstrip()
27 except subprocess.CalledProcessError as e:
28 raise type(e)('Could not find full upstream sha for %s' % abbrev_sha, e.cmd) from e
29
30
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070031def get_commit_message(kernel_path, sha):
32 """Returns the commit message for a sha in a given local path to kernel."""
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070033 try:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070034 cmd = ['git', '-C', kernel_path, 'log',
35 '--format=%B', '-n', '1', sha]
Hirthanan Subenderanaffcc4a2020-03-25 14:42:33 -070036 commit_message = subprocess.check_output(cmd, encoding='utf-8', errors='ignore')
Hirthanan Subenderan3450f512020-04-09 22:36:50 -070037
38 # Single newline following commit message
39 return commit_message.rstrip() + '\n'
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070040 except subprocess.CalledProcessError as e:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070041 raise type(e)('Couldnt retrieve commit in kernel path %s for sha %s'
42 % (kernel_path, sha), e.cmd) from e
43
44
45def get_upstream_commit_message(upstream_sha):
46 """Returns the commit message for a given upstream sha using git cli."""
47 upstream_absolute_path = common.get_kernel_absolute_path(common.UPSTREAM_PATH)
48 return get_commit_message(upstream_absolute_path, upstream_sha)
49
50
51def get_chrome_commit_message(chrome_sha):
52 """Returns the commit message for a given chrome sha using git cli."""
53 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
54 return get_commit_message(chrome_absolute_path, chrome_sha)
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070055
56
57def get_commit_changeid_linux_chrome(kernel_sha):
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070058 """Returns the changeid of the kernel_sha commit by parsing linux_chrome git log.
59
60 kernel_sha will be one of linux_stable or linux_chrome commits.
61 """
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070062 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
63 try:
64 cmd = ['git', '-C', chrome_absolute_path, 'log', '--format=%B', '-n', '1', kernel_sha]
Hirthanan Subenderanaffcc4a2020-03-25 14:42:33 -070065 commit_message = subprocess.check_output(cmd, encoding='utf-8', errors='ignore')
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070066
67 m = re.findall('^Change-Id: (I[a-z0-9]{40})$', commit_message, re.M)
68
69 # Get last change-id in case chrome sha cherry-picked/reverted into new commit
70 return m[-1]
71 except subprocess.CalledProcessError as e:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070072 raise type(e)('Couldnt retrieve changeid for commit %s' % kernel_sha, e.cmd) from e
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070073 except IndexError as e:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070074 # linux_stable kernel_sha's do not have an associated ChangeID
75 return None
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070076
77
78def get_last_commit_sha_linux_chrome():
79 """Retrieves the last SHA in linux_chrome repository."""
80 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
81 try:
82 cmd = ['git', '-C', chrome_absolute_path, 'rev-parse', 'HEAD']
Hirthanan Subenderanaffcc4a2020-03-25 14:42:33 -070083 last_commit = subprocess.check_output(cmd, encoding='utf-8')
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070084 return last_commit.rstrip()
85 except subprocess.CalledProcessError as e:
86 raise type(e)('Couldnt retrieve most recent commit in linux_chrome', e.cmd) from e
87
88
Hirthanan Subenderanbbafac42020-04-10 16:18:16 -070089def get_git_push_cmd(chromeos_branch, reviewers):
90 """Generates git push command with added reviewers and autogenerated tag.
91
92 Read more about gerrit tags here:
93 https://gerrit-review.googlesource.com/Documentation/cmd-receive-pack.html
94 """
95 git_push_head = 'git push origin HEAD:refs/for/%s' % chromeos_branch
96 reviewers_tag = ['r=%s'% r for r in reviewers]
97 autogenerated_tag = ['t=autogenerated']
98 tags = ','.join(reviewers_tag + autogenerated_tag)
99 return git_push_head + '%' + tags
100
101
102def cherry_pick_and_push_fix(fixer_upstream_sha, chromeos_branch,
103 fix_commit_message, reviewers):
104 """Cherry picks upstream commit into chrome repo.
105
106 Adds reviewers and autogenerated tag with the pushed commit.
107 """
Hirthanan Subenderanb1866552020-03-20 14:01:14 -0700108 cwd = os.getcwd()
109 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
110
111 # reset linux_chrome repo to remove local changes
112 try:
113 os.chdir(chrome_absolute_path)
Hirthanan Subenderanbbafac42020-04-10 16:18:16 -0700114 subprocess.run(['git', 'checkout', chromeos_branch], check=True)
115 subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch], check=True)
116 subprocess.run(['git', 'cherry-pick', '-n', fixer_upstream_sha], check=True)
117 subprocess.run(['git', 'commit', '-s', '-m', fix_commit_message], check=True)
Hirthanan Subenderanb1866552020-03-20 14:01:14 -0700118
119 # commit has been cherry-picked and committed locally, precommit hook
120 # in git repository adds changeid to the commit message
121 last_commit = get_last_commit_sha_linux_chrome()
122 fixer_changeid = get_commit_changeid_linux_chrome(last_commit)
123
Hirthanan Subenderanbbafac42020-04-10 16:18:16 -0700124 git_push_cmd = get_git_push_cmd(chromeos_branch, reviewers)
125 subprocess.run(git_push_cmd.split(' '), check=True)
126 subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch], check=True)
Hirthanan Subenderanb1866552020-03-20 14:01:14 -0700127
128 return fixer_changeid
129 except subprocess.CalledProcessError as e:
130 raise ValueError('Failed to cherrypick and push upstream fix %s on branch %s'
131 % (fixer_upstream_sha, chromeos_branch)) from e
132 finally:
Hirthanan Subenderan41ac0822020-04-07 21:29:31 -0700133 subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch], check=True)
Hirthanan Subenderanb1866552020-03-20 14:01:14 -0700134 os.chdir(cwd)