{"thread":{"id":"32912","subject":"[PATCH v2 1/3] contrib/subtree: Store subtree sources in .gitsubtree and use for push/pull","startedAt":"2013-02-15T22:42:13Z","lastAt":"2013-02-15T22:42:13Z","messageCount":1,"participants":["Paul Campbell"],"isPatch":true,"patchVersion":2,"patchTotal":3},"messages":[{"id":"209564","messageId":"CALeLG_kgyGHYAc+5Hac2XSud95G3Xc2uxeG9sB3mC8qnPib3og@mail.gmail.com","threadId":"32912","inReplyTo":null,"subject":"[PATCH v2 1/3] contrib/subtree: Store subtree sources in .gitsubtree and use for push/pull","fromName":"Paul Campbell","fromEmail":"pcampbell@kemitix.net","sentAt":"2013-02-15T22:42:13Z","receivedAt":"2013-02-15T22:42:13Z","isPatch":true,"sender":{"key":"pcampbell@kemitix.net","avatar":"https://gravatar.com/avatar/57584e05501b694929004e43fcd7308f4ad64df2eb0474cd8c7e5f93662bb0f1?d=mp&s=160"},"body":"Add the prefix, repository and refspec in the file .gitsubtree when\ngit subtree add is used. Then when a git subtree push or pull is needed\nthe repository and refspec from .gitsubtree are used as the default\nvalues.\n\nHaving to remember what subtree came from what source is a waste of\ndeveloper memory and doesn't transfer easily to other developers.\n\ngit subtree push/pull operations would typically be to/from the same\nsource that the original subtree was cloned from with git subtree add.\n\nThe <repository> and <refspec>, or <commit>, used in the git subtree add\noperation are stored in .gitsubtree. One line each, delimited by a space:\n\"<prefix> <repository> <refspec>\" or \"<prefix> . <commit>\".\n\nSubsequent git subtree push/pull operations now default to the values\nstored in .gitsubtree, unless overridden from the command line.\n\nThe .gitsubtree file should be tracked as part of the repo as it\ndescribes where parts of the tree came from and can be used to update\nto and from that source.\n\nSigned-off-by: Paul Campbell <pcampbell@kemitix.net>\n---\n\nReworked my previous patch paying closer attention to the coding style\ndocumentation and renamed my new functions to make more sense.\n\n contrib/subtree/git-subtree.sh | 75 +++++++++++++++++++++++++++++++++++-------\n 1 file changed, 64 insertions(+), 11 deletions(-)\n\ndiff --git a/contrib/subtree/git-subtree.sh b/contrib/subtree/git-subtree.sh\nindex 51146bd..6dc8999 100755\n--- a/contrib/subtree/git-subtree.sh\n+++ b/contrib/subtree/git-subtree.sh\n@@ -11,8 +11,8 @@ OPTS_SPEC=\"\\\n git subtree add   --prefix=<prefix> <commit>\n git subtree add   --prefix=<prefix> <repository> <commit>\n git subtree merge --prefix=<prefix> <commit>\n-git subtree pull  --prefix=<prefix> <repository> <refspec...>\n-git subtree push  --prefix=<prefix> <repository> <refspec...>\n+git subtree pull  --prefix=<prefix> [<repository> <refspec...>]\n+git subtree push  --prefix=<prefix> [<repository> <refspec...>]\n git subtree split --prefix=<prefix> <commit...>\n --\n h,help        show the help\n@@ -489,6 +489,28 @@ ensure_clean()\n \tfi\n }\n\n+add_subtree () {\n+\tif ( grep \"^$dir \" .gitsubtree )\n+\tthen\n+\t\t# remove $dir from .gitsubtree - there's probably a clever way to\ndo this with sed\n+\t\tgrep -v \"^$dir \" .gitsubtree > .gitsubtree.temp\n+\t\trm .gitsubtree\n+\t\tmv .gitsubtree.temp .gitsubtree\n+\tfi\n+\tif test $# -eq 1\n+\tthen\n+\t\t# Only a commit provided, thus use the current repository\n+\t\techo \"$dir . $@\" >> .gitsubtree\n+\telif test $# -eq 2\n+\tthen\n+\t\techo \"$dir $@\" >> .gitsubtree\n+\tfi\n+}\n+\n+get_subtree () {\n+\tgrep \"^$dir \" .gitsubtree || die \"Subtree not found in .gitsubtree: \" \"$dir\"\n+}\n+\n cmd_add()\n {\n \tif [ -e \"$dir\" ]; then\n@@ -497,6 +519,8 @@ cmd_add()\n\n \tensure_clean\n \t\n+\tadd_subtree \"$@\"\n+\n \tif [ $# -eq 1 ]; then\n \t    git rev-parse -q --verify \"$1^{commit}\" >/dev/null ||\n \t    die \"'$1' does not refer to a commit\"\n@@ -700,7 +724,23 @@ cmd_merge()\n cmd_pull()\n {\n \tensure_clean\n-\tgit fetch \"$@\" || exit $?\n+\tif test $# -eq 0\n+\tthen\n+\t\tsubtree=($(get_subtree))\n+\t\trepository=${subtree[1]}\n+\t\trefspec=${subtree[2]}\n+\t\tif test \"$repository\" == \".\"\n+\t\tthen\n+\t\t\techo \"Pulling into $dir from branch $refspec\"\n+\t\telse\n+\t\t\techo \"Pulling into '$dir' from '$repository' '$refspec'\"\n+\t\tfi\n+\t\techo \"git fetch using: \" $repository $refspec\n+\t\tgit fetch \"$repository\" \"$refspec\" || exit $?\n+\telse\n+\t\techo \"git fetch using: $@\"\n+\t\tgit fetch \"$@\" || exit $?\n+\tfi\n \trevs=FETCH_HEAD\n \tset -- $revs\n \tcmd_merge \"$@\"\n@@ -708,16 +748,29 @@ cmd_pull()\n\n cmd_push()\n {\n-\tif [ $# -ne 2 ]; then\n-\t    die \"You must provide <repository> <refspec>\"\n+\trepository=$1\n+\trefspec=$2\n+\tif test $# -eq 0\n+\tthen\n+\t\tsubtree=($(get_subtree))\n+\t\trepository=${subtree[1]}\n+\t\trefspec=${subtree[2]}\n+\t\tif test \"$repository\" == \".\"\n+\t\tthen\n+\t\t\techo \"Pushing from $dir into branch $refspec\"\n+\t\telse\n+\t\t\techo \"Pushing from $dir into $repository $refspec\"\n+\t\tfi\n+\telif test $# -ne 2\n+\tthen\n+\t\tdie \"You must provide <repository> <refspec>, or a <prefix> listed\nin .gitsubtree\"\n \tfi\n-\tif [ -e \"$dir\" ]; then\n-\t    repository=$1\n-\t    refspec=$2\n-\t    echo \"git push using: \" $repository $refspec\n-\t    git push $repository $(git subtree split\n--prefix=$prefix):refs/heads/$refspec\n+\tif test -e \"$dir\"\n+\tthen\n+\t\techo \"git push using: \" $repository $refspec\n+\t\tgit push $repository $(git subtree split\n--prefix=$prefix):refs/heads/$refspec\n \telse\n-\t    die \"'$dir' must already exist. Try 'git subtree add'.\"\n+\t\tdie \"'$dir' must already exist. Try 'git subtree add'.\"\n \tfi\n }\n\n-- \n1.8.1.3.605.g02339dd\n"}]}