Created
October 3, 2022 08:24
-
-
Save orip/a4d4e77c57ddf3fb6ec2114ba7d3358e to your computer and use it in GitHub Desktop.
Simple git worktree filters in Python. Sample usage: `cd $(worktrees.py ~/myrepo max_path)`
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 argparse | |
import os | |
import subprocess | |
import sys | |
from dataclasses import dataclass | |
@dataclass | |
class WorktreeInfo: | |
bools: set | |
attrs: dict | |
def is_(self, label): | |
return label in self.bools | |
def get(self, label): | |
return self.attrs.get(label) | |
@property | |
def path(self): | |
return self.get("worktree") | |
@property | |
def is_bare(self): | |
return self.is_("bare") | |
@property | |
def head(self): | |
return self.get("HEAD") | |
@staticmethod | |
def create(lines): | |
assert lines | |
bools = set() | |
attrs = dict() | |
for line in lines: | |
line = line.decode("utf-8") | |
if " " in line: | |
label, value = line.split(maxsplit=1) | |
attrs[label] = value | |
else: | |
bools.add(line) | |
return WorktreeInfo(bools=bools, attrs=attrs) | |
def get_worktrees(git_dir): | |
result = subprocess.run( | |
["git", "worktree", "list", "--porcelain", "-z"], | |
cwd=git_dir, | |
capture_output=True, | |
) | |
return ( | |
WorktreeInfo.create(blob.split(bytes(1))) | |
for blob in result.stdout.rstrip(bytes(1)).split(bytes(2)) | |
) | |
def max_worktree(git_dir): | |
"sort by last path element" | |
return max( | |
(x for x in get_worktrees(git_dir) if not x.is_bare), | |
key=lambda x: float(x.path.split("/")[-1]), | |
) | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument("git_dir") | |
parser.add_argument("filter", choices=["max_path"]) | |
args = parser.parse_args() | |
if args.filter == "max_path": | |
path = max_worktree(args.git_dir).path | |
# support relative worktree paths | |
print(os.path.join(args.git_dir, path) if path.startswith(".") else path) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment