-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgit_utils.py
92 lines (76 loc) · 2.64 KB
/
git_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import sys
import baker
from contextlib import contextmanager
from git import Repo, GitCommandError
from logbook import Logger, StreamHandler
StreamHandler(sys.stdout).push_application()
log = Logger(__name__)
@contextmanager
def base_branch(git):
"""
1. Get current branch
2. Return branch to current branch at the end
:type git: git.cmd.Git
"""
current_branch = git.rev_parse("--abbrev-ref", "HEAD")
try:
yield
finally:
git.checkout(current_branch)
def get_git_instance(working_tree_dir):
repo = Repo(working_tree_dir)
return repo.git
def get_latest_tag(working_tree_dir):
git = get_git_instance(working_tree_dir)
return git.describe()
@baker.command
def mass_cherry_pick(source_branch, working_tree_dir, *branch_list):
"""
1. Init repo specified in the working tree directory
2. Obtain required commit
3. iterate through the specified branches
4. Create new branch that combines the source branch name
5. Cherry pick commit
:type source_branch: str
:type working_tree_dir: str
:type branch_list: list
"""
git = get_git_instance(working_tree_dir)
with base_branch(git):
required_commit = get_required_commit(git, source_branch)
log.info(f"Cherry-picking commit: {required_commit}")
for branch_name in branch_list:
new_branch = f"{source_branch}_{branch_name}"
if new_branch not in git.branch().split():
log.info(f"Moving to {branch_name} and pulling...")
git.checkout(branch_name)
log.info(git.pull())
git.checkout("-b", new_branch)
log.info(f"Created new branch: {new_branch}")
git_cherry_pick(git, required_commit)
git.push("--set-upstream", "origin", new_branch)
else:
log.error(f"Branch {new_branch} already exists!")
def get_required_commit(git, source_branch):
"""
get hash of the required commit that will be cherry picked
:type git: git.cmd.Git
:type source_branch: str
"""
git.checkout(source_branch)
return git.show("-s", "--format=%H")
def git_cherry_pick(git, required_commit):
"""
Attempt to cherry pich with the specified commit. In case of error, abort
:type git: git.cmd.Git
:type required_commit: str
"""
try:
log.notice(git.cherry_pick(required_commit))
except GitCommandError as e:
for error_line in e.stderr.split('\n'):
log.error(error_line)
log.error(f"Aborting cherry picking due to errors")
git.cherry_pick("--abort")
if __name__ == '__main__':
baker.run()