| 1 |
#!/usr/bin/env python |
| 2 |
# vim: et |
| 3 |
|
| 4 |
from __future__ import with_statement |
| 5 |
|
| 6 |
import os |
| 7 |
import sys |
| 8 |
import commands |
| 9 |
import exceptions |
| 10 |
|
| 11 |
def nearest_git_objects(path): |
| 12 |
dotgit = os.path.join(path, ".git") |
| 13 |
objects = os.path.join(path, "objects") |
| 14 |
if os.path.isdir(dotgit): |
| 15 |
return nearest_git_objects(dotgit) |
| 16 |
elif os.path.isdir(objects): |
| 17 |
return objects |
| 18 |
raise exceptions.RuntimeError("Could not find git dir from " + path) |
| 19 |
|
| 20 |
def alt_path(git_path): |
| 21 |
return os.path.join(git_path, "info", "alternates") |
| 22 |
|
| 23 |
def read_objs(git_path): |
| 24 |
fn = alt_path(git_path) |
| 25 |
alts = set() |
| 26 |
if os.path.exists(fn): |
| 27 |
with open(fn) as f: |
| 28 |
alts = set([l.strip() for l in f.readlines()]) |
| 29 |
|
| 30 |
return alts |
| 31 |
|
| 32 |
def setup_alternates(from_objects, to_objects): |
| 33 |
alts = read_objs(from_objects) |
| 34 |
alts.add(to_objects) |
| 35 |
with open(alt_path(from_objects), "w") as f: |
| 36 |
f.write("\n".join(alts) + "\n") |
| 37 |
|
| 38 |
def here(): |
| 39 |
(e, o) = commands.getstatusoutput("git rev-parse --git-dir") |
| 40 |
if e != 0: |
| 41 |
raise exceptions.RuntimeError("This is not a git repo.") |
| 42 |
return nearest_git_objects(o.strip()) |
| 43 |
|
| 44 |
def setup_new_alternate(where): |
| 45 |
alt = nearest_git_objects(where) |
| 46 |
loc = here() |
| 47 |
print loc, "->", alt |
| 48 |
setup_alternates(loc, alt) |
| 49 |
|
| 50 |
def display_alternates(): |
| 51 |
p = here() |
| 52 |
alts = read_objs(p) |
| 53 |
print "Alternates for %s (%d):" % (p, len(alts)) |
| 54 |
for s in sorted(alts): |
| 55 |
print " %s" % s |
| 56 |
|
| 57 |
if __name__ == '__main__': |
| 58 |
if len(sys.argv) < 2: |
| 59 |
display_alternates() |
| 60 |
else: |
| 61 |
setup_new_alternate(sys.argv[1]) |