ref: 738c1ea8ac43ffcb5589ad1fe749b8f13fc4a652
dir: /repack.c/
#include <u.h> #include <libc.h> #include "git.h" #define TMPPATH(suff) (".git/objects/pack/repack."suff) int cleanup(Hash h) { char newpfx[42], dpath[256], fpath[256]; int i, j, nd; Dir *d; snprint(newpfx, sizeof(newpfx), "%H.", h); for(i = 0; i < 256; i++){ snprint(dpath, sizeof(dpath), ".git/objects/%02x", i); if((nd = slurpdir(dpath, &d)) == -1) continue; for(j = 0; j < nd; j++){ snprint(fpath, sizeof(fpath), ".git/objects/%02x/%s", i, d[j].name); remove(fpath); } remove(dpath); free(d); } snprint(dpath, sizeof(dpath), ".git/objects/pack"); if((nd = slurpdir(dpath, &d)) == -1) return -1; for(i = 0; i < nd; i++){ if(strncmp(d[i].name, newpfx, strlen(newpfx)) == 0) continue; snprint(fpath, sizeof(fpath), ".git/objects/pack/%s", d[i].name); remove(fpath); } return 0; } void usage(void) { fprint(2, "usage: %s [-d]\n", argv0); exits("usage"); } void main(int argc, char **argv) { char path[128], **names; int fd, nobj, nrefs; Hash *refs, h; Object **obj; Dir rn; ARGBEGIN{ case 'd': chattygit++; break; default: usage(); }ARGEND; gitinit(); refs = nil; if((nrefs = listrefs(&refs, &names)) == -1) sysfatal("load refs: %r"); if(findtwixt(refs, nrefs, nil, 0, &obj, &nobj) == -1) sysfatal("load twixt: %r"); if((fd = create(TMPPATH("pack.tmp"), OWRITE, 0644)) == -1) sysfatal("open %s: %r", TMPPATH("pack.tmp")); if(writepack(fd, obj, nobj, &h) == -1) sysfatal("writepack: %r"); free(obj); if(indexpack(TMPPATH("pack.tmp"), TMPPATH("idx.tmp"), h) == -1) sysfatal("indexpack: %r"); close(fd); nulldir(&rn); rn.name = path; snprint(path, sizeof(path), "%H.pack", h); if(dirwstat(TMPPATH("pack.tmp"), &rn) == -1) sysfatal("rename pack: %r"); snprint(path, sizeof(path), "%H.idx", h); if(dirwstat(TMPPATH("idx.tmp"), &rn) == -1) sysfatal("rename pack: %r"); if(cleanup(h) == -1) sysfatal("cleanup: %r"); exits(nil); }