blob: b4e9a21572bf84b08a80f1def7f9f921298fac38 [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]
25 full_sha = subprocess.check_output(cmd).decode('utf-8')
26 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 Subenderanb1866552020-03-20 14:01:14 -070036 commit_message = subprocess.check_output(cmd).decode('utf-8', errors='ignore')
37 return commit_message
38 except subprocess.CalledProcessError as e:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070039 raise type(e)('Couldnt retrieve commit in kernel path %s for sha %s'
40 % (kernel_path, sha), e.cmd) from e
41
42
43def get_upstream_commit_message(upstream_sha):
44 """Returns the commit message for a given upstream sha using git cli."""
45 upstream_absolute_path = common.get_kernel_absolute_path(common.UPSTREAM_PATH)
46 return get_commit_message(upstream_absolute_path, upstream_sha)
47
48
49def get_chrome_commit_message(chrome_sha):
50 """Returns the commit message for a given chrome sha using git cli."""
51 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
52 return get_commit_message(chrome_absolute_path, chrome_sha)
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070053
54
55def get_commit_changeid_linux_chrome(kernel_sha):
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070056 """Returns the changeid of the kernel_sha commit by parsing linux_chrome git log.
57
58 kernel_sha will be one of linux_stable or linux_chrome commits.
59 """
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070060 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
61 try:
62 cmd = ['git', '-C', chrome_absolute_path, 'log', '--format=%B', '-n', '1', kernel_sha]
63 commit_message = subprocess.check_output(cmd).decode('utf-8', errors='ignore')
64
65 m = re.findall('^Change-Id: (I[a-z0-9]{40})$', commit_message, re.M)
66
67 # Get last change-id in case chrome sha cherry-picked/reverted into new commit
68 return m[-1]
69 except subprocess.CalledProcessError as e:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070070 raise type(e)('Couldnt retrieve changeid for commit %s' % kernel_sha, e.cmd) from e
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070071 except IndexError as e:
Hirthanan Subenderand6922c32020-03-23 14:17:40 -070072 # linux_stable kernel_sha's do not have an associated ChangeID
73 return None
Hirthanan Subenderanb1866552020-03-20 14:01:14 -070074
75
76def get_last_commit_sha_linux_chrome():
77 """Retrieves the last SHA in linux_chrome repository."""
78 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
79 try:
80 cmd = ['git', '-C', chrome_absolute_path, 'rev-parse', 'HEAD']
81 last_commit = subprocess.check_output(cmd).decode('utf-8')
82 return last_commit.rstrip()
83 except subprocess.CalledProcessError as e:
84 raise type(e)('Couldnt retrieve most recent commit in linux_chrome', e.cmd) from e
85
86
87def cherry_pick_and_push_fix(fixer_upstream_sha, chromeos_branch, fix_commit_message):
88 """Cherry picks upstream commit into chrome repo."""
89 cwd = os.getcwd()
90 chrome_absolute_path = common.get_kernel_absolute_path(common.CHROMEOS_PATH)
91
92 # reset linux_chrome repo to remove local changes
93 try:
94 os.chdir(chrome_absolute_path)
95 subprocess.run(['git', 'checkout', chromeos_branch])
96 subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch])
97 subprocess.run(['git', 'cherry-pick', '-n', fixer_upstream_sha])
98 subprocess.run(['git', 'commit', '-s', '-m', fix_commit_message])
99
100 # commit has been cherry-picked and committed locally, precommit hook
101 # in git repository adds changeid to the commit message
102 last_commit = get_last_commit_sha_linux_chrome()
103 fixer_changeid = get_commit_changeid_linux_chrome(last_commit)
104
105 subprocess.run(['git', 'push', 'origin',
106 'HEAD:refs/for/%s%%t=autogenerated' % chromeos_branch])
107 subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch])
108
109 return fixer_changeid
110 except subprocess.CalledProcessError as e:
111 raise ValueError('Failed to cherrypick and push upstream fix %s on branch %s'
112 % (fixer_upstream_sha, chromeos_branch)) from e
113 finally:
114 subprocess.run(['git', 'reset', '--hard', 'origin/%s' % chromeos_branch])
115 os.chdir(cwd)