{"thread":{"id":"6838","subject":"[PATCH] Include git-bundle and git-unbundle in Makefile.","startedAt":"2007-02-16T00:19:51Z","lastAt":"2007-02-16T11:57:20Z","messageCount":22,"participants":["Mark Levedahl","Junio C Hamano","Linus Torvalds","Shawn O. Pearce","Simon 'corecode' Schubert"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"34751","messageId":"11715851974102-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":null,"subject":"Respun - Scripts to use bundles to move data between repos","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:51Z","receivedAt":"2007-02-16T00:19:51Z","isPatch":false,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Respun patch for git-bundle / git-unbundle.\n\nI am working a project using git where we have many repositories on\nmachines that can never be directly connected, but which need to have\nthe same objects and development history.  Existing git protocols offer\nlimited support: we can either a) publish and apply patch files branch\nby branch, or b) copy an entire repository from one machine to another\nand then do local push or fetch.  While both are workable, neither is a\ncompletely satisfactory solution, so I wrote the attached scripts that\nsupport a \"bundle\" transfer mechanism.  A bundle is a tar archive having\ntwo files: a list of references as given by git-show-ref and a pack file\nof objects from git-pack-objects.  git-bundle creates the bundle,\ngit-unbundle unpacks and applies at the receiving end.  The means of\ntransporting the bundle file between the machines is arbitrary (sneaker\nnet, email, etc all can work).\n\nThis transfer protocol leaves it to the user to assure that the objects\nin the bundle are sufficient: git-fetch and git-push determine what is\nneeded by comparison, but no such conversation is possible here.  The\napproach is to specificy a range of commits to include in the bundle:\ne.g.  git-bundle master~10..master to get the last 10 commits.  Having\ntoo many is fine: git at the receiving end happily ignores duplicates.\nHaving too few objects raises an error and references are updated only\nif their full set of dependencies are found in the target repository.\n\n\n---\n\nThanks to all for comments on my previous set of patches on this topic,\nI have respun them, taking the following actions on the various\nsuggestions.\n\n1) Reformat help and .txt to fit 80 column screen: Done.\n\n2) Use tar for the bundle, not zip. Done.\n\n3) Link into main makefile: Done (including rename of git* to git*.sh\n\n4) Link into Documentation/cmd-list.perl: Done.\n\n5) Source git-sh-setup: Done (including removal of --bare and git dir\n   checks).\n\n6) Use git-index-pack rather than git-unpack-objects -Done.\n\n7) Pipe ref list directly into git-pack-objects. - doesn't handle\n   rev-list-args such as --since=5.days.ago, piping through git-rev-list\n   first does so I left it that way.\n\n8) Shallow option was broken - removed as non-essential and too hard to\n   fix. (can re-add properly later if someone really wants it).\n\n9) Dont use git-fsck, instead tell receiver what commits are needed\n   directly. Done, but with regrets. git-rev-list --objects-edge needs\n   to be taught to work when given --max-age, git-bundle calculates the\n   required result using a shell pipeline for the moment. Will revisit\n   after re-educating git-rev-list. (git-bundle does use git-rev-list\n   when --max-age is not present).\n\n10) Allow --output file, rather than --output=file. Rejected as this\n   required git-bundle to check arguments for git-rev-list rather than\n   letting git-rev-parse do that, or requires a specific ordering of\n   inputs. The first violates separation of functions (let git-rev-parse\n   handle errors on arguments it takes), or simply trades one annoyance\n   for another. No available solution is better than what is there now.\n\n11) Don't use temporary files in git-bundle. Left as is. Shell scrambles\n   binary data, so cannot be used to split out a binary pack file. This\n   is the service tar provides, and tar will only build from existing\n   files, so temporary files are needed unless this whole thing is\n   re-written in C.\n\n\nMark Levedahl\n"},{"id":"34748","messageId":"11715851972838-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"11715851974102-git-send-email-mdl123@verizon.net","subject":"[PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:52Z","receivedAt":"2007-02-16T00:19:52Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Some workflows require coordinated development between repositories on\nmachines that can never be connected. This utility creates a bundle\ncontaining a pack of objects and associated references (heads or tags)\nthat can be independently transferred to another machine, effectively\nsupporting git-push like operations between disconnected systems.\n\nSigned-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n git-bundle.sh |  103 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 103 insertions(+), 0 deletions(-)\n create mode 100755 git-bundle.sh\n\ndiff --git a/git-bundle.sh b/git-bundle.sh\nnew file mode 100755\nindex 0000000..c431b52\n--- /dev/null\n+++ b/git-bundle.sh\n@@ -0,0 +1,103 @@\n+#!/bin/sh\n+# Create a bundle to carry from one git repo to another\n+# (e.g., \"sneaker-net\" based push)\n+# git-bundle <git-rev-list args>\n+# git-bundle --bare <git-rev-list args>\n+# creates bundle.tar in current directory (can rename of course)\n+#\n+# The bundle includes all refs given (--all selects every ref in the repo).\n+# and all of the commit objects needed subject to the list given.\n+#\n+# Objects to be packed are limited by specifying one or more of\n+#   ^commit-ish    - indicated commits already at the target\n+#                    (can have more than one ^commit-ish)\n+#   --since=xxx    - Assume target repo has all relevant commits\n+#                    earlier than xxx\n+\n+USAGE='git-bundle [--output=file] <git-rev-list arguments>'\n+SUBDIRECTORY_OK=1\n+. git-sh-setup\n+\n+# pull out rev-list args vs program args, parse the latter\n+gitrevargs=$(git-rev-parse --symbolic --revs-only $*) || exit 1\n+myargs=$(git-rev-parse --no-revs $*) || exit 1\n+\n+bfile=bundle.tar\n+nextisoutput=\n+for arg in $myargs ; do\n+\tcase \"$arg\" in\n+\t\t-h|--h|--he|--hel|--help)\n+\t\t\techo \"$USAGE\"\n+\t\t\texit;;\n+\t\t--output=*)\n+\t\t\tbfile=${arg##--output=};;\n+\t\t*)\n+\t\t\tdie \"unknown option: $arg\";;\n+\tesac\n+done\n+\n+# find the refs to carry along and get sha1s for each.\n+refs=\n+fullrevargs=\n+for arg in $gitrevargs ; do\n+\t#ignore options and basis refs, get unambiguous ref name for things\n+\t# we will transport (e.g., user gives master, have heads/master and\n+\t# remotes/origin/master, we keep the former).\n+\tcase \"$arg\" in\n+\t\t-*) fullrevargs=\"$fullrevargs $arg\";;\n+\t\t^*) fullrevargs=\"$fullrevargs $arg\";;\n+\t\t*)\tref=$(git-show-ref \"$arg\" | head -n1)\n+\t\t\t[ -z \"$ref\" ] && die \"unknown reference: $arg\"\n+\t\t\tfullrevargs=\"$fullrevargs ${ref#* }\"\n+\t\t\trefs=\"$refs $ref\"\n+\t\t\t;;\n+\tesac\n+done\n+[ -z \"$refs\" ] && die \"No references specified, I don't know what to bundle.\"\n+\n+# git-rev-list cannot determine edge objects if a date restriction is given...\n+# we do things a slow way if max-age or min-age are given\n+fast=\n+[ \"${fullrevargs##*--max-age}\" == \"$fullrevargs\" ] && \\\n+[ \"${fullrevargs##*--min-age}\" == \"$fullrevargs\" ] && fast=1\n+\n+if [ -z \"$fast\" ] ; then\n+\t# get a list of all commits that will be packed along with parents of each.\n+\t# A fixed git-rev-list --boundary should replace all of this.\n+\techo \"Finding prerequisites and commits to bundle...\"\n+\tcommits=$(git-rev-list $fullrevargs)\n+\t\n+\t# get immediate parents of each commit to include\n+\tparents=\n+\tfor c in $commits ; do\n+\t\tparents=\"$parents $(git-rev-list --parents $c | head -1 | cut -b42-)\"\n+\tdone\n+\tparents=$(printf \"%s\\n\" $parents | sort | uniq)\n+\t\n+\t# factor out what will be in this bundle, the remainder are the bundle's pre-requisites.\n+\t# double up commits in this as we only want things that are only in parents to appear once\n+\tprereqs=$(printf \"%s\\n\" $parents $commits $commits | \\\n+\t\tsort | \\\n+\t\tuniq -c | \\\n+\t\tgrep ' 1 ' \\\n+\t\t| sed 's/ *1 //')\n+else\n+\tprereqs=$(git-rev-list --objects-edge $fullrevargs | \\\n+\t\tgrep '^-' | sed 's/-//')\n+fi\n+\n+# create refs and pack\n+[ -e \"$bfile\" ] && rm -f \"$bfile\" 2>/dev/null\n+printf \"%s\\n\" $prereqs > .gitBundleReferences\n+echo \"-\" >> .gitBundleReferences\n+git-show-ref $refs >> .gitBundleReferences\n+(git-rev-list --objects $fullrevargs | \\\n+\tcut -b-40 | \\\n+\tgit pack-objects --all-progress --stdout >.gitBundlePack) \\\n+\t|| (rm -f \"$bfile\" ; exit)\n+tar cf \"$bfile\"  .gitBundleReferences .gitBundlePack\n+tar cf \"$bfile\"  .gitBundleReferences .gitBundlePack\n+rm .gitBundleReferences .gitBundlePack\n+\n+# done\n+echo \"Created $bfile\"\n-- \n1.5.0.34.g6afaa\n"},{"id":"34749","messageId":"11715851973802-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"11715851972838-git-send-email-mdl123@verizon.net","subject":"[PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:53Z","receivedAt":"2007-02-16T00:19:53Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Some workflows require coordinated development between repositories on\nmachines that can never be connected. This utility unpacks a bundle\ncontaining objects and associated references (heads or tags) into the\ncurrent repository, effectively supporting git-push like operations\nbetween disconnected systems.\n\nSigned-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n git-unbundle.sh |   67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 67 insertions(+), 0 deletions(-)\n create mode 100755 git-unbundle.sh\n\ndiff --git a/git-unbundle.sh b/git-unbundle.sh\nnew file mode 100755\nindex 0000000..ca13305\n--- /dev/null\n+++ b/git-unbundle.sh\n@@ -0,0 +1,67 @@\n+#!/bin/sh\n+# unpack a git-bundle file into current repository\n+#\n+# See git-bundle.\n+\n+USAGE=\"usage: git-unbundle [-f|--force] [file]\"\n+SUBDIRECTORY_OK=1\n+. git-sh-setup\n+\n+bfile=bundle.tar\n+force=\n+while case \"$#\" in 0) break ;; esac\n+do\n+\tcase \"$1\" in\n+\t-f|--f|--fo|--for|--forc|--force)\n+\t\tforce=1;;\n+\t-h|--h|--he|--hel|--help)\n+\t\tusage;;\n+\t-*)\n+\t\tdie \"unknown option: $1\";;\n+\t*)\n+\t\tbfile=\"$1\";;\n+\tesac\n+\tshift\n+done\n+\n+[ -e \"$bfile\" ] || die \"cannot find $bfile\"\n+\n+# Get prereqs and refs in one go to avoid a third tar invocation.\n+# Prereqs come first, are separated by a single - from the actual refs.\n+refdata=$(tar -f \"$bfile\" -x --to-stdout  .gitBundleReferences)\n+prereqs=\"${refdata%%-*}\"\n+refs=\"${refdata#*-}\"\n+\n+# check that the prerequisites exist before unbundling.\n+for sha1 in $prereqs ; do\n+\tgit-rev-parse --verify $sha1 >& /dev/null || die \"Prerequisite commit $sha1 not found.\"\n+done\n+\n+# get the objects, maybe repack\n+tar -f \"$bfile\" -x --to-stdout .gitBundlePack | git-index-pack --stdin\n+\n+# check each reference, assure that the result would be valid before updating local ref\n+printf \"%s %s\\n\" $refs | while read sha1 ref ; do\n+\tok=\n+\tif [ -z \"$force\" ] ; then\n+\t\t# update only if non-fastforward\n+\t\tlocal=$(git-rev-parse --verify \"$ref^0\" 2>/dev/null)\n+\t\tif [ ! -z \"$local\" ] ; then\n+\t\t\tmb=$(git-merge-base $local $sha1)\n+\t\t\tif [ \"$mb\" != \"$local\" ] ; then\n+\t\t\t\techo \"Not applying non-fast forward update: $ref\"\n+\t\t\telse\n+\t\t\t\tok=1\n+\t\t\tfi\n+\t\telse\n+\t\t\tok=1\n+\t\tfi\n+\telse\n+\t\t#forced, accept non-fast forward update\n+\t\tok=1\n+\tfi\n+\tif [ ! -z \"$ok\" ] ; then\n+\t\techo \"updating: $ref to $sha1\"\n+\t\tgit-update-ref -m \"git-unbundle update\" $ref $sha1\n+\tfi\n+done\n-- \n1.5.0.34.g6afaa\n"},{"id":"34747","messageId":"11715851973121-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"11715851973802-git-send-email-mdl123@verizon.net","subject":"[PATCH] Include git-bundle and git-unbundle in Makefile.","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:54Z","receivedAt":"2007-02-16T00:19:54Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Signed-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n Makefile |    3 ++-\n 1 files changed, 2 insertions(+), 1 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex ebecbbd..c2be7a7 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -177,7 +177,8 @@ SCRIPT_SH = \\\n \tgit-applymbox.sh git-applypatch.sh git-am.sh \\\n \tgit-merge.sh git-merge-stupid.sh git-merge-octopus.sh \\\n \tgit-merge-resolve.sh git-merge-ours.sh \\\n-\tgit-lost-found.sh git-quiltimport.sh\n+\tgit-lost-found.sh git-quiltimport.sh \\\n+\tgit-bundle.sh git-unbundle.sh\n \n SCRIPT_PERL = \\\n \tgit-add--interactive.perl \\\n-- \n1.5.0.34.g6afaa\n"},{"id":"34752","messageId":"11715851973628-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"11715851973121-git-send-email-mdl123@verizon.net","subject":"[PATCH] Create documentation for git-bundle.","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:55Z","receivedAt":"2007-02-16T00:19:55Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Signed-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n Documentation/git-bundle.txt |   87 ++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 87 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-bundle.txt\n\ndiff --git a/Documentation/git-bundle.txt b/Documentation/git-bundle.txt\nnew file mode 100644\nindex 0000000..aed413f\n--- /dev/null\n+++ b/Documentation/git-bundle.txt\n@@ -0,0 +1,87 @@\n+git-bundle(1)\n+=============\n+\n+NAME\n+----\n+git-bundle - Package objects and refs for a disconnected repository\n+\n+\n+SYNOPSIS\n+--------\n+'git-bundle' [--output=file] <git-rev-list args>\n+\n+DESCRIPTION\n+-----------\n+\n+Some workflows require that one or more branches of development on\n+one machine be replicated on another machine, but the two machines\n+cannot be directly connected so the git-fetch protocol cannot be used.\n+This command creates a bundle file containing objects and references\n+that can be used to update another repository (using\n+gitlink:git-unbundle[1]) without phsyically connecting the two.  As no\n+direct connection exists, the user must specify a basis for the bundle\n+that is held by the destination repository: the bundle assumes that\n+all objects in the basis are already in the destination repository.\n+\n+OPTIONS\n+-------\n+\n+--output=file::\n+\tSpecifies the name of the bundle file. Default is\n+        \"bundle.tar\" in the current directory.\n+\n+<git-rev-list args>::\n+\n+        A list of arguments, accepatble to git-rev-parse and\n+        git-rev-list, that specify the specific objects and\n+        references to transport. For example,  \"master~10..master\"\n+        causes the current master reference to be packaged along with\n+        all objects added since its 10th ancestor commit. There is no\n+        explicit limit to the number of references and objects that\n+        may be packaged.\n+\n+\n+SPECIFYING REFERENCES\n+---------------------\n+\n+git-bundle will only package references that are shown by\n+git-show-ref: this includes heads, tags, and remote heads.  References\n+such as master~1 cannot be packaged, but are perfectly suitable for\n+defining the basis.  More than one reference may be packaged, and more\n+than one basis can be specified.  The objects packaged are those not\n+contained in the union of the given bases.  Each basis can be\n+specified explicitly (e.g., ^master~10), or implicitly (e.g.,\n+master~10..master, master --since=10.days.ago).\n+\n+It is very important that the basis used be held by the destination.\n+It is ok to err on the side of conservatism, causing the bundle file\n+to contain objects already in the destination as these are ignored\n+when unpacking at the destination.\n+\n+EXAMPLE\n+-------\n+\n+Assume two repositories exist as R1 on machine A, and R2 on machine B.\n+For whatever reason, direct connection between A and B is not allowed,\n+but we can move data from A to B via some mechanism (CD, email, etc).\n+We want to update R2 with developments made on branch master in R1.\n+We set a tag in R1 (lastR2bundle) after the previous such transport,\n+and move it afterwards to help build the bundle.\n+\n+in R1 on A:\n+git-bundle master ^lastR2bundle\n+git tag -f lastR2bundle master\n+\n+(move bundle.tar from A to B by some mechanism)\n+\n+in R2 on B:\n+git-unbundle bundle.tar (3)\n+\n+\n+Author\n+------\n+Written by Mark Levedahl <mdl123@verizon.net>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n-- \n1.5.0.34.g6afaa\n"},{"id":"34753","messageId":"1171585197833-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"11715851973628-git-send-email-mdl123@verizon.net","subject":"[PATCH] Create documentation for git-unbundle.","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:56Z","receivedAt":"2007-02-16T00:19:56Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Signed-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n Documentation/git-unbundle.txt |   48 ++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 48 insertions(+), 0 deletions(-)\n create mode 100644 Documentation/git-unbundle.txt\n\ndiff --git a/Documentation/git-unbundle.txt b/Documentation/git-unbundle.txt\nnew file mode 100644\nindex 0000000..99713ce\n--- /dev/null\n+++ b/Documentation/git-unbundle.txt\n@@ -0,0 +1,48 @@\n+git-unbundle(1)\n+===============\n+\n+NAME\n+----\n+git-unbundle - Unpackage objects and refs\n+\n+SYNOPSIS\n+--------\n+'git-unbundle' [--force] file\n+\n+DESCRIPTION\n+-----------\n+\n+Some workflows require that one or more branches of development on one\n+machine be replicated on another machine, but the two machines cannot\n+be directly connected so the gitlink:git-fetch[1] protocol cannot be\n+used.  This command unpacks a bundle file created by\n+gitlink:git-bundle[1] on another repository, adding the objects and\n+updating references as defined by the donor repository.\n+\n+OPTIONS\n+-------\n+\n+--force::\n+        Normally only fast-forward reference updates are performed.\n+        Specifying this option allows non-fast forward updates.\n+\n+file::\n+        Bundle file created by gitlink:git-bundle[1]. Default is\n+        bundle.tar.\n+\n+ERROR CHECKING\n+--------------\n+\n+In addition to the checks mentioned under --force above, the bundle\n+includes a list of prerequisite commits needed. If any prerequisite is\n+not present, git-unbundle stops. The repository is updated using\n+gitlink:git-index-pack[1] and gitlink:git-update-ref[1] which assure\n+that the pack is readable and that references are updated correctly.\n+\n+Author\n+------\n+Written by Mark Levedahl <mdl123@verizon.net>\n+\n+GIT\n+---\n+Part of the gitlink:git[7] suite\n-- \n1.5.0.34.g6afaa\n"},{"id":"34750","messageId":"1171585197120-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"1171585197833-git-send-email-mdl123@verizon.net","subject":"[PATCH] Link git-bundle and git-unbundle docs from git(7).","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T00:19:57Z","receivedAt":"2007-02-16T00:19:57Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Signed-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n Documentation/cmd-list.perl |    2 ++\n 1 files changed, 2 insertions(+), 0 deletions(-)\n mode change 100755 => 100644 Documentation/cmd-list.perl\n\ndiff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl\nold mode 100755\nnew mode 100644\nindex a2d6268..3a22083\n--- a/Documentation/cmd-list.perl\n+++ b/Documentation/cmd-list.perl\n@@ -70,6 +70,7 @@ git-archive                             mainporcelain\n git-bisect                              mainporcelain\n git-blame                               ancillaryinterrogators\n git-branch                              mainporcelain\n+git-bundle                              mainporcelain\n git-cat-file                            plumbinginterrogators\n git-checkout-index                      plumbingmanipulators\n git-checkout                            mainporcelain\n@@ -172,6 +173,7 @@ git-svnimport                           foreignscminterface\n git-symbolic-ref                        plumbingmanipulators\n git-tag                                 mainporcelain\n git-tar-tree                            plumbinginterrogators\n+git-unbundle                            mainporcelain\n git-unpack-file                         plumbinginterrogators\n git-unpack-objects                      plumbingmanipulators\n git-update-index                        plumbingmanipulators\n-- \n1.5.0.34.g6afaa\n"},{"id":"34759","messageId":"7vodnuc0me.fsf@assigned-by-dhcp.cox.net","threadId":"6838","inReplyTo":"11715851972838-git-send-email-mdl123@verizon.net","subject":"Re: [PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-16T02:11:37Z","receivedAt":"2007-02-16T02:11:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> writes:\n\n> +# find the refs to carry along and get sha1s for each.\n> +refs=\n> +fullrevargs=\n> +for arg in $gitrevargs ; do\n> +\t#ignore options and basis refs, get unambiguous ref name for things\n> +\t# we will transport (e.g., user gives master, have heads/master and\n> +\t# remotes/origin/master, we keep the former).\n\nI am not sure if that is a good behaviour.  What if user gives\nxyzzy and there are tags/xyzzy and remotes/origin/xyzzy?\n\nI suspect it would be much safer to error out in ambiguous cases.\n\n> +# we do things a slow way if max-age or min-age are given\n> +fast=\n> +[ \"${fullrevargs##*--max-age}\" == \"$fullrevargs\" ] && \\\n> +[ \"${fullrevargs##*--min-age}\" == \"$fullrevargs\" ] && fast=1\n\nStyle.\n\nOur scripts tend to spell the test command \"test\" and equality test\noperator as single '='.  Also they tend to say:\n\n        case \"$fullrevargs\" in\n        *--max-age* | *--min-age*) ... \n        esac\n\n> +\t# get immediate parents of each commit to include\n> +\tparents=\n> +\tfor c in $commits ; do\n> +\t\tparents=\"$parents $(git-rev-list --parents $c | head -1 | cut -b42-)\"\n> +\tdone\n\nNicely done, but you seemed to have used \"head -n 1\" elsewhere,\nwhich is more portable.\n\n> +\t# factor out what will be in this bundle, the remainder are the bundle's pre-requisites.\n> +\t# double up commits in this as we only want things that are only in parents to appear once\n> +\tprereqs=$(printf \"%s\\n\" $parents $commits $commits | \\\n> +\t\tsort | \\\n> +\t\tuniq -c | \\\n> +\t\tgrep ' 1 ' \\\n> +\t\t| sed 's/ *1 //')\n\nDon't pipe output of grep to sed ;-).\n\n> +else\n> +\tprereqs=$(git-rev-list --objects-edge $fullrevargs | \\\n> +\t\tgrep '^-' | sed 's/-//')\n> +fi\n\nLikewise.  The latter is:\n\n\t... | sed -ne 's/^-//p'\n\n> +# create refs and pack\n> +[ -e \"$bfile\" ] && rm -f \"$bfile\" 2>/dev/null\n> +printf \"%s\\n\" $prereqs > .gitBundleReferences\n\nOur scripts assume $GIT_DIR/ is writable but not necessarily the\nworking directory when they have to use temporary files.  Also\nplease clean temporaries even when you error out with traps.\n\n\ttmp=$GIT_DIR/bundle_tmp$$\n\treferences=\"$tmp-references\"\n        pack=\"$tmp-pack\"\n        trap 'rm -f \"$tmp-*\"' 0 1 2 3 15\n\n        echo \"-\" >>\"$references\" &&\n        git-show-ref $refs >>\"$references\" &&\n        (git-rev-list ... >\"$pack\") || exit\n"},{"id":"34760","messageId":"7vire2c00i.fsf@assigned-by-dhcp.cox.net","threadId":"6838","inReplyTo":"11715851973802-git-send-email-mdl123@verizon.net","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-16T02:24:45Z","receivedAt":"2007-02-16T02:24:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> writes:\n\n> +# check that the prerequisites exist before unbundling.\n> +for sha1 in $prereqs ; do\n> +\tgit-rev-parse --verify $sha1 >& /dev/null || die \"Prerequisite commit $sha1 not found.\"\n> +done\n\nIf you are checking only boundary commits this is too weak a\ncheck and unsafe (we used to have the same bug in http fetch\nlong time ago).  You have to make sure not only the object\nexists, but also it is reachable by one of the refs.\n\nOne way to check that would be to ask \"describe --all\" if it can\nfind a ref that can reach that commit.  It would error out if\nthe commit object exists but is not reachable from any of the\nrefs.\n"},{"id":"34761","messageId":"Pine.LNX.4.64.0702151838250.20368@woody.linux-foundation.org","threadId":"6838","inReplyTo":"7vire2c00i.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2007-02-16T02:40:32Z","receivedAt":"2007-02-16T02:40:32Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Thu, 15 Feb 2007, Junio C Hamano wrote:\n> \n> One way to check that would be to ask \"describe --all\" if it can\n> find a ref that can reach that commit.  It would error out if\n> the commit object exists but is not reachable from any of the\n> refs.\n\nActually, more efficient and to the point:\n\n\tlist-all-boundary-sha1s |\n\t\tgit-rev-list --stdin --not --all\n\nshould return empty. Or something like that.\n\n\t\tLinus\n"},{"id":"34766","messageId":"20070216043732.GA28894@spearce.org","threadId":"6838","inReplyTo":"11715851974102-git-send-email-mdl123@verizon.net","subject":"Re: Respun - Scripts to use bundles to move data between repos","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-16T04:37:32Z","receivedAt":"2007-02-16T04:37:32Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> wrote:\n> 7) Pipe ref list directly into git-pack-objects. - doesn't handle\n>    rev-list-args such as --since=5.days.ago, piping through git-rev-list\n>    first does so I left it that way.\n\nYuck.  I just went back and looked at the pack-objects source.\n\nApparently we only accept ref names and SHA-1 values here, and\n`--not` on a line by itself.  Nothing else is valid.\n\nThe documentation is a little misleading, as usually when we say\nsomething is processed the same way as rev-list does it we usually\nalso mean that any valid option to rev-list is also a valid option\nin that context.  Here its not.\n\n-- \nShawn.\n"},{"id":"34767","messageId":"20070216044158.GB28894@spearce.org","threadId":"6838","inReplyTo":"7vodnuc0me.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-16T04:41:58Z","receivedAt":"2007-02-16T04:41:58Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Mark Levedahl <mdl123@verizon.net> writes:\n> > +# we do things a slow way if max-age or min-age are given\n> > +fast=\n> > +[ \"${fullrevargs##*--max-age}\" == \"$fullrevargs\" ] && \\\n> > +[ \"${fullrevargs##*--min-age}\" == \"$fullrevargs\" ] && fast=1\n> \n> Style.\n> \n> Our scripts tend to spell the test command \"test\" and equality test\n> operator as single '='.\n\nUsing \"test\" is a style thing, but using \"=\" rather than \"==\" is\na portability issue.  \"==\" is accepted by bash as a synonym for\n\"=\", but its not valid elsewhere.\n\nI've made my fair share of patches with \"==\" in them, only to have\nsomeone else have a problem on their system and then submit a fix to\nchange them to \"=\".  Just say no to \"==\" in Git shell scripts.  ;-)\n \n> > +\t# get immediate parents of each commit to include\n> > +\tparents=\n> > +\tfor c in $commits ; do\n> > +\t\tparents=\"$parents $(git-rev-list --parents $c | head -1 | cut -b42-)\"\n> > +\tdone\n> \n> Nicely done, but you seemed to have used \"head -n 1\" elsewhere,\n> which is more portable.\n\nWhat about:\n\n\tparents=\"$parents $(git-rev-list --max-count=1 --parents $c | cut -b42-)\"\n\n?\n\nI just used that trick recently.  Oh yea it was in git-gui's\nGIT-VERSION-GEN script.  Though I did not know about using cut\nlike that...\n \n-- \nShawn.\n"},{"id":"34770","messageId":"45D54DB0.4090300@verizon.net","threadId":"6838","inReplyTo":"7vire2c00i.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T06:22:40Z","receivedAt":"2007-02-16T06:22:40Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Junio C Hamano wrote:\n> Mark Levedahl <mdl123@verizon.net> writes:\n>\n>   \n>> +# check that the prerequisites exist before unbundling.\n>> +for sha1 in $prereqs ; do\n>> +\tgit-rev-parse --verify $sha1 >& /dev/null || die \"Prerequisite commit $sha1 not found.\"\n>> +done\n>>     \n>\n> If you are checking only boundary commits this is too weak a\n> check and unsafe (we used to have the same bug in http fetch\n> long time ago).  You have to make sure not only the object\n> exists, but also it is reachable by one of the refs.\n>\n> One way to check that would be to ask \"describe --all\" if it can\n> find a ref that can reach that commit.  It would error out if\n> the commit object exists but is not reachable from any of the\n> refs\nI'm not sure I follow the logic here. Assuming the object is a \nprerequisite of the bundle and exists, it will be reachable from an \nupdated reference once the bundle is applied, no? In any case, Linus' \nsuggestion is very neat and fast, and I presume reliable.\n\nMark\n"},{"id":"34771","messageId":"11716079211954-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"Pine.LNX.4.64.0702151838250.20368@woody.linux-foundation.org","subject":"[PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T06:38:41Z","receivedAt":"2007-02-16T06:38:41Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Some workflows require coordinated development between repositories on\nmachines that can never be connected. This utility unpacks a bundle\ncontaining objects and associated references (heads or tags) into the\ncurrent repository, effectively supporting git-push like operations\nbetween disconnected systems.\n\nSigned-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n git-unbundle.sh |   68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 68 insertions(+), 0 deletions(-)\n create mode 100755 git-unbundle.sh\n\ndiff --git a/git-unbundle.sh b/git-unbundle.sh\nnew file mode 100755\nindex 0000000..c947f15\n--- /dev/null\n+++ b/git-unbundle.sh\n@@ -0,0 +1,68 @@\n+#!/bin/sh\n+# unpack a git-bundle file into current repository\n+#\n+# See git-bundle.\n+\n+USAGE=\"usage: git-unbundle [-f|--force] [file]\"\n+SUBDIRECTORY_OK=1\n+. git-sh-setup\n+\n+bfile=bundle.tar\n+force=\n+while case \"$#\" in 0) break ;; esac\n+do\n+    case \"$1\" in\n+    -f|--f|--fo|--for|--forc|--force)\n+        force=1;;\n+    -h|--h|--he|--hel|--help)\n+        usage;;\n+    -*)\n+        die \"unknown option: $1\";;\n+    *)\n+        bfile=\"$1\";;\n+    esac\n+    shift\n+done\n+\n+test -e \"$bfile\" || die \"cannot find $bfile\"\n+\n+# Get prereqs and refs in one go to avoid a third tar invocation.\n+# Have a header line with version, prereqs, then references.\n+references=$(tar -xf \"$bfile\" --to-stdout references)\n+refdata=${references##v1*prerequisites}\n+test \"$references\" = \"$refdata\" && die \"This doesn't look like a v1 bundle file.\"\n+prereqs=\"${refdata%%references*}\"\n+refs=\"${refdata#*references}\"\n+\n+# make sure prerequisites are available\n+test -n \"$prereqs\" && printf \"%s\\n\" $prereqs | \\\n+    git-rev-list --stdin --not --all || exit 1\n+\n+# get the pack file\n+tar -xf \"$bfile\" --to-stdout pack | git-index-pack --stdin || exit 1\n+\n+# check each reference, avoid non-fast forward update unless forced\n+printf \"%s %s\\n\" $refs | while read sha1 ref ; do\n+    ok=\n+    if test -z \"$force\" ; then\n+        # update only if non-fastforward\n+        local=$(git-rev-parse --verify \"$ref^0\" 2>/dev/null)\n+        if test -n \"$local\"  ; then\n+            mb=$(git-merge-base $local $sha1)\n+            if test \"$mb\" != \"$local\" ; then\n+                echo \"Not applying non-fast forward update: $ref\"\n+            else\n+                ok=1\n+            fi\n+        else\n+            ok=1\n+        fi\n+    else\n+        #forced, accept non-fast forward update\n+        ok=1\n+    fi\n+    if test -n \"$ok\" ; then\n+        echo \"updating: $ref to $sha1\"\n+        git-update-ref -m \"git-unbundle update\" $ref $sha1\n+    fi\n+done\n-- \n1.5.0.rc4.375.gd0938-dirty\n"},{"id":"34772","messageId":"11716079843500-git-send-email-mdl123@verizon.net","threadId":"6838","inReplyTo":"7vodnuc0me.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Mark Levedahl","fromEmail":"mdl123@verizon.net","sentAt":"2007-02-16T06:39:44Z","receivedAt":"2007-02-16T06:39:44Z","isPatch":true,"sender":{"key":"mdl123@verizon.net","avatar":"https://avatars.githubusercontent.com/u/5302462?v=4"},"body":"Some workflows require coordinated development between repositories on\nmachines that can never be connected. This utility creates a bundle\ncontaining a pack of objects and associated references (heads or tags)\nthat can be independently transferred to another machine, effectively\nsupporting git-push like operations between disconnected systems.\n\nSigned-off-by: Mark Levedahl <mdl123@verizon.net>\n---\n git-bundle.sh |  112 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 112 insertions(+), 0 deletions(-)\n create mode 100755 git-bundle.sh\n\ndiff --git a/git-bundle.sh b/git-bundle.sh\nnew file mode 100755\nindex 0000000..f56f499\n--- /dev/null\n+++ b/git-bundle.sh\n@@ -0,0 +1,112 @@\n+#!/bin/sh\n+# Create a bundle to carry from one git repo to another\n+# (e.g., \"sneaker-net\" based push)\n+# git-bundle <git-rev-list args>\n+# git-bundle --bare <git-rev-list args>\n+# creates bundle.tar in current directory (can rename of course)\n+#\n+# The bundle includes all refs given (--all selects every ref in the repo).\n+# and all of the commit objects needed subject to the list given.\n+#\n+# Objects to be packed are limited by specifying one or more of\n+#   ^commit-ish    - indicated commits already at the target\n+#                    (can have more than one ^commit-ish)\n+#   --since=xxx    - Assume target repo has all relevant commits\n+#                    earlier than xxx\n+\n+USAGE='git-bundle [-o file | --output=file] <git-rev-list arguments>'\n+SUBDIRECTORY_OK=1\n+. git-sh-setup\n+\n+bfile=bundle.tar\n+args=\n+while test -n \"$1\" ; do\n+    case $1 in\n+        -h|--h|--he|--hel|--help)\n+            echo \"$USAGE\"\n+            exit;;\n+        --output=*)\n+            bfile=${1##--output=};;\n+        -o|--output)\n+            shift\n+            bfile=$1;;\n+        *)\n+            args=\"$args $1\"\n+    esac\n+    shift\n+done\n+\n+unknown=$(git-rev-parse --no-revs $args)\n+test -z \"$unknown\" || die \"unknown option: $unknown\"\n+gitrevargs=$(git-rev-parse --symbolic --revs-only $args) || exit 1\n+\n+# find the refs to carry along and get sha1s for each.\n+refs=\n+fullrevargs=\n+for arg in $gitrevargs ; do\n+    #ignore options and basis refs, get unambiguous ref name for things\n+    # we will transport (e.g., user gives master, have heads/master and\n+    # remotes/origin/master, we keep the former).\n+    case \"$arg\" in\n+        -*) fullrevargs=\"$fullrevargs $arg\";;\n+        ^*) fullrevargs=\"$fullrevargs $arg\";;\n+        *)  ref=$(git-show-ref \"$arg\")\n+            test \"$(echo $ref | wc -w)\" = \"2\" || die \"Ambigous reference: $arg\n+$ref\"\n+            fullrevargs=\"$fullrevargs ${ref#* }\"\n+            refs=\"$refs $ref\"\n+            ;;\n+    esac\n+done\n+test -z \"$refs\" && die \"No references specified, I don't know what to bundle.\"\n+\n+# git-rev-list cannot determine edge objects if a date restriction is\n+# given...  we do things a slow way if max-age or min-age are given\n+case \"$fullrevargs\" in\n+    *--max-age* | *--min-age*)\n+    # get a list of all commits that will be packed along with\n+    # parents of each.  A fixed git-rev-list --boundary should\n+    # replace all of this.\n+    echo \"Finding prerequisites and commits to bundle...\"\n+    commits=$(git-rev-list $fullrevargs)\n+\n+    # get immediate parents of each commit to include\n+    parents=\n+    for c in $commits ; do\n+        parents=\"$parents $(git-rev-list --parents --max-count=1 $c | cut -b42-)\"\n+    done\n+    parents=$(printf \"%s\\n\" $parents | sort | uniq)\n+\n+    # factor out what will be in this bundle, the remainder are the\n+    # bundle's prerequisites.  double up commits in this as we only\n+    # want things that are only in parents to appear once\n+    prereqs=$(printf \"%s\\n\" $parents $commits $commits | \\\n+        sort | uniq -c | sed -ne 's/^ *1 //p');;\n+    *)\n+        prereqs=$(git-rev-list --objects-edge $fullrevargs | sed -ne 's/^-//p');;\n+esac\n+\n+# create refs and pack\n+tmp=$GIT_DIR/bundle_tmp$$\n+references=\"$tmp-references\"\n+pack=\"$tmp-pack\"\n+trap 'rm -f \"$references\" \"$pack\"' 0 1 2 3 15\n+\n+echo \"v1\" > \"$references\" &&\n+echo \"prerequisites\" >> \"$references\" &&\n+printf \"%s\\n\" $prereqs >> \"$references\" &&\n+echo \"references\" >> \"$references\" &&\n+git-show-ref $refs >> \"$references\" &&\n+(git-rev-list --objects $fullrevargs | \\\n+    cut -b-40 | \\\n+    git pack-objects --all-progress --stdout >> \"$pack\" ) \\\n+    || exit\n+\n+# create the tar file, clean up\n+tar cf \"$bfile\" --absolute-names --transform=\"s,$tmp-,,\" \\\n+    --verbose --show-transformed-names \\\n+    \"$references\" \"$pack\"\n+rm -f \"$pack\" \"$references\"\n+\n+# done\n+echo \"Created $bfile\"\n-- \n1.5.0.rc4.375.gd0938-dirty\n"},{"id":"34773","messageId":"20070216064852.GF28894@spearce.org","threadId":"6838","inReplyTo":"11716079211954-git-send-email-mdl123@verizon.net","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-16T06:48:52Z","receivedAt":"2007-02-16T06:48:52Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> wrote:\n> +        # update only if non-fastforward\n> +        local=$(git-rev-parse --verify \"$ref^0\" 2>/dev/null)\n> +        if test -n \"$local\"  ; then\n> +            mb=$(git-merge-base $local $sha1)\n> +            if test \"$mb\" != \"$local\" ; then\n> +                echo \"Not applying non-fast forward update: $ref\"\n> +            else\n> +                ok=1\n> +            fi\n> +        else\n> +            ok=1\n> +        fi\n> +    else\n> +        #forced, accept non-fast forward update\n> +        ok=1\n> +    fi\n> +    if test -n \"$ok\" ; then\n> +        echo \"updating: $ref to $sha1\"\n> +        git-update-ref -m \"git-unbundle update\" $ref $sha1\n\nWhat about passing $local as the final argument to update-ref,\nso that the ref won't be modified if someone changed it while\nan unbundle was running?  Sure its mostly a manual operation,\nbut imagine running it on a bare repository while someone else\nis pushing into it...\n\n-- \nShawn.\n"},{"id":"34774","messageId":"20070216065421.GG28894@spearce.org","threadId":"6838","inReplyTo":"11716079843500-git-send-email-mdl123@verizon.net","subject":"Re: [PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-16T06:54:21Z","receivedAt":"2007-02-16T06:54:21Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> wrote:\n> +# create the tar file, clean up\n> +tar cf \"$bfile\" --absolute-names --transform=\"s,$tmp-,,\" \\\n> +    --verbose --show-transformed-names \\\n> +    \"$references\" \"$pack\"\n\nI'm not sure this will work on FreeBSD.  Both 5.1 and 6.1 use tar\nthat does not know about --absolute-names, --transform, --verbose,\nor --show-transformed-names.\n\n-- \nShawn.\n"},{"id":"34775","messageId":"7vk5yia7l7.fsf@assigned-by-dhcp.cox.net","threadId":"6838","inReplyTo":"45D54DB0.4090300@verizon.net","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-16T07:24:04Z","receivedAt":"2007-02-16T07:24:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Mark Levedahl <mdl123@verizon.net> writes:\n\n> I'm not sure I follow the logic here. Assuming the object is a\n> prerequisite of the bundle and exists, it will be reachable from an\n> updated reference once the bundle is applied, no?\n\nNo.  That's not the point.  Yes, the object might be reachable,\nbut you haven't proven that everything necessary to complete\nthat object is already in the object store.  We never trust\nexistence of an object alone when doing an operation that\nupdates a ref.  Having unreferenced objects in the object store\nis a norm, but refs pointing at an object, some of whose\nprerequisites are missing, is a crime.\n\nFor example, suppose an earlier http-fetch found that the\nupdated master should be at commit 'x', downloaded 'x', and you\nkilled the process with ^C.  It died without updating\nrefs/remotes/origin/master, which is good.  Then you have a\nbundle to unpack that has 'x' as a boundary.\n\nYou would start with a repository like this:\n\n  ---o---o---o...-...-...-...x\n             ^origin.\n\nwhere 'x' is a dangling commit, '-' are ones that you do not\nhave but you ought to have them in order for 'x' to be complete,\nand 'o' are complete commits.  If the bundle boundary falls on\nthe 'x' commit, you cannot say \"I have all that are needed to\ncomplete this 'x'\".  You only have 'x' but still lack its\nprerequisites.  That's what it means never to trust the mere\nexistence of an object.\n\nLinus's suggestion would make rev-list barf when 'x' cannot\nreach any existing ref, which is a good solution for this\nproblem.\n\nAlso as Shawn pointed out, the script too heavily depends on GNU\ntar.  Can we do something about it?  Requiring GNU tar is\nprobably fine if the script absolutely needs its extended\nfeatures, as long as people have ways to tweak the command name\nin the script to point at their installed GNU tar (remember,\nsome systems have GNU tar under different name such as \"gtar\").\n\nAlthough if we require GNU tar we might be better off placing\nthis under contrib/ not at the toplevel.  I dunno.\n"},{"id":"34776","messageId":"7vd54aa7dr.fsf@assigned-by-dhcp.cox.net","threadId":"6838","inReplyTo":"20070216044158.GB28894@spearce.org","subject":"Re: [PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-16T07:28:32Z","receivedAt":"2007-02-16T07:28:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> Using \"test\" is a style thing, but using \"=\" rather than \"==\" is\n> a portability issue.  \"==\" is accepted by bash as a synonym for\n> \"=\", but its not valid elsewhere.\n\nTrue, I should have stressed that.  Thanks.  Also in the same\nsense (but to a lessor degree), \"test\" vs \"[\" is also\nportability issue.\n\n> What about:\n>\n> \tparents=\"$parents $(git-rev-list --max-count=1 --parents $c | cut -b42-)\"\n>\n> I just used that trick recently.  Oh yea it was in git-gui's\n> GIT-VERSION-GEN script.  Though I did not know about using cut\n> like that...\n\nI used to stay away from 'cut' myself, although it is not too\nbad for portability these days.  I would probably have done the\nabove with a single sed process, though.\n"},{"id":"34778","messageId":"7v4ppma788.fsf@assigned-by-dhcp.cox.net","threadId":"6838","inReplyTo":"20070216064852.GF28894@spearce.org","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-02-16T07:31:51Z","receivedAt":"2007-02-16T07:31:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Shawn O. Pearce\" <spearce@spearce.org> writes:\n\n> Mark Levedahl <mdl123@verizon.net> wrote:\n>> +        # update only if non-fastforward\n>> +        local=$(git-rev-parse --verify \"$ref^0\" 2>/dev/null)\n>> ...\n>> +        git-update-ref -m \"git-unbundle update\" $ref $sha1\n>\n> What about passing $local as the final argument to update-ref,\n> so that the ref won't be modified if someone changed it while\n> an unbundle was running?  Sure its mostly a manual operation,\n> but imagine running it on a bare repository while someone else\n> is pushing into it...\n\nThe script already has $local at that point, so adding it to\nupdate-ref is a no-cost change to make things safer.  I think it\nmakes sense.\n\nBut I have to wonder...  While someone else is _pushing_ into\nit?  Why are _you_ sneakernetting, then?\n"},{"id":"34779","messageId":"20070216074503.GH28894@spearce.org","threadId":"6838","inReplyTo":"7v4ppma788.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] Add git-unbundle - unpack objects and references for disconnected transfer","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-02-16T07:45:03Z","receivedAt":"2007-02-16T07:45:03Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> \"Shawn O. Pearce\" <spearce@spearce.org> writes:\n> > Mark Levedahl <mdl123@verizon.net> wrote:\n> >> +        # update only if non-fastforward\n> >> +        local=$(git-rev-parse --verify \"$ref^0\" 2>/dev/null)\n> >> ...\n> >> +        git-update-ref -m \"git-unbundle update\" $ref $sha1\n> >\n> > What about passing $local as the final argument to update-ref,\n> > so that the ref won't be modified if someone changed it while\n> > an unbundle was running?  Sure its mostly a manual operation,\n> > but imagine running it on a bare repository while someone else\n> > is pushing into it...\n> \n> The script already has $local at that point, so adding it to\n> update-ref is a no-cost change to make things safer.  I think it\n> makes sense.\n\nActually that's only if --force was not given.  If --force was\ngiven, rev-parse wasn't run, so local is not populated.  So maybe\nits not trivial.\n \n> But I have to wonder...  While someone else is _pushing_ into\n> it?  Why are _you_ sneakernetting, then?\n\nPeople do weird things.  I agree, its probably unlikely to ever\nhappen.  But give a user a length of rope, they will find a way to\nhang themselves...\n\nI can see someone trying to use an update hook with bundle/unbundle\nto move stuff from one repository to another, despite the fact that\nare better ways to do that.  Better that we fail when an update\nmight lose changes.\n\n-- \nShawn.\n"},{"id":"34790","messageId":"45D59C20.6050708@fs.ei.tum.de","threadId":"6838","inReplyTo":"20070216065421.GG28894@spearce.org","subject":"Re: [PATCH] Add git-bundle - pack objects and references for disconnected transfer","fromName":"Simon 'corecode' Schubert","fromEmail":"corecode@fs.ei.tum.de","sentAt":"2007-02-16T11:57:20Z","receivedAt":"2007-02-16T11:57:20Z","isPatch":true,"sender":{"key":"corecode@fs.ei.tum.de","avatar":"https://gravatar.com/avatar/eff9dbf0cdac0d1e6a6cd7ed0e50763edcb376b493b5253a35ff167918ad79e1?d=mp&s=160"},"body":"Shawn O. Pearce wrote:\n> Mark Levedahl <mdl123@verizon.net> wrote:\n>> +# create the tar file, clean up\n>> +tar cf \"$bfile\" --absolute-names --transform=\"s,$tmp-,,\" \\\n>> +    --verbose --show-transformed-names \\\n>> +    \"$references\" \"$pack\"\n> \n> I'm not sure this will work on FreeBSD.  Both 5.1 and 6.1 use tar\n> that does not know about --absolute-names, --transform, --verbose,\n> or --show-transformed-names.\n\nfor portability, pax is the official choice :)  and it can even do path name modifications with -s.  but why again are we using tar there?  this data could easiliy be put in one mixed text/binary file, starting out with\n\n#!/bin/sh\necho \"This is a git bundle.  Use git-unbundle to process me.\" >&1\nexit\n### DATA ###\n\nor so\n\ncheers\n  simon\n\n-- \nServe - BSD     +++  RENT this banner advert  +++    ASCII Ribbon   /\"\\\nWork - Mac      +++  space for low €€€ NOW!1  +++      Campaign     \\ /\nParty Enjoy Relax   |   http://dragonflybsd.org      Against  HTML   \\\nDude 2c 2 the max   !   http://golden-apple.biz       Mail + News   / \\\n\n"}]}