Git-basis is a perl script that remembers bases for use by git-bundle. This script shouldn't be needed because git-push and git-remote should do this kind of work. Unfortunately they currently don't so some might find this script useful. Signed-off-by: Adam Brewster <asb@xxxxxx> --- contrib/basis/git-basis.perl | 77 ++++++++++++++++++++++++++++++++++++ contrib/basis/git-basis.txt | 90 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 0 deletions(-) create mode 100755 contrib/basis/git-basis.perl create mode 100644 contrib/basis/git-basis.txt diff --git a/contrib/basis/git-basis.perl b/contrib/basis/git-basis.perl new file mode 100755 index 0000000..b3e753f --- /dev/null +++ b/contrib/basis/git-basis.perl @@ -0,0 +1,77 @@ +#!/usr/bin/perl + +use strict; + +use Git; + +require Time::Local; +my $git_epoch = Time::Local::timegm(0, 0, 0, 1, 0, 70); + +my $r = Git->repository(); +my $d = $r->repo_path(); + +if ( ! -d "$d/bases" ) { + mkdir("$d/bases") || die "Could not create $d/bases: $!"; +} + +if ( $#ARGV == -1 || ($#ARGV == 0 && $ARGV[0] eq '--update') ) { + print STDERR "usage: git-basis [--update] basis1...\n"; + exit; +} elsif ( $ARGV[0] eq '--update' ) { + shift @ARGV; + + my %new = (); + while (<STDIN>) { + if (!/^^?([a-z0-9]{40})/) {next;} + $new{$1} = 1; + } + + foreach my $f (@ARGV) { + my %these = (); + my $fh; + + open $fh, "+<$d/bases/$f" || die "Can't open bases/$f: $!"; + while (<$fh>) { + if (!/^([a-z0-9]{40})/) {next;} + $these{$1} = 1; + } + + print $fh "# ", gmtime() - $git_epoch, + " +0000 // ", scalar(localtime()), "\n"; + + foreach my $b (keys %new) { + if (exists($these{$b})) {next;} + print $fh "$b\n"; + } + close $fh; + } +} else { + my $n = 0; + my %basis = (); + + my $f = shift @ARGV; + open F, "<$d/bases/$f" || die "Can't open bases/$f: $!"; + while (<F>) { + if (!/^([a-z0-9]{40})/) {next;} + $basis{$1} = $n; + } + close F; + + foreach $f (@ARGV) { + open F, "<$d/bases/$f" || die "Can't open bases/$f: $!"; + while (<F>) { + if (!/^([a-z0-9]{40})/) {next;} + if (!exists($basis{$1})) {next;} + + if ($basis{$1} == $n) {$basis{$1}++;} + else {delete $basis{$1};} + } + close F; + $n++; + } + + foreach my $b (keys %basis) { + if ( $basis{$b} != $n ) {next;} + print "^$b\n"; + } +} diff --git a/contrib/basis/git-basis.txt b/contrib/basis/git-basis.txt new file mode 100644 index 0000000..97cfc20 --- /dev/null +++ b/contrib/basis/git-basis.txt @@ -0,0 +1,90 @@ +git-basis(1) +============ + +NAME +---- +git-basis - Track sets of references available on remote systems (bases) + +SYNOPSIS +-------- +[verse] +'git-basis' <basis> [<basis>...] +'git-basis' --update <basis> [<basis>...] < <object list or bundle> + +DESCRIPTION +----------- +Maintains lists of objects that are known to be accessible on remote +computer systems that are not accessible by network. + +OPTIONS +------- + +basis:: + List of bases to operate on. Any valid filename can be + the name of a basis. Bases that do not exist are taken + to be empty. + +--update:: + Tells git-basis to read a list of objects from stdin and + add them to each of the given bases. git-basis produces + no output when this option is given. Bases will be created + if necessary. + +object list or bundle:: + Git-basis --update reads object names, one per line from stdin. + Leading caret ("^") characters are ignored, as is anything + after the object name. Lines that don't begin with an object + name are ignored. The output of linkgit:git-ls-remote[1] or a + bundle created by linkgit:git-bundle[1] are both suitable input. + +DISCUSSION +---------- +git-basis is probably only useful with linkgit:git-bundle[1]. + +To create a bundle that excludes all objects that are part of my-basis, +use + +git-basis my-basis | git-bundle create my-bundle --all --stdin + +To add the objects in my-bundle to my-basis, use + +git-basis --update my-basis < my-bundle + +DETAILS +------- +Bases are stored as plain text files under .git/bases/. One object +entry per line. + +git-basis without --update reads all of the basis names given on the +command line, and outputs the intersection of them to stdout, with each +object prefixed by "^". + +git-basis --update reads object names from stdin, and adds all of the +references to each of the bases listed. Duplicate references will not +be listed twice, but otherwise redundant information will be included. +Each update is prefixed by a line with the current date. + +BUGS +---- +Git-baisis has no undo function. Once an object is added to a basis, +it will stay there forever. If you need to remove objects from a basis, +use a text editor to alter the file .git/bases/<basis name>. + +Git-basis --update does not remove redundant information from bases. +(Having an object implies that it's parents are also available.) This +is done intentionally to make sure git-basis --update is +non-destructive. + +Bug reports are welcome, and patches are encouraged. + +SEE ALSO +-------- +linkgit:git-bundle[1] + +AUTHOR +------ +Written by Adam Brewster <asb@xxxxxx> + +GIT +--- +Part of the linkgit:git[1] suite -- 1.5.5.1.211.g65ea3.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html