From: "Adam Brewster" <adam@adambrewster.com>
To: git@vger.kernel.org
Subject: [PATCH/RFC] Created git-basis and modified git-bundle to accept --stdin.
Date: Mon, 23 Jun 2008 22:21:44 -0400 [thread overview]
Message-ID: <c376da900806231921y2d822been9cd573d509fbf78a@mail.gmail.com> (raw)
In-Reply-To: <1214273297-8257-2-git-send-email-adambrewster@gmail.com>
Git-basis is a perl script that remembers bases for use by git-bundle.
Code from rev-parse was borrowed to allow git-bundle to handle --stdin.
Signed-off-by: Adam Brewster <adambrewster@gmail.com>
---
Git-bundle is a great tool to move repositories between computers on
different networks, but in order to create thin packs, it needs to be
given a list of objects that are available on the remote end. I don't
like any of the options listed in the git-bundle documentation, so I did
this.
Git-basis is a script that maintains lists of objects that exist in
various places.
With this patch, the command:
git-basis my-basis | git-bundle create my-bundle --all --stdin
will prepare a bundle containing everything except that which is a part
of my-basis.
Then you can add the objects in the bundle to the basis, so they won't
get included in the next pack like this:
git-basis --update my-basis < my-bundle
I'm sure that my implementation is crap, but I think this is a useful
idea. Anybody agree? Disagree?
bundle.c | 22 +++++++++++++++++-
git-basis | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+), 2 deletions(-)
create mode 100755 git-basis
diff --git a/bundle.c b/bundle.c
index 0ba5df1..0af12d7 100644
--- a/bundle.c
+++ b/bundle.c
@@ -227,8 +227,26 @@ int create_bundle(struct bundle_header *header,
const char *path,
/* write references */
argc = setup_revisions(argc, argv, &revs, NULL);
- if (argc > 1)
- return error("unrecognized argument: %s'", argv[1]);
+
+ for (i = 1; i < argc; i++) {
+ if ( !strcmp(argv[i], "--stdin") ) {
+ char line[1000];
+ while (fgets(line, sizeof(line),
stdin) != NULL) {
+ int len = strlen(line);
+ if (len && line[len - 1] == '\n')
+ line[--len] = 0;
+ if (!len)
+ break;
+ if (line[0] == '-')
+ die("options not supported in
--stdin mode");
+ if (handle_revision_arg(line, &revs, 0, 1))
+ die("bad revision '%s'", line);
+ }
+ continue;
+ }
+
+ return error("unrecognized argument: %s'", argv[i]);
+ }
for (i = 0; i < revs.pending.nr; i++) {
struct object_array_entry *e = revs.pending.objects + i;
diff --git a/git-basis b/git-basis
new file mode 100755
index 0000000..891635c
--- /dev/null
+++ b/git-basis
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+
+use strict;
+
+use Git;
+
+my $r = Git->repository();
+my $d = $r->repo_path();
+
+if ( ! -d "$d/bases" ) {
+ system( "mkdir '$d/bases'" );
+}
+
+if ( $#ARGV == -1 ) {
+ print "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 = ();
+ open F, "<$d/bases/$f" || die "Can't open bases/$f: $!";
+ while (<F>) {
+ if (!/^([a-z0-9]{40})/) {next;}
+ $these{$1} = 1;
+ }
+ close F;
+ open F, ">>$d/bases/$f" || die "Can't open bases/$f: $!";
+ print F "\#" . `date`;
+ foreach my $b (keys %new) {
+ if (exists($these{$b})) {next;}
+ print F "$b\n";
+ }
+ close F;
+ }
+} 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";
+ }
+}
--
1.5.5.1.211.g65ea3.dirty
next parent reply other threads:[~2008-06-24 2:22 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1214273297-8257-1-git-send-email-adambrewster@gmail.com>
[not found] ` <1214273297-8257-2-git-send-email-adambrewster@gmail.com>
2008-06-24 2:21 ` Adam Brewster [this message]
2008-06-24 8:09 ` [PATCH/RFC] Created git-basis and modified git-bundle to accept --stdin Jakub Narebski
2008-06-24 15:30 ` Adam Brewster
2008-06-24 18:55 ` Jakub Narebski
[not found] ` <c376da900806241655q85fc1d9r5bf67096a7930f94@mail.gmail.com>
2008-06-25 0:21 ` Jakub Narebski
2008-06-25 1:14 ` Adam Brewster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c376da900806231921y2d822been9cd573d509fbf78a@mail.gmail.com \
--to=adam@adambrewster.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).