git-tidy-python/git-tidy
2023-01-26 07:43:08 +02:00

105 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python
# git-tidy is free software: you can redistribute it and/or modify it under the terms of the GNU
# General Public License as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
# git-tidy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
# You should have received a copy of the GNU General Public License along with git-tidy. If not, see
# <https://www.gnu.org/licenses/>.
import subprocess
import sys
common_default_branches = [
"main",
"master",
"devel",
"dev",
]
# Check whether we're actually in a git repo before doing anything else.
# TODO: Rename this function to something more obvious.
def get_status():
git_status = subprocess.run(
["git", "status"],
capture_output=True, # we don't want to show the user everything
)
if git_status.returncode == 0:
return True
print(git_status.stderr.decode())
return False
def get_default_branch() -> str:
# Try to see if there's a configuration already.
sp = subprocess.run(["git", "config", "--get", "tidy.defaultbranch"], capture_output=True)
if sp.returncode != 0:
print("No default branch for git-tidy configured, will try to figure out which to use...")
candidates = []
branch_list = [
branch.strip()
for branch in subprocess.run(["git", "branch", "--list"], capture_output=True).stdout.decode().split("\n")
if len(branch)
]
# Check whether any branches match our list of common defaults.
for branch in branch_list:
# Remove the asterisk in front of the active branch name.
if branch[0] == "*":
branch = branch[2:]
if branch in common_default_branches:
candidates.append(branch)
if len(candidates) == 1:
# Only one branch name matches, so we'll go with that one.
subprocess.run(["git", "config", "--add", "tidy.defaultbranch", candidates[0]])
return candidates[0]
# TODO: Handle the zero case.
# If we don't have one or zero, which do we have?
selection = -1
while (selection < 0) or (selection >= len(candidates)):
print(
f"{'Several' if len(candidates) > 1 else 'No'} potential default branch candidates found. Please select one:"
)
for n, candidate in enumerate(candidates):
print(f"{n}: {candidate}")
# TODO: This breaks if the user is stupid and doesn't input an int.
selection = int(input("Which to choose?"))
return candidates[selection]
# TODO: Might be nice to have a sanity-check that the configured branch is in fact actually on the list. It may just be easiest to do this by trying to switch to it.
return sp.stdout.decode()
if __name__ == "__main__":
if not get_status():
exit()
default_branch = get_default_branch()
print(f"Switching to {default_branch}")
# Checkout the default branch.
subprocess.run(["git", "switch", default_branch])
subprocess.run(["git", "pull"]) # Make sure it's the most up-to-date version.
# Check which branches are `--merged` and delete them.
merged_branch_output = subprocess.run(["git", "branch", "--merged"], capture_output=True)
merged_branches = [
branch for branch in merged_branch_output.stdout.decode().split("\n") if len(branch)
] # Remove zero-length elements.
for branch in merged_branches:
if branch[0] != "*":
subprocess.run(["git", "branch", "-d", branch.strip()])
# Clear up dangling references to remote branches which are no longer.
subprocess.run(["git", "fetch", "--all", "-p"])