Last active
August 10, 2022 09:50
-
-
Save ShadyRover/f1b64cddbaadb4563daca952bdc38389 to your computer and use it in GitHub Desktop.
Python script that finds branches with the latest commit older than a given date
This file contains hidden or 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 | |
# Using: | |
# Run script with parameters | |
# pip3 install gitpython | |
# chmod +x git-tool.py | |
# ./git-tool.py check -d "01/01/2021" -p "/Users/path_to_git_repo" | |
# ./git-tool.py delete -d "/Users/path_to_git_repo" | |
import datetime | |
import sys | |
from pathlib import Path | |
import git | |
import calendar | |
import time | |
import argparse | |
def _print_old_branches(args): | |
print(args.repo_path) | |
repo = git.Repo(args.repo_path) | |
assert not repo.bare | |
current_time = time.gmtime() | |
ts = calendar.timegm(current_time) | |
print("Current timestamp:", ts) | |
target_time = int(datetime.datetime.strptime(args.target_date, '%d/%m/%Y').strftime("%s")) | |
print(target_time) | |
text = "" | |
for repo_branch in repo.references: | |
if repo_branch.commit.committed_date <= target_time: | |
try: | |
print("Branch %s" % repo_branch.remote_head) | |
text += "origin/" + repo_branch.remote_head + "\n" | |
# print("commit date %s " % repo_branch.commit.committed_date) | |
except Exception: | |
pass | |
with open('branches.txt', 'w') as fp: | |
fp.write(text) | |
print("Done!") | |
def _delete_remote_branches(args): | |
if not query_yes_no( | |
'This action will remove all branches on ORIGIN listed in branches.txt. Are you sure?'.format(args.file)): | |
sys.exit(1) | |
counter = 0 | |
ignored_count = 0 | |
repo = git.Repo(args.repo_path) # Repo object set to cloned repo | |
assert not repo.bare # Make sure repo isn't empty | |
remote = repo.remote() # Set to a remote object (Defaults to 'origin') can override with name=... | |
with open('branches.txt', 'r') as f: | |
branches = f.read().splitlines() | |
for repo_branch in repo.references: # loop over the remote branches | |
for branch in branches: | |
# print("%s" % repo_branch.name) | |
if branch == repo_branch.name: # does the branch you want to delete exist in the remote git repo? | |
try: | |
print("deleting remote branch: %s" % repo_branch.remote_head) | |
print("deleted") | |
# remote.push(refspec=( | |
# ":%s" % repo_branch.remote_head)) | |
counter += 1 | |
except Exception: | |
ignored_count += 1 | |
print("can't delete branch %s" % repo_branch.remote_head) | |
print("%s branches removed" % counter) | |
print("%s branches ignored" % ignored_count) | |
def query_yes_no(question, default="yes"): | |
valid = {"yes": True, "y": True, "ye": True, | |
"no": False, "n": False} | |
if default is None: | |
prompt = " [y/n] " | |
elif default == "yes": | |
prompt = " [Y/n] " | |
elif default == "no": | |
prompt = " [y/N] " | |
else: | |
raise ValueError("invalid default answer: '%s'" % default) | |
while True: | |
sys.stdout.write(question + prompt) | |
choice = input().lower() | |
if default is not None and choice == '': | |
return valid[default] | |
elif choice in valid: | |
return valid[choice] | |
else: | |
sys.stdout.write("Please respond with 'yes' or 'no' " | |
"(or 'y' or 'n').\n") | |
def main(): | |
print(Path().absolute()) | |
parser = argparse.ArgumentParser(description='Git tool') | |
subparsers = parser.add_subparsers(title='Actions', description='Git tool actions', help='actions') | |
check_parser = subparsers.add_parser('check') | |
check_parser.set_defaults(func=_print_old_branches) | |
check_parser.add_argument('-ir', '--ignore-release', dest='ignore_release', help='Ignore release branches', | |
default='false') | |
check_parser.add_argument('-d', '--date', dest='target_date', help='Get branches older than date', | |
default='false') | |
check_parser.add_argument('-p', '--path', dest='repo_path', help='Path to git repository', | |
default=Path().absolute()) | |
delete_parser = subparsers.add_parser('delete') | |
delete_parser.set_defaults(func=_delete_remote_branches) | |
delete_parser.add_argument('-p', '--path', dest='repo_path', help='Path to git repository', | |
default=Path().absolute()) | |
args = parser.parse_args() | |
args.func(args) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment