Created
April 3, 2019 14:08
-
-
Save madprog/c3c766318577cd99f6497a9769fbb2fa to your computer and use it in GitHub Desktop.
Utility script which insert branch creation commands in a git rebase-TODO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import os | |
import re | |
import subprocess as sp | |
import sys | |
def find_git_folder(): | |
parts = os.getcwd().split(os.path.sep) | |
parts[0] = '/' # instead of '' | |
while len(parts) > 0: | |
p = os.path.join(*parts, '.git') | |
if os.path.exists(p): | |
return p | |
parts.pop() | |
raise RuntimeError(f'Unable to find a git folder in {os.getcwd()!r} ' | |
'or one of its parents') | |
def main(args): | |
git_folder = find_git_folder() | |
rebase_todo_path = f'{git_folder}/rebase-merge/git-rebase-todo' | |
if not os.path.exists(rebase_todo_path): | |
raise RuntimeError('Unable to find git rebase TODO ' | |
f'at {rebase_todo_path!r}. No rebase in progress?') | |
git_branches = sp.Popen(['git', '-C', git_folder, 'branch', '-v'], | |
stdout=sp.PIPE, stderr=sp.PIPE) | |
out, err = git_branches.communicate() | |
if git_branches.returncode != 0: | |
raise RuntimeError(err.decode('utf-8')) | |
branches = {} | |
for m in re.finditer(r'^[* ] ([^ ]+) +([0-9a-f]*) ', out.decode('utf-8'), | |
re.MULTILINE): | |
branches[m.group(2)] = m.group(1) | |
with open(rebase_todo_path, 'r') as fp: | |
rebase_todo = fp.readlines() | |
new_todo = [] | |
line_expr = re.compile(r'^(?P<cmd>p|r|e|s|f|x|b|d|l|t|m|pick|reword|edit|' | |
r'squash|fixup|exec|break|drop|label|reset|merge) ' | |
r'(?P<hash>[0-9a-f]{7})') | |
append_cmd = None | |
for line in rebase_todo: | |
m = line_expr.match(line) | |
if m: | |
if append_cmd is not None: | |
new_todo.append(append_cmd) | |
append_cmd = None | |
hash = m.group('hash') | |
if hash in branches: | |
append_cmd = f'exec git branch -f {branches[hash]} HEAD\n' | |
new_todo.append(line) | |
# Last append_cmd is not added because the branch will be moved by git-rebase | |
# If we move it ourselves, git-rebase will be lost and will fail | |
with open(rebase_todo_path, 'w') as fp: | |
fp.write(''.join(new_todo)) | |
if __name__ == '__main__': | |
try: | |
main(sys.argv[1:]) | |
except Exception as e: | |
print(e, file=sys.stderr) | |
sys.exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment