commit 58c7866468edf2c777e3d244d5169f5d6fa5ae3a Author: n loewen Date: Wed Apr 23 21:56:44 2025 +0100 First commit diff --git a/git_time_machine.py b/git_time_machine.py new file mode 100644 index 0000000..a6aa640 --- /dev/null +++ b/git_time_machine.py @@ -0,0 +1,67 @@ +# by ChatGPT + + +import curses +import subprocess +import sys + +def get_commits(filename): + cmd = ['git', 'log', '--pretty=format:%h %ad %s', '--date=short', '--', filename] + result = subprocess.run(cmd, capture_output=True, text=True) + return result.stdout.splitlines() + +def get_file_at_commit(commit_hash, filename): + cmd = ['git', 'show', f'{commit_hash}:{filename}'] + result = subprocess.run(cmd, capture_output=True, text=True) + return result.stdout.splitlines() + +def main(stdscr, filename): + curses.curs_set(0) + stdscr.keypad(True) + + commits = get_commits(filename) + selected = 0 + + while True: + stdscr.clear() + height, width = stdscr.getmaxyx() + mid = width // 2 + + # Draw commit list on the left + for i, line in enumerate(commits): + if i >= height: + break + if i == selected: + stdscr.attron(curses.A_REVERSE) + stdscr.addnstr(i, 0, line, mid - 1) + if i == selected: + stdscr.attroff(curses.A_REVERSE) + + # Show file content on the right + if commits: + commit_hash = commits[selected].split()[0] + file_lines = get_file_at_commit(commit_hash, filename) + for i, line in enumerate(file_lines): + if i >= height: + break + stdscr.addnstr(i, mid + 1, line, width - mid - 2) + + stdscr.refresh() + + key = stdscr.getch() + if key in [ord('q'), 27]: # q or ESC to quit + break + elif key in [curses.KEY_DOWN, ord('j')]: + if selected < len(commits) - 1: + selected += 1 + elif key in [curses.KEY_UP, ord('k')]: + if selected > 0: + selected -= 1 + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python git_time_machine.py path/to/file") + sys.exit(1) + filename = sys.argv[1] + curses.wrapper(main, filename) +