cmd/gitcheckup.py

92 lines
2.8 KiB
Python

import os
import subprocess
import sys
from voussoirkit import winwhich
GIT = winwhich.which('git')
# https://git-scm.com/docs/git-status#_short_format
# Here is an example of typical `git status --short` output:
#
# M file1
# D file2
# A file4
# ?? file3
# Here is an example of typical `git log -1 --decorate` output:
#
# commit f8fddd0de4283a251a8beb35493bd1bd3a4c925a (HEAD -> master)
# Author: My Name <mymail@example.net>
# Date: Sat Jan 11 01:59:07 2020 -0800
#
# I made some changes.
def checkup_committed(directory):
os.chdir(directory)
command = [GIT, 'status', '--short', '--untracked-files=all']
output = subprocess.check_output(command, stderr=subprocess.STDOUT)
added = 0
modified = 0
deleted = 0
for line in output.splitlines():
status = line.split()[0].strip().decode('ascii')
# These are ifs instead of elifs because you might have a file that is
# added in the index but deleted on disk, etc. Anyway these numbers
# don't need to be super accurate, just enough to remind you to commit.
if {'A', '?'}.intersection(status):
added += 1
if {'M', 'R', '!'}.intersection(status):
modified += 1
if {'D'}.intersection(status):
deleted += 1
if (added, modified, deleted) == (0, 0, 0):
committed = True
details = ''
else:
committed = False
details = f'+{added}, -{deleted}, ~{modified}'
return (committed, details)
def checkup_pushed(directory):
os.chdir(directory)
command = [GIT, 'log', '-1', '--decorate']
output = subprocess.check_output(command, stderr=subprocess.STDOUT)
headline = output.splitlines()[0]
refs = headline.split(b'(')[-1].split(b')')[0]
return any (b'/' in ref for ref in refs.split(b','))
def checkup(directory):
(committed, details) = checkup_committed(directory)
pushed = checkup_pushed(directory)
return {'committed': committed, 'pushed': pushed, 'details': details}
def main(argv):
directories_file = os.path.join(os.path.dirname(__file__), 'gitcheckup.txt')
try:
handle = open(directories_file, 'r')
except FileNotFoundError:
print(f'Please put your git repo locations in {directories_file}.')
return 1
directories = handle.readlines()
handle.close()
directories = [line.strip() for line in directories]
directories = [line for line in directories if line]
for directory in directories:
result = checkup(directory)
committed = 'C' if result['committed'] else ' '
pushed = 'P' if result['pushed'] else ' '
details = result['details']
details = f' ({details})' if details else ''
print(f'[{committed}][{pushed}] {directory}{details}')
if __name__ == '__main__':
raise SystemExit(main(sys.argv[1:]))