{"thread":{"id":"14234","subject":"[PATCH/v2] git-basis, a script to manage bases for git-bundle","startedAt":"2008-06-30T22:49:25Z","lastAt":"2008-07-04T20:55:45Z","messageCount":22,"participants":["Adam Brewster","Jeff King","Junio C Hamano","Mark Levedahl","Jay Soffian","Jakub Narebski","Johannes Schindelin"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"81794","messageId":"c376da900806301549r6044cd35r5a23baa405570808@mail.gmail.com","threadId":"14234","inReplyTo":"1214272713-7808-1-git-send-email-adambrewster@gmail.com","subject":"[PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-06-30T22:49:25Z","receivedAt":"2008-06-30T22:49:25Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":"Git-basis is a perl script that remembers bases for use by git-bundle.\nCode from rev-parse was borrowed to allow git-bundle to handle --stdin.\n\nSigned-off-by: Adam Brewster <adambrewster@gmail.com>\n---\nAs promised, here's another patch with documentation.  The code is\nidentical to the previous version.\n\nI know this is a minor patch, but I think the result is a more usable\ngit-bundle feature, and I'd like to see it included in future releases\nif there are no objections.\n\n Documentation/git-basis.txt |   82 +++++++++++++++++++++++++++++++++++++++++++\n bundle.c                    |   22 ++++++++++-\n git-basis                   |   71 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 173 insertions(+), 2 deletions(-)\n create mode 100644 Documentation/git-basis.txt\n create mode 100755 git-basis\n\ndiff --git a/Documentation/git-basis.txt b/Documentation/git-basis.txt\nnew file mode 100644\nindex 0000000..3624890\n--- /dev/null\n+++ b/Documentation/git-basis.txt\n@@ -0,0 +1,82 @@\n+git-basis(1)\n+============\n+\n+NAME\n+----\n+git-basis - Track sets of references available on remote systems (bases)\n+\n+SYNOPSIS\n+--------\n+[verse]\n+'git-basis' <basis> [<basis>...]\n+'git-basis' --update <basis> [<basis>...] < <object list or bundle>\n+\n+DESCRIPTION\n+-----------\n+Maintains lists of objects that are known to be accessible on remote\n+computer systems that are not accessible by network.\n+\n+OPTIONS\n+-------\n+\n+basis::\n+       List of bases to operate on.  Any valid filename can be\n+       the name of a basis.  Bases that do not exist are taken\n+       to be empty.\n+\n+--update::\n+       Tells git-basis to read a list of objects from stdin and\n+       add them to each of the given bases.  git-basis produces\n+       no output when this option is given.  Bases will be created\n+       if necessary.\n+\n+object list or bundle::\n+       Git-basis --update reads object names, one per line from stdin.\n+       Leading caret (\"^\") characters are ignored, as is anything\n+       after the object name.  Lines that don't begin with an object\n+       name are ignored.  The output of linkgit:git-ls-remote[1] or a\n+       bundle created by linkgit:git-bundle[1] are both suitable input.\n+\n+DISCUSSION\n+----------\n+git-basis is probably only useful with linkgit:git-bundle[1].\n+\n+To create a bundle that excludes all objects that are part of my-basis,\n+use\n+\n+git-basis my-basis | git-bundle create my-bundle --all --stdin\n+\n+To add the objects in my-bundle to my-basis, use\n+\n+git-basis --update my-basis < my-bundle\n+\n+DETAILS\n+-------\n+Bases are stored as plain text files under .git/bases/.  One object\n+entry per line.\n+\n+git-basis without --update reads all of the basis names given on the\n+command line, and outputs the intersection of them to stdout, with each\n+object prefixed by \"^\".\n+\n+git-basis --update reads object names from stdin, and adds all of the\n+references to each of the bases listed.  Duplicate references will not\n+be listed twice, but otherwise redundant information will be included.\n+\n+BUGS\n+----\n+Likely.\n+\n+Bug reports are welcome, and patches are encouraged.\n+\n+SEE ALSO\n+--------\n+linkgit:git-bundle[1]\n+\n+AUTHOR\n+------\n+Written by Adam Brewster <asb@bu.edu>\n+\n+GIT\n+---\n+Part of the linkgit:git[1] suite\ndiff --git a/bundle.c b/bundle.c\nindex 0ba5df1..0af12d7 100644\n--- a/bundle.c\n+++ b/bundle.c\n@@ -227,8 +227,26 @@ int create_bundle(struct bundle_header *header,\nconst char *path,\n\n       /* write references */\n       argc = setup_revisions(argc, argv, &revs, NULL);\n-       if (argc > 1)\n-               return error(\"unrecognized argument: %s'\", argv[1]);\n+\n+       for (i = 1; i < argc; i++) {\n+               if ( !strcmp(argv[i], \"--stdin\") ) {\n+                       char line[1000];\n+                               while (fgets(line, sizeof(line),\nstdin) != NULL) {\n+                               int len = strlen(line);\n+                               if (len && line[len - 1] == '\\n')\n+                                       line[--len] = 0;\n+                               if (!len)\n+                                       break;\n+                               if (line[0] == '-')\n+                                       die(\"options not supported in\n--stdin mode\");\n+                               if (handle_revision_arg(line, &revs, 0, 1))\n+                                       die(\"bad revision '%s'\", line);\n+                       }\n+                       continue;\n+               }\n+\n+               return error(\"unrecognized argument: %s'\", argv[i]);\n+       }\n\n       for (i = 0; i < revs.pending.nr; i++) {\n               struct object_array_entry *e = revs.pending.objects + i;\ndiff --git a/git-basis b/git-basis\nnew file mode 100755\nindex 0000000..891635c\n--- /dev/null\n+++ b/git-basis\n@@ -0,0 +1,71 @@\n+#!/usr/bin/perl\n+\n+use strict;\n+\n+use Git;\n+\n+my $r = Git->repository();\n+my $d = $r->repo_path();\n+\n+if ( ! -d \"$d/bases\" ) {\n+    system( \"mkdir '$d/bases'\" );\n+}\n+\n+if ( $#ARGV == -1 ) {\n+    print \"usage: git-basis [--update] basis1...\\n\";\n+    exit;\n+} elsif ( $ARGV[0] eq '--update' ) {\n+    shift @ARGV;\n+\n+    my %new = ();\n+    while (<STDIN>) {\n+       if (!/^^?([a-z0-9]{40})/) {next;}\n+       $new{$1} = 1;\n+    }\n+\n+    foreach my $f (@ARGV) {\n+       my %these = ();\n+       open F, \"<$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n+       while (<F>) {\n+           if (!/^([a-z0-9]{40})/) {next;}\n+           $these{$1} = 1;\n+       }\n+       close F;\n+       open F, \">>$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n+       print F \"\\#\" . `date`;\n+       foreach my $b (keys %new) {\n+           if (exists($these{$b})) {next;}\n+           print F \"$b\\n\";\n+       }\n+       close F;\n+    }\n+} else {\n+    my $n = 0;\n+    my %basis = ();\n+\n+    my $f = shift @ARGV;\n+    open F, \"<$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n+    while (<F>) {\n+       if (!/^([a-z0-9]{40})/) {next;}\n+       $basis{$1} = $n;\n+    }\n+    close F;\n+\n+    foreach $f (@ARGV) {\n+       open F, \"<$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n+       while (<F>) {\n+           if (!/^([a-z0-9]{40})/) {next;}\n+           if (!exists($basis{$1})) {next;}\n+\n+           if ($basis{$1} == $n) {$basis{$1}++;}\n+           else {delete $basis{$1};}\n+       }\n+       close F;\n+       $n++;\n+    }\n+\n+    foreach my $b (keys %basis) {\n+       if ( $basis{$b} != $n ) {next;}\n+       print \"^$b\\n\";\n+    }\n+}\n--\n1.5.5.1.211.g65ea3.dirty\n"},{"id":"81856","messageId":"20080701095117.GC5853@sigill.intra.peff.net","threadId":"14234","inReplyTo":"c376da900806301549r6044cd35r5a23baa405570808@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-07-01T09:51:18Z","receivedAt":"2008-07-01T09:51:18Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jun 30, 2008 at 06:49:25PM -0400, Adam Brewster wrote:\n\n> Git-basis is a perl script that remembers bases for use by git-bundle.\n> Code from rev-parse was borrowed to allow git-bundle to handle --stdin.\n\nI don't use bundles myself, so I can't comment on how useful this is for\na bundle-based workflow. But it seems like a sensible idea in general.\n\nA few comments:\n\n> --- a/bundle.c\n> +++ b/bundle.c\n> @@ -227,8 +227,26 @@ int create_bundle(struct bundle_header *header,\n> const char *path,\n> \n>        /* write references */\n>        argc = setup_revisions(argc, argv, &revs, NULL);\n> -       if (argc > 1)\n> -               return error(\"unrecognized argument: %s'\", argv[1]);\n> +\n> +       for (i = 1; i < argc; i++) {\n> +               if ( !strcmp(argv[i], \"--stdin\") ) {\n\nWhen a new feature depends on other, more generic improvements\nto existing code, it is usually split into two patches. E.g.,\n\n  1/2: add --stdin to git-bundle\n  2/2: add git-basis\n\nwith the advantages that:\n\n - it is slightly easier to review each change individually\n - it is easier for other features to build on the generic improvement\n   without requiring part 2, especially if part 2 is questionable\n\nAs it happens in this case, I think in this case the change was already\neasy to read, being logically separated by file, so I am nitpicking\nsomewhat. But splitting changes is a good habit to get into.\n\n> +                               if (len && line[len - 1] == '\\n')\n> +                                       line[--len] = 0;\n\nStyle: we usually spell NUL as '\\0'.\n\n> diff --git a/git-basis b/git-basis\n> new file mode 100755\n\nThis should be git-basis.perl, with accompanying Makefile changes.\n\n> +if ( ! -d \"$d/bases\" ) {\n> +    system( \"mkdir '$d/bases'\" );\n> +}\n\nYikes. This fails if $d contains an apostrophe. You'd want to use\nquotemeta to properly shell out. But there's no need at all to shell out\nhere, since perl has its own mkdir call.\n\n> +if ( $#ARGV == -1 ) {\n> +    print \"usage: git-basis [--update] basis1...\\n\";\n> +    exit;\n\nUsage should probably go to STDERR.\n\n> +    my %new = ();\n> +    while (<STDIN>) {\n> +       if (!/^^?([a-z0-9]{40})/) {next;}\n> +       $new{$1} = 1;\n> +    }\n\nWhy make a hash when the only thing we ever do with it is \"keys %new\"?\nShouldn't an array suffice?\n\n> +    foreach my $f (@ARGV) {\n> +       my %these = ();\n> +       open F, \"<$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n\nStyle: I know we are not consistent within git, but it is usually better\nto use local variables for filehandles these days. I.e.,\n\n  open my $fh, \"<$d/bases/$f\"\n\n> +       open F, \">>$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n\nSo the basis just grows forever? That is, each time we do a bundle and\nbasis update, we add a line for every changed ref, and we never delete\nany lines. But having a commit implies having all of its ancestors, so\nin the normal case (i.e., no rewind or rebase) we can simply replace old\nobjects if we know they are a subset of the new ones (which you can\ndiscover with git-merge-base). For the rewind/rebase case, probably\nthese lists should get pruned eventually for non-existent objects.\n\nBut maybe it is not worth worrying about this optimization at first, and\nwe can see if people complain. In that case, it is perhaps worth a note\nin the 'Bugs' section (or 'Discussion' section) of the manpage.\n\n> +       print F \"\\#\" . `date`;\n\nI don't think there are any portability issues with 'date' (especially\nsince it appears to be just a comment here, so we don't really care\nabout the format), but in general I think it is nicer to use perl's date\nfunctions just for consistency's sake.\n\n> --\n> 1.5.5.1.211.g65ea3.dirty\n\nNotably absent: any tests.\n\n-Peff\n"},{"id":"81910","messageId":"7vzlp1jh1o.fsf@gitster.siamese.dyndns.org","threadId":"14234","inReplyTo":"c376da900806301549r6044cd35r5a23baa405570808@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-07-01T23:55:31Z","receivedAt":"2008-07-01T23:55:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Adam Brewster\" <adambrewster@gmail.com> writes:\n\n> Git-basis is a perl script that remembers bases for use by git-bundle.\n> Code from rev-parse was borrowed to allow git-bundle to handle --stdin.\n>\n> Signed-off-by: Adam Brewster <adambrewster@gmail.com>\n> ---\n> As promised, here's another patch with documentation.  The code is\n> identical to the previous version.\n>\n> I know this is a minor patch, but I think the result is a more usable\n> git-bundle feature, and I'd like to see it included in future releases\n> if there are no objections.\n\nWell, I have a moderately strong objection to this.\n\nThis very much feels like adding a missing feature to \"git bundle\" command\nitself.  Why isn't it a new option to it?\n\nFor that matter, I am not sure how this integrates to a larger workflow.\nYou have a site (or more) to \"push\" your changes to, and you would need to\nremember up to which revisions you have given out bundles to.  To remember\nwhich site is at what basis level, you would need an extra infrastructure\nthan what this separate command offers (and \"I'll have a yet another layer\nof wrapper to this script\" is not a good answer.  That wrapper can simply\nread the tips from the bundle and record them without your script, and the\nwrapper can use the previously recorded information to use the new bottom\nrefs when creating a new bundle again without using your script).\n\nPerhaps it would be sufficient to have a new option to git-bundle.  \"write\nbasis information under this name, so that I can reuse it in the next\ninvocation\", and \"I am not giving the bottom refs to create this bundle;\nread them from the existing basis with this name\".  It probably is easiest\nto operate if these two are simply a new single option, like this...\n\ndiff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt\nindex f6a0612..d3e0716 100644\n--- a/Documentation/git-bundle.txt\n+++ b/Documentation/git-bundle.txt\n@@ -9,7 +9,7 @@ git-bundle - Move objects and refs by archive\n SYNOPSIS\n --------\n [verse]\n-'git-bundle' create <file> <git-rev-list args>\n+'git-bundle' create [--basis=<filename>] <file> <git-rev-list args>\n 'git-bundle' verify <file>\n 'git-bundle' list-heads <file> [refname...]\n 'git-bundle' unbundle <file> [refname...]\n@@ -37,6 +37,17 @@ create <file>::\n        Used to create a bundle named 'file'.  This requires the\n        git-rev-list arguments to define the bundle contents.\n \n+--basis=<filename>;;\n+\tRecord the tips of resulting bundle to the file whie creating the\n+        bundle, so that the information can be used when later creating a\n+        new bundle to incrementally update a repository that resulting\n+        bundle has already been applied to.\n++\n+If the named file exists, it should name the file given to this\n+option in a previous invocation of 'git-bundle create' command.\n+The tips of history recorded in the file is read and the resulting\n+bundle will require them.\n+\n verify <file>::\n        Used to check that a bundle file is valid and will apply\n        cleanly to the current repository.  This includes checks on the\n@@ -165,6 +176,26 @@ $ git pull bundle\n would treat it as if it is talking with a remote side over the\n network.\n \n+- Use basis file to keep track.\n+\n+------------\n+$ git bundle create --basis=siteA.basis 2008-07-01.bndl master\n+------------\n+\n+The new file `siteA.basis` records the tip commits in the created\n+bundle.  Give `2008-07-01.bndl` to 'site A'.  Then later:\n+\n+------------\n+$ git bundle create --basis=siteA.basis 2008-08-01.bndl master\n+------------\n+\n+This invocation will read the existing `siteA.basis` file, reads the tip\n+commits recorded there, and excludes the history reachable from these\n+commits from the resulting `2008-08-01.bndl` bundle.  You can give this to\n+'site A'; as long as they have extracted the previous bundle, it is\n+sufficient to bring them up-to-date.\n+\n+\n Author\n ------\n Written by Mark Levedahl <mdl123@verizon.net>\n\nHmm?\n"},{"id":"81911","messageId":"486AC8E0.60002@verizon.net","threadId":"14234","inReplyTo":"7vzlp1jh1o.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2008-07-02T00:16:32Z","receivedAt":"2008-07-02T00:16:32Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Junio C Hamano wrote:\n\n> \n> Well, I have a moderately strong objection to this.\n> \n> This very much feels like adding a missing feature to \"git bundle\" command\n> itself.  Why isn't it a new option to it?\n> \n\nI have implemented (in script form) a different approach: basically, I just keep \na local copy of the refs pushed out via bundle in refs/remotes/*, just as for \nany other remote, and then use those as the basis for later bundles. My longer \nterm goal is to integrate this into git push, so that with a properly configured \nremote \"git push foo\" will create a bundle based upon the local knowledge of the \nremote's basis and update the local copy of the refs.\n\n\nFor reference, this is the script I currently use ...\n\n#!/bin/sh\n# usage\nif test $# -lt 4\nthen\n     echo \"usage: $0 repoDirectory bundleName remote [git-for-each-ref args]\"\n     exit 1\nfi\n\n# must be at toplevel\ncd $1 || exit 1\ncd ./$(git rev-parse --show-cdup) || exit 1\n\nbundleName=$2\nremote=$3\nshift 3\n\n# get list of what we want to bundle up\nnewrefs=$(git for-each-ref --format=\"%(refname)\" $*)\n\n# get list of the current bundle\nbasis=$(git for-each-ref --format=\"^%(objectname)\" refs/remotes/$remote)\n\n# create the bundle\nif git bundle create \"$bundleName\" $newrefs $basis\nthen\n     # update our record of basis from the bundle\n     git bundle list-heads \"$bundleName\" | \\\n     while read sha1 refname\n     do\n         git update-ref refs/remotes/\"$remote\"/\"${refname##refs/}\" $sha1\n     done\nelse\n     rm -f \"$bundleName\"\nfi\n\nMark\n"},{"id":"81914","messageId":"c376da900807011836i76363d74n7f1b87d66ba34cd6@mail.gmail.com","threadId":"14234","inReplyTo":"20080701095117.GC5853@sigill.intra.peff.net","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-07-02T01:36:20Z","receivedAt":"2008-07-02T01:36:20Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":"Hi Jeff,\n\nThank you for your feedback.  I have made most of the code changes you\nsuggested, and am in the process of writing tests, but it looks like\nsome others on the list have more serious objections, so I'll hold of\non that until I think it might actually be accepted.\n\nIn the mean time, I have a couple of responses to your comments below.\n\n>\n> When a new feature depends on other, more generic improvements\n> to existing code, it is usually split into two patches. E.g.,\n>\n>  1/2: add --stdin to git-bundle\n>  2/2: add git-basis\n>\n> with the advantages that:\n>\n>  - it is slightly easier to review each change individually\n>  - it is easier for other features to build on the generic improvement\n>   without requiring part 2, especially if part 2 is questionable\n>\n> As it happens in this case, I think in this case the change was already\n> easy to read, being logically separated by file, so I am nitpicking\n> somewhat. But splitting changes is a good habit to get into.\n>\n\nMakes sense,  I thought it was small enough for one commit, but I'll\nsplit it up when I resubmit.\n\n>> +                               if (len && line[len - 1] == '\\n')\n>> +                                       line[--len] = 0;\n>\n> Style: we usually spell NUL as '\\0'.\n>\n\nOkay.  I can also include a third patch for the code I cut-and-pasted.\n\ndiff --git a/builtin-rev-list.c b/builtin-rev-list.c\nindex 11a7eae..73fe334 100644\n--- a/builtin-rev-list.c\n+++ b/builtin-rev-list.c\n@@ -582,7 +582,7 @@ static void read_revisions_from_stdin(struct rev_info *revs)\n        while (fgets(line, sizeof(line), stdin) != NULL) {\n                int len = strlen(line);\n                if (len && line[len - 1] == '\\n')\n-                       line[--len] = 0;\n+                       line[--len] = '\\0';\n                if (!len)\n                        break;\n                if (line[0] == '-')\n\n\n>> diff --git a/git-basis b/git-basis\n>> new file mode 100755\n>\n> This should be git-basis.perl, with accompanying Makefile changes.\n>\n>> +if ( ! -d \"$d/bases\" ) {\n>> +    system( \"mkdir '$d/bases'\" );\n>> +}\n>\n> Yikes. This fails if $d contains an apostrophe. You'd want to use\n> quotemeta to properly shell out. But there's no need at all to shell out\n> here, since perl has its own mkdir call.\n>\n\nMade both of these changes.\n\n>> +if ( $#ARGV == -1 ) {\n>> +    print \"usage: git-basis [--update] basis1...\\n\";\n>> +    exit;\n>\n> Usage should probably go to STDERR.\n>\n\nMakes sense.\n\n>> +    my %new = ();\n>> +    while (<STDIN>) {\n>> +       if (!/^^?([a-z0-9]{40})/) {next;}\n>> +       $new{$1} = 1;\n>> +    }\n>\n> Why make a hash when the only thing we ever do with it is \"keys %new\"?\n> Shouldn't an array suffice?\n>\n\nIt's probably a non-issue, but using a hash will prevent duplicates.\n\n>> +    foreach my $f (@ARGV) {\n>> +       my %these = ();\n>> +       open F, \"<$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n>\n> Style: I know we are not consistent within git, but it is usually better\n> to use local variables for filehandles these days. I.e.,\n>\n>  open my $fh, \"<$d/bases/$f\"\n>\n\nOkay.\n\n>> +       open F, \">>$d/bases/$f\" || die \"Can't open bases/$f: $!\";\n>\n> So the basis just grows forever? That is, each time we do a bundle and\n> basis update, we add a line for every changed ref, and we never delete\n> any lines. But having a commit implies having all of its ancestors, so\n> in the normal case (i.e., no rewind or rebase) we can simply replace old\n> objects if we know they are a subset of the new ones (which you can\n> discover with git-merge-base). For the rewind/rebase case, probably\n> these lists should get pruned eventually for non-existent objects.\n>\n\nIf all goes well then you're right, but I thought old objects should\nbe kept around  in case the user has some reason to manually delete\nthem.  As it is, you can go into the basis file and delete everything\npast a given date line and be back where you were.  If I delete the\nredundant objects, then that's not always possible.\n\nIt'd be nice if it could prune old objects (maybe older than 6 months,\nor settable by git-config) that are redundant, but I currently have no\nneed for such functionality.\n\nI also hadn't thought about rebasing.  Objects that don't exist\nshouldn't hurt anything though.  Just a waste of a little disk space.\nIf pruning is ever put in, objects that don't exist can be deleted.\n\n> But maybe it is not worth worrying about this optimization at first, and\n> we can see if people complain. In that case, it is perhaps worth a note\n> in the 'Bugs' section (or 'Discussion' section) of the manpage.\n>\n\nAgree.  I put it under bugs.\n\n>> +       print F \"\\#\" . `date`;\n>\n> I don't think there are any portability issues with 'date' (especially\n> since it appears to be just a comment here, so we don't really care\n> about the format), but in general I think it is nicer to use perl's date\n> functions just for consistency's sake.\n>\n\nMaybe I'm a idiot, but I can't find any built-in date to string\nfunctions that do nice things like print the date the way the user\nsays he likes to look at dates.\n\nI updated the comment line to be \"# <git-date> // `date`\" where\ngit-date is as per git-fast-import (seconds since 1969 +/-TZ).  If\nautomatic pruning ever happens, the git-date will be used, so `date`\nis just for humans.\n\n>\n> Notably absent: any tests.\n>\n\nWorking on those.  I'll also include tests for git-bundle.\n\nAdam\n"},{"id":"81915","messageId":"76718490807011910p37ac9bcbjf9fa9748a2eb2e@mail.gmail.com","threadId":"14234","inReplyTo":"c376da900807011836i76363d74n7f1b87d66ba34cd6@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-07-02T02:10:16Z","receivedAt":"2008-07-02T02:10:16Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Jul 1, 2008 at 9:36 PM, Adam Brewster <adambrewster@gmail.com> wrote:\n> Maybe I'm a idiot, but I can't find any built-in date to string\n> functions that do nice things like print the date the way the user\n> says he likes to look at dates.\n\nperldoc -f localtime\n\nj.\n"},{"id":"81916","messageId":"c376da900807011912x5a9ad3aaxa04598e0f1416604@mail.gmail.com","threadId":"14234","inReplyTo":"7vzlp1jh1o.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-07-02T02:12:28Z","receivedAt":"2008-07-02T02:12:28Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":">\n> Well, I have a moderately strong objection to this.\n>\n> This very much feels like adding a missing feature to \"git bundle\" command\n> itself.  Why isn't it a new option to it?\n>\n\nMostly because this was an easy way to accomplish the same thing.  If\nthis is popular, then it can be added to git-bundle.\n\n> For that matter, I am not sure how this integrates to a larger workflow.\n> You have a site (or more) to \"push\" your changes to, and you would need to\n> remember up to which revisions you have given out bundles to.  To remember\n> which site is at what basis level, you would need an extra infrastructure\n> than what this separate command offers (and \"I'll have a yet another layer\n> of wrapper to this script\" is not a good answer.  That wrapper can simply\n> read the tips from the bundle and record them without your script, and the\n> wrapper can use the previously recorded information to use the new bottom\n> refs when creating a new bundle again without using your script).\n\nThe intent is to use one basis per site, not one per bundle, so the\nfirst iteration is\n\nA$ git-bundle create package.git --all\nB$ git-clone package.git package\nA$ git-bundle --update siteB < package.git\n\nand thereafter it's\n\nA$ git-bundle siteB | git-bundle create package.git --all --stdin\nB$ git-pull\nA$ git-bundle --update siteB < package.git\n\nThere's no issue of remembering which site is at which basis level,\nbecause each site gets it's own basis.\n\nIf you're worried about hundred of sites, this is a bad solution.  I\nhappen to be worried about three sites, so this works well for me.\n\n>\n> Perhaps it would be sufficient to have a new option to git-bundle.  \"write\n> basis information under this name, so that I can reuse it in the next\n> invocation\", and \"I am not giving the bottom refs to create this bundle;\n> read them from the existing basis with this name\".  It probably is easiest\n> to operate if these two are simply a new single option, like this...\n>\n> [...]\n\nI agree than git-bundle --basis is a better syntax than git-basis |\ngit-bundle --stdin.\n\nI do, however, think that creating the bundle and updating the basis\nshould be two separate steps.  Mostly because the fact that I created\na bundle and planned to install it on another machine does not\nguarantee that the resources of that bundle exist on the other\nmachine.  (I may need to stop for coffee and ... who knows?) Also, in\npractice, I always use the intersection of all of my remote bases when\nI create a bundle, and I frequently use them in places other than\nwhere I intended.  Yes it's a pain to go back to git-basis --update,\nbut it's better than trying to git-pull from a bundle that's missing\nobjects.\n\nAdam\n"},{"id":"81917","messageId":"c376da900807011916j5a3032een4587619535061b72@mail.gmail.com","threadId":"14234","inReplyTo":"76718490807011910p37ac9bcbjf9fa9748a2eb2e@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-07-02T02:16:21Z","receivedAt":"2008-07-02T02:16:21Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":"On Tue, Jul 1, 2008 at 10:10 PM, Jay Soffian <jaysoffian@gmail.com> wrote:\n> On Tue, Jul 1, 2008 at 9:36 PM, Adam Brewster <adambrewster@gmail.com> wrote:\n>> Maybe I'm a idiot, but I can't find any built-in date to string\n>> functions that do nice things like print the date the way the user\n>> says he likes to look at dates.\n>\n> perldoc -f localtime\n>\n\nBut of course one function returns two very different things depending\non what's on the left side of the equals sign.  That makes perfect\nsense.\n\n> j.\n>\n\nThank you.\nAdam\n"},{"id":"81918","messageId":"76718490807011921o3ad1c0efmbfd819eae012865@mail.gmail.com","threadId":"14234","inReplyTo":"c376da900807011916j5a3032een4587619535061b72@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jay Soffian","fromEmail":"jaysoffian@gmail.com","sentAt":"2008-07-02T02:21:11Z","receivedAt":"2008-07-02T02:21:11Z","isPatch":true,"sender":{"key":"jaysoffian@gmail.com","avatar":"https://avatars.githubusercontent.com/u/155970?v=4"},"body":"On Tue, Jul 1, 2008 at 10:16 PM, Adam Brewster <adambrewster@gmail.com> wrote:\n> But of course one function returns two very different things depending\n> on what's on the left side of the equals sign.  That makes perfect\n> sense.\n\nContext should be the very first thing taught in any Perl tutorial,\nlest ye end up in jail:\n\nhttp://yro.slashdot.org/article.pl?sid=01/03/13/208259\n\n:-)\n\nj.\n"},{"id":"81920","messageId":"20080702032155.GA13581@sigill.intra.peff.net","threadId":"14234","inReplyTo":"c376da900807011836i76363d74n7f1b87d66ba34cd6@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-07-02T03:21:55Z","receivedAt":"2008-07-02T03:21:55Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jul 01, 2008 at 09:36:20PM -0400, Adam Brewster wrote:\n\n> Makes sense,  I thought it was small enough for one commit, but I'll\n> split it up when I resubmit.\n\nI think in this instance it is not too big a deal either way.  I am just\ntrying to help encourage good habits. :)\n\n> > Style: we usually spell NUL as '\\0'.\n> \n> Okay.  I can also include a third patch for the code I cut-and-pasted.\n\nHeh. I said \"usually\", but I guess even Junio makes mistakes (unless I\nam dreaming such a style directive, but ISTR it being mentioned before\non the list). I wouldn't bother with the style cleanup in rev-list\n(usually for such small things, we just wait until touching that part of\nthe code).\n\n> > Why make a hash when the only thing we ever do with it is \"keys %new\"?\n> > Shouldn't an array suffice?\n> \n> It's probably a non-issue, but using a hash will prevent duplicates.\n\nAh, true. And there will be duplicates here, if you have multiple refs\nat the same spot in your bundle list. So it should remain as you have\nit.\n\n> If all goes well then you're right, but I thought old objects should\n> be kept around  in case the user has some reason to manually delete\n> them.  As it is, you can go into the basis file and delete everything\n> past a given date line and be back where you were.  If I delete the\n> redundant objects, then that's not always possible.\n\nHmm, and that might be useful. Probably the best thing would be to leave\nit as-is for now, then, with a note. Then we can decide the best pruning\nstrategy if and when it becomes an issue.\n\n> Maybe I'm a idiot, but I can't find any built-in date to string\n> functions that do nice things like print the date the way the user\n> says he likes to look at dates.\n> \n> I updated the comment line to be \"# <git-date> // `date`\" where\n> git-date is as per git-fast-import (seconds since 1969 +/-TZ).  If\n> automatic pruning ever happens, the git-date will be used, so `date`\n> is just for humans.\n\nThat sounds reasonable.\n\n> > Notably absent: any tests.\n> Working on those.  I'll also include tests for git-bundle.\n\nGreat. Glancing over Junio's comments, though, it might make sense to\nintegrate this more tightly with git-bundle, in which case the perl\nstuff would go away. So I'll let you work out with him which is the best\nroute.\n\n-Peff\n"},{"id":"81964","messageId":"200807021144.46423.jnareb@gmail.com","threadId":"14234","inReplyTo":"20080702032155.GA13581@sigill.intra.peff.net","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-07-02T09:44:45Z","receivedAt":"2008-07-02T09:44:45Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Wed, 2 July 2008, Jeff King wrote:\n>\n> Glancing over Junio's comments, though, it might make sense to\n> integrate this more tightly with git-bundle, in which case the perl\n> stuff would go away. So I'll let you work out with him which is the\n> best route.\n\nWell, there is one situation where either separate git-bases program\n(which is a good start; it can be named git-bundle--bases; there are\nsome precedents for that ;-)), or allowing to create 'bases' file\nwithout creating bundle would be good to have.  Namely situation\nwhere two computers are _sometimes off-line (disconnected)_.  If you\nwant to transfer new commits from machine B to machine A, you would\ngenerate 'bases' file on machine A, then transfer this file using some\noff-line medium, then generate bundle on machine B using those bases,\netc.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"82149","messageId":"20080703195915.GA18532@sigill.intra.peff.net","threadId":"14234","inReplyTo":"200807021144.46423.jnareb@gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-07-03T19:59:15Z","receivedAt":"2008-07-03T19:59:15Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jul 02, 2008 at 11:44:45AM +0200, Jakub Narebski wrote:\n\n> Well, there is one situation where either separate git-bases program\n> (which is a good start; it can be named git-bundle--bases; there are\n> some precedents for that ;-)), or allowing to create 'bases' file\n> without creating bundle would be good to have.  Namely situation\n> where two computers are _sometimes off-line (disconnected)_.  If you\n> want to transfer new commits from machine B to machine A, you would\n> generate 'bases' file on machine A, then transfer this file using some\n> off-line medium, then generate bundle on machine B using those bases,\n> etc.\n\nYes, certainly it is more flexible to have them split. I find Adam's\nargument the most compelling, though. Think about moving commits as a\nmulti-step protocol:\n\n  1. Local -> Remote: Here are some new commits, basis..current\n  2. Remote -> Local: OK, I am now at current.\n  3. Local: update basis to current\n\ngit-push has the luxury of asking for \"basis\" each time, so we know it\nis correct. But with bundles, we can't do that. And failing to update\n\"basis\" means we will send some extra commits next time. But updating\n\"basis\" when we shouldn't means that the next bundle will be broken.\n\nSo I think even if people _do_ want to update \"basis\" when they create\nthe bundle (because it is more convenient, and they are willing to\naccept the possibility of losing sync), it is trivial to create that\nworkflow on top of the separate components. But I can see why somebody\nmight prefer the separate components, and it is hard to create them if\nthe feature is lumped into \"git-bundle\" (meaning in such a way that you\ncannot perform the steps separately; obviously git-bundle --basis would\nbe equivalent).\n\nBut I am not a bundle user, so that is just my outsider perspective.\n\n-Peff\n"},{"id":"82171","messageId":"c376da900807031613pc63639du356946f8daeabb29@mail.gmail.com","threadId":"14234","inReplyTo":"486AC8E0.60002@verizon.net","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-07-03T23:13:09Z","receivedAt":"2008-07-03T23:13:09Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":"Hi Mark,\n\nThank you for your help, and I'm sorry I didn't get back to you sooner.\n\n>\n> I have implemented (in script form) a different approach: basically, I just\n> keep a local copy of the refs pushed out via bundle in refs/remotes/*, just\n> as for any other remote, and then use those as the basis for later bundles.\n> My longer term goal is to integrate this into git push, so that with a\n> properly configured remote \"git push foo\" will create a bundle based upon\n> the local knowledge of the remote's basis and update the local copy of the\n> refs.\n>\n> [...]\n\nThat's a good way to do things.  I tend to like my system better\nbecause it's a little more flexible and it doesn't pollute git-branch\n-a and gitk --all, also as I said before I like the bundle creation\nand the basis update to be separated.\n\nHow do you deal with the case where you want to include remote refs in\nthe bundle?  Don't they get saved as\nrefs/remotes/remote/remotes/somewhere-else/master?\n\nAdam\n"},{"id":"82174","messageId":"c376da900807031638l219229bcy983ed994b37512c9@mail.gmail.com","threadId":"14234","inReplyTo":"20080703195915.GA18532@sigill.intra.peff.net","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-07-03T23:38:21Z","receivedAt":"2008-07-03T23:38:21Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":">\n> Yes, certainly it is more flexible to have them split. I find Adam's\n> argument the most compelling, though. Think about moving commits as a\n> multi-step protocol:\n>\n>  1. Local -> Remote: Here are some new commits, basis..current\n>  2. Remote -> Local: OK, I am now at current.\n>  3. Local: update basis to current\n>\n> git-push has the luxury of asking for \"basis\" each time, so we know it\n> is correct. But with bundles, we can't do that. And failing to update\n> \"basis\" means we will send some extra commits next time. But updating\n> \"basis\" when we shouldn't means that the next bundle will be broken.\n>\n> So I think even if people _do_ want to update \"basis\" when they create\n> the bundle (because it is more convenient, and they are willing to\n> accept the possibility of losing sync), it is trivial to create that\n> workflow on top of the separate components. But I can see why somebody\n> might prefer the separate components, and it is hard to create them if\n> the feature is lumped into \"git-bundle\" (meaning in such a way that you\n> cannot perform the steps separately; obviously git-bundle --basis would\n> be equivalent).\n>\n> But I am not a bundle user, so that is just my outsider perspective.\n>\n> -Peff\n>\n\nHow does everybody feel about the following:\n\n- Leave git-basis as a small perl script.\n\n- Add a -b/--basis option in git-bundle that calls git-basis.  Any\nobjects mentioned in the output would be excluded from the bundle.\nMultiple --basis options will call git-basis once with several\narguments to generate the intersection of specified bases.\n\n- (maybe) Add an option \"--update-bases\" to automatically call\ngit-basis --update after the bundle is created successfully.\n\n- Change the syntax a bit so git-basis --show does what git-basis\nalone does now (because the user will no longer need to interact with\nthat command).\n\nThere's still plenty of potential for improvements, like a --gc mode\nto clean up basis files, a --rewind option to undo an incorrect\n--update, or improvements in the way it calculates intersections, but\nI think that with these changes the system is as simple as possible\nwhile maximizing flexibility, utility, and usability.\n\nAdam\n"},{"id":"82187","messageId":"alpine.DEB.1.00.0807040237580.2849@eeepc-johanness","threadId":"14234","inReplyTo":"c376da900807031638l219229bcy983ed994b37512c9@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-07-04T00:44:10Z","receivedAt":"2008-07-04T00:44:10Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 3 Jul 2008, Adam Brewster wrote:\n\n> > Yes, certainly it is more flexible to have them split. I find Adam's \n> > argument the most compelling, though. Think about moving commits as a \n> > multi-step protocol:\n> >\n> >  1. Local -> Remote: Here are some new commits, basis..current\n> >  2. Remote -> Local: OK, I am now at current.\n> >  3. Local: update basis to current\n> >\n> > git-push has the luxury of asking for \"basis\" each time, so we know it \n> > is correct. But with bundles, we can't do that. And failing to update \n> > \"basis\" means we will send some extra commits next time. But updating \n> > \"basis\" when we shouldn't means that the next bundle will be broken.\n> >\n> > So I think even if people _do_ want to update \"basis\" when they create \n> > the bundle (because it is more convenient, and they are willing to \n> > accept the possibility of losing sync), it is trivial to create that \n> > workflow on top of the separate components. But I can see why somebody \n> > might prefer the separate components, and it is hard to create them if \n> > the feature is lumped into \"git-bundle\" (meaning in such a way that \n> > you cannot perform the steps separately; obviously git-bundle --basis \n> > would be equivalent).\n> >\n> > But I am not a bundle user, so that is just my outsider perspective.\n> \n> How does everybody feel about the following:\n> \n> - Leave git-basis as a small perl script.\n\nI'd rather not.\n\n> - Add a -b/--basis option in git-bundle that calls git-basis.  Any \n>   objects mentioned in the output would be excluded from the bundle.  \n>   Multiple --basis options will call git-basis once with several \n>   arguments to generate the intersection of specified bases.\n\nSo the only function of -b would be to fork() && exec() a _shell_ script?  \nI don't like that at all.\n\n> - (maybe) Add an option \"--update-bases\" to automatically call git-basis \n>   --update after the bundle is created successfully.\n\nRather, have it as a feature to auto-detect if there is a \".basis\" file of \nthe same basename (or, rather \".state\", a I find \"basis\" less than \ndescriptive), and rewrite it if it was there.\n\nIt could be forced by a to-be-introduced \"--state\" option to git-bundle.\n\n> There's still plenty of potential for improvements, like a --gc mode\n> to clean up basis files,\n\numm, why?  \"rm\" is not simple enough?\n\n> a --rewind option to undo an incorrect --update,\n\nRather hard, would you not think?  The information is either not there, or \nyou store loads of cruft in the .state file.\n\n> or improvements in the way it calculates intersections,\n\nUmm.  How so?\n\n> but I think that with these changes the system is as simple as possible \n> while maximizing flexibility, utility, and usability.\n\nI am not convinced.  This sort of feature belongs into git-bundle.  It \ncertainly does not deserve being blessed by yet-another git-* command, \nwhen we are constantly being bashed for having _way_ too many _already_.\n\nCiao,\nDscho\n"},{"id":"82195","messageId":"c376da900807031904y6309a179u5525f147ebc4cd53@mail.gmail.com","threadId":"14234","inReplyTo":"alpine.DEB.1.00.0807040237580.2849@eeepc-johanness","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Adam Brewster","fromEmail":"adambrewster@gmail.com","sentAt":"2008-07-04T02:04:10Z","receivedAt":"2008-07-04T02:04:10Z","isPatch":true,"sender":{"key":"adambrewster@gmail.com","avatar":"https://avatars.githubusercontent.com/u/223816?v=4"},"body":">>\n>> How does everybody feel about the following:\n>>\n>> - Leave git-basis as a small perl script.\n>\n> I'd rather not.\n>\n\nI'm not exactly sure what your objection is here, but I guess it's\neither you don't want a separate tool called git-basis that does all\nof the things I've described, or you don't like my choice of perl to\ndo the work.\n\nIf the former, I suggest that my approach is consistent with the\nphilosophy of doing one thing and doing it well.  I acknowledge that\nit could do it's one job better (see potential improvements in my last\nemail), but that doesn't seem to be your complaint.\n\nIf the latter, I wonder what practical advantage comes from redoing\nwhat I've already done in C.  It would be slightly faster, but I'm not\nworried about saving a few milliseconds in a process that takes at\nleast a couple of minutes (considering of course the time it takes to\nwalk to whatever remote system).\n\n>> - Add a -b/--basis option in git-bundle that calls git-basis.  Any\n>>   objects mentioned in the output would be excluded from the bundle.\n>>   Multiple --basis options will call git-basis once with several\n>>   arguments to generate the intersection of specified bases.\n>\n> So the only function of -b would be to fork() && exec() a _shell_ script?\n> I don't like that at all.\n>\n\nNot quite.  It would be more like a shortcut for\n\ngit-basis --show basis | git-bundle create bundle -all --stdin or\ngit-bundle create bundle --all <( git-basis --show basis )\n\n(the latter of which of course wouldn't work because git-basis doesn't\ntake filenames.\n\nThe bundle creation is still done by git-bundle.  git-basis is just\ndeciding what should (not) be included in the bundle.\n\nIt seems like similar architectures have been accepted to support the\n-i/--interactive options or git-add and git-rebase.\n\n>> - (maybe) Add an option \"--update-bases\" to automatically call git-basis\n>>   --update after the bundle is created successfully.\n>\n> Rather, have it as a feature to auto-detect if there is a \".basis\" file of\n> the same basename (or, rather \".state\", a I find \"basis\" less than\n> descriptive), and rewrite it if it was there.\n>\n> It could be forced by a to-be-introduced \"--state\" option to git-bundle.\n>\n\nJust because I'm creating a bundle, doesn't guarantee that the bundle\nwill be installed on any particular remote system, so I think that\nupdating the basis without being told to do so by the user is a bad\nidea.  For example, when creating a bundle, I find it's best to\nexclude objects that I know exist on ALL of my systems, so that I can\npull from it anywhere, but usually I only end up sending it to one\nsystem.\n\nWith regard to the use of the word basis, it comes from the\ndocumentation of git-bundle.  It's been a while since I took linear\nalgebra, but if I remember correctly, a basis is a set of vectors that\ndescribe a vector space, such that a combination of those vectors\nyields any point in the space.  The analogy isn't perfect, but I think\nit's pretty close.  The word state seems very generic, as the state of\na repository includes much more than a list of objects that are known\nto be available.\n\n>> There's still plenty of potential for improvements, like a --gc mode\n>> to clean up basis files,\n>\n> umm, why?  \"rm\" is not simple enough?\n>\n\nrm leaves the files a little cleaner than I'd like.  A basis is really\na list of objects.  --gc should make sure that the objects in the list\nactually exist, and aren't redundant (if I know that a remote system\nhas a given commit, I also know that it has all of the ancestors, so I\ncould delete them from the basis file without losing (much)\ninformation.\n\n>> a --rewind option to undo an incorrect --update,\n>\n> Rather hard, would you not think?  The information is either not there, or\n> you store loads of cruft in the .state file.\n>\n\nThere's some information that you might describe as cruft.  It is\nspecifically engineered to enable this operation, and the purpose of\n--gc is to reduce the volume of that cruft.\n\n>> or improvements in the way it calculates intersections,\n>\n> Umm.  How so?\n>\n\nIn a tree with three commits, where A (the root) is a parent of X and\nY, if only ommit X is in basisX and only commit Y is in basisY, then\nthe intersection of basisX and basisY should include A.  Currently\ngit-basis will return nothing, because it doesn't care about ancestry.\n\nI don't consider this a serious flaw, because it results in extra\ninformation being included in the bundle, but should never cause\nbroken bundles that are missing information.\n\n>> but I think that with these changes the system is as simple as possible\n>> while maximizing flexibility, utility, and usability.\n>\n> I am not convinced.  This sort of feature belongs into git-bundle.  It\n> certainly does not deserve being blessed by yet-another git-* command,\n> when we are constantly being bashed for having _way_ too many _already_.\n>\n\nI disagree.  I think the --basis option seems like a logical addition\nto git-bundle, but I don't think git-bundle is the right interface to\nupdate the basis files.\n\nIn other news, it seems, the change to make git-bundle accept --stdin\nis less controversial, so I'll submit that as a small patch.\n\n> Ciao,\n> Dscho\n>\n>\n\n\n\nAdam Brewster\n"},{"id":"82222","messageId":"486E2245.6040404@gmail.com","threadId":"14234","inReplyTo":"c376da900807031613pc63639du356946f8daeabb29@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Mark Levedahl","fromEmail":"mlevedahl@gmail.com","sentAt":"2008-07-04T13:14:45Z","receivedAt":"2008-07-04T13:14:45Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Adam Brewster wrote:\n> Hi Mark,\n>\n> Thank you for your help, and I'm sorry I didn't get back to you sooner.\n>\n> That's a good way to do things.  I tend to like my system better\n> because it's a little more flexible and it doesn't pollute git-branch\n> -a and gitk --all, also as I said before I like the bundle creation\n> and the basis update to be separated.\n>\n> How do you deal with the case where you want to include remote refs in\n> the bundle?  Don't they get saved as\n> refs/remotes/remote/remotes/somewhere-else/master?\n>\n> Adam\n>\n>   \nMy script is based upon experience with breakage from keeping the basis \nseparate: absent keeping the refs in the git repo, there is nothing to \nguarantee that the referenced commits continue to exist. We make \nextensive use of short lived topic branches that are often rebased \nmultiple times before being incorporated into a stable branch, so an \nexternally stored basis would frequently have invalid commits. The \nsolutions to this are to 1) filter them out, one by one, with a \"git \nrev-parse $commit\" or some such, or 2) keep the refs in tree so git will \nnot remove the objects.\n\nI'm using this for sneaker-netting, so I know the bundles are being \napplied - clearly the create bundle and update in-tree basis steps could \nbe separated, but I don't use this for cases where I'm not sure the \nbundle will be applied. In the latter case, I just use a basis \ncontaining only previous stable branches.\n\nYou are correct in the name for a remote in the pushed bundle, the names \ndo get convoluted, but then I'm not sure what the \"correct\" syntax would \nbe to refer to a remote repo's idea of a remote branch.\n\nMark\n"},{"id":"82223","messageId":"alpine.DEB.1.00.0807041420330.9925@racer","threadId":"14234","inReplyTo":"486E2245.6040404@gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-07-04T13:22:57Z","receivedAt":"2008-07-04T13:22:57Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 4 Jul 2008, Mark Levedahl wrote:\n\n> I'm using this for sneaker-netting, so I know the bundles are being \n> applied - clearly the create bundle and update in-tree basis steps could \n> be separated, but I don't use this for cases where I'm not sure the \n> bundle will be applied.\n\n/me wonders if it would not make sense to support \"git push <bundle>\", \nthen.  Maybe with a running counter, i.e.\n\n\t$ git push the-bundle-5.bundle master\n\nwould create the-bundle-6.bundle with everything needed in addition to \nthe-bundle-5.bundle to have the current \"master\".\n\nJust an idea,\nDscho\n"},{"id":"82230","messageId":"486E2A6B.7040905@verizon.net","threadId":"14234","inReplyTo":"alpine.DEB.1.00.0807041420330.9925@racer","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2008-07-04T13:49:31Z","receivedAt":"2008-07-04T13:49:31Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Johannes Schindelin wrote:\n> Hi,\n> \n> On Fri, 4 Jul 2008, Mark Levedahl wrote:\n> \n> \n> /me wonders if it would not make sense to support \"git push <bundle>\", \n> then.  Maybe with a running counter, i.e.\n> \n> \t$ git push the-bundle-5.bundle master\n> \n> would create the-bundle-6.bundle with everything needed in addition to \n> the-bundle-5.bundle to have the current \"master\".\n> \n> Just an idea,\n> Dscho\n> \n\nI think the trouble here is that the-bundle-5.bundle does not necessarily \ncontain the basis. Consider the general case of pushing master, next, pu, and \nonly pu has updated since the last push. Now, the-bundle-6.bundle will only \ncontain pu, not master nor next as there is nothing new, and thus is not a good \nbasis for creating the-bundle-7.bundle. This leads to a need for a meta-storage \nof basis or a redefinition of how git-bundle deals with refs that are equal to \nthe given basis (currently, it excludes such refs).\n\nMark\n"},{"id":"82240","messageId":"486E540D.8000008@gmail.com","threadId":"14234","inReplyTo":"alpine.DEB.1.00.0807040237580.2849@eeepc-johanness","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Mark Levedahl","fromEmail":"mlevedahl@gmail.com","sentAt":"2008-07-04T16:47:09Z","receivedAt":"2008-07-04T16:47:09Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Johannes Schindelin wrote:\n> I am not convinced.  This sort of feature belongs into git-bundle.  It \n> certainly does not deserve being blessed by yet-another git-* command, \n> when we are constantly being bashed for having _way_ too many _already_.\n>\n> Ciao,\n> Dscho\n>\n>   \nActually, I would like to see \"normal\" interface for git-bundle handled \nby git-push, git-fetch, and git-remote. We fixed the retrieve side to \nuse git-fetch before first integration, but didn't understand the \nsemantics for creation well-enough to put into git-push. Right now, we \ncan do \"git remote add bundle-nick <path-to-bundle>\" and set up the remote.\n\nWe should have \"git push bundle-nick\"  create the new bundle, updating \nthe basis refs kept somewhere in refs/* (possibly refs/remotes, possibly \nrefs/bundles?).\n\nHowever, we need two helpers to maintain the basis refs, both I believe \nshould be sub-commands of git-remote:\n\n- a \"rewind\" function to roll the refs back to a previous state because \nthe bundle didn't get applied, whatever. This is well supported by \nreflogs, is \"expire anything *newer* than time\", and for convenience \nshould apply to all refs for the given remote so the user doesn't have \nto invoke per branch on the remote. e.g., \"git remote rewind bundle-nick \n3.days.ago\".\n\n- a \"prune\" function to remove any branch for the remote that is not \nknown to the local refs/heads/* hierarchy. This is needed to support \ncleaning up pruned topic branches. Could be a special behavior of \"git \nremote prune\" triggered by the remote being a bundle, but that might be \nconfusing a perhaps need a new sub-command name. Perhaps, \"git remote \nprune-non-local bundle-nick\"\n\nIf we did the above, then git-bundle can be relegated to plumbing and \nbundles become better integrated to the porcelain.\n\nMark\n"},{"id":"82253","messageId":"20080704195110.GA3752@sigill.intra.peff.net","threadId":"14234","inReplyTo":"c376da900807031638l219229bcy983ed994b37512c9@mail.gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-07-04T19:51:11Z","receivedAt":"2008-07-04T19:51:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jul 03, 2008 at 07:38:21PM -0400, Adam Brewster wrote:\n\n> There's still plenty of potential for improvements, like a --gc mode\n> to clean up basis files, a --rewind option to undo an incorrect\n> --update, or improvements in the way it calculates intersections, but\n> I think that with these changes the system is as simple as possible\n> while maximizing flexibility, utility, and usability.\n\nI was thinking about Mark's approach, and I think there are two distinct\ndifferences from yours:\n\n  1. he updates the basis upon bundle creation, rather than as a\n     separate step (and I have already commented on this)\n\n  2. he stores the basis in the refs hierarchy\n\nI actually think '2' makes a lot of sense. Storing the basis as refs\ngets you:\n\n  - an easy implementation; you use existing git tools\n\n  - correct reachability analysis, since the refs will be taken into\n    account by git-fsck, meaning you won't ever accidentally prune\n    your basis objects\n\n  - free logging of your basis history, in the form of reflogs\n\n  - free gc in the usual reflog way\n\nIIRC, Mark suggested putting them under refs/remotes/<bundle>, and you\nobjected that you didn't want to clutter that hierarchy. If that is a\nproblem, you can always use refs/basis/<bundle>, which will be ignored\nby gitk and \"git branch -a\", but will be correctly handled by other\ntools.\n\nAnd then suddenly your perl script gets a lot simpler, and is either a\nshort shell script, or even better, can be written in C as part of\ngit-bundle. So you would have something like \"git bundle --update-basis\n<basis>\" instead of \"git-basis\", and a config option like\n\"bundle.autoUpdateBasis\" to update the basis whenever you create a\nbundle.\n\n-Peff\n"},{"id":"82256","messageId":"200807042255.46949.jnareb@gmail.com","threadId":"14234","inReplyTo":"486E540D.8000008@gmail.com","subject":"Re: [PATCH/v2] git-basis, a script to manage bases for git-bundle","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-07-04T20:55:45Z","receivedAt":"2008-07-04T20:55:45Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Mark Levedahl wrote:\n\n> We should have \"git push bundle-nick\"  create the new bundle, updating \n> the basis refs kept somewhere in refs/* (possibly refs/remotes, possibly \n> refs/bundles?).\n\nI think that because \"git push directory\" (local push) with error in\ndirectory name, which otherwise would result in error, can be mistaken\nfor \"git push bundle\", that we would want to either use pseudo-protocol\n(\"git push bundle://path/to/bundle\") or some extension...\n\n-- \nJakub Narebski\nPoland\n"}]}