{"thread":{"id":"5044","subject":"[PATCH 1/1] Make git-tar-tree more flexible","startedAt":"2006-07-30T17:48:47Z","lastAt":"2006-07-31T01:17:58Z","messageCount":5,"participants":["Anand Kumria","A Large Angry SCM","Junio C Hamano","Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"24378","messageId":"20060730174847.GA32574@eve.kumria.com","threadId":"5044","inReplyTo":null,"subject":"[PATCH 1/1] Make git-tar-tree more flexible","fromName":"Anand Kumria","fromEmail":"wildfire@progsoc.org","sentAt":"2006-07-30T17:48:47Z","receivedAt":"2006-07-30T17:48:47Z","isPatch":true,"sender":{"key":"wildfire@progsoc.org","avatar":null},"body":"  If you have a project which is setup like:\n     project\n     website\n  and you decide you wish to generate a tar archive of _just_ the 'project'\n  portion, git-tar-tree is not able to help. This patch adds two parameters\n  which can assist.\n\n  The first is '--pathlimit', which forces git-tar-tree to only generate the\n  tar archive for project; as in:\n    'git tar-tree --pathlimit=project project-1.0 tag-1.0'\n\n  The above command will mean that paths in the tar archive look like:\n    project-1.0/project/src/main.c\n  etc.\n\n  The second parameter allows you two strip the extraneous project, as in:\n    'git tar-tree --strippath=project --pathlimit=project project-1.0 tag-1.0     Which will result in tar archives looking like:\n    project-1.0/src/main.c\n\n  This patch also updates the documentation to match the new parameters and\n  rewrites the argument processing so that arguments can be passed in any\n  order by the user\n\nSigned-off-by: Anand Kumria <wildfire@progsoc.org>\n---\n Documentation/git-tar-tree.txt |   11 ++++++\n tar-tree.c                     |   70 ++++++++++++++++++++++++++++++----------\n 2 files changed, 63 insertions(+), 18 deletions(-)\n\ndiff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt\nindex 2139b6f..d123329 100644\n--- a/Documentation/git-tar-tree.txt\n+++ b/Documentation/git-tar-tree.txt\n@@ -8,7 +8,7 @@ git-tar-tree - Creates a tar archive of \n \n SYNOPSIS\n --------\n-'git-tar-tree' <tree-ish> [ <base> ]\n+'git-tar-tree' [--strippath=<path>] [--pathlimit=<path>] <tree-ish> [ <base> ]\n \n DESCRIPTION\n -----------\n@@ -23,6 +23,15 @@ commit time as recorded in the reference\n Additionally the commit ID is stored in a global extended pax header.\n It can be extracted using git-get-tar-commit-id.\n \n+OPTIONS\n+-------\n+--strippath::\n+\tRemove from the created tar archive the specified string from\n+\tany of the generated paths\n+\n+--pathlimit::\n+\tCreate the tar archive but limit the included files to be those\n+\tspecified by the pathlimit\n \n Author\n ------\ndiff --git a/tar-tree.c b/tar-tree.c\nindex fc60a90..78ae7ff 100644\n--- a/tar-tree.c\n+++ b/tar-tree.c\n@@ -11,7 +11,7 @@ #include \"tar.h\"\n #define RECORDSIZE\t(512)\n #define BLOCKSIZE\t(RECORDSIZE * 20)\n \n-static const char tar_tree_usage[] = \"git-tar-tree <key> [basedir]\";\n+static const char tar_tree_usage[] = \"git-tar-tree [--strippath=<path>] [--pathlimit=<path>] <key> [basedir]\";\n \n static char block[BLOCKSIZE];\n static unsigned long offset;\n@@ -265,7 +265,7 @@ static void write_global_extended_header\n \tfree(ext_header.buf);\n }\n \n-static void traverse_tree(struct tree_desc *tree, struct strbuf *path)\n+static void traverse_tree(struct tree_desc *tree, struct strbuf *path, const char *namelimit, const char *strippath)\n {\n \tint pathlen = path->len;\n \n@@ -280,14 +280,25 @@ static void traverse_tree(struct tree_de\n \t\tsha1 = tree_entry_extract(tree, &name, &mode);\n \t\tupdate_tree_entry(tree);\n \n+\t\t/* if we have a namelimit and we don't match it, escape */\n+\t\tif (namelimit)\n+\t\t\tif (!(strcmp(name,namelimit) == 0))\n+\t\t\t\tcontinue;\n+\n \t\teltbuf = read_sha1_file(sha1, elttype, &eltsize);\n \t\tif (!eltbuf)\n \t\t\tdie(\"cannot read %s\", sha1_to_hex(sha1));\n \n \t\tpath->len = pathlen;\n-\t\tstrbuf_append_string(path, name);\n-\t\tif (S_ISDIR(mode))\n-\t\t\tstrbuf_append_string(path, \"/\");\n+\n+\t\t/* if we match the path to strip out,\n+\t\t *  don't append it to the path\n+\t\t */\n+\t\tif ((strippath) && (!(strcmp(name,strippath) == 0))) {\n+\t\t\tstrbuf_append_string(path, name);\n+\t\t\tif (S_ISDIR(mode))\n+\t\t\t\tstrbuf_append_string(path, \"/\");\n+\t\t}\n \n \t\twrite_entry(sha1, path, mode, eltbuf, eltsize);\n \n@@ -295,7 +306,7 @@ static void traverse_tree(struct tree_de\n \t\t\tstruct tree_desc subtree;\n \t\t\tsubtree.buf = eltbuf;\n \t\t\tsubtree.size = eltsize;\n-\t\t\ttraverse_tree(&subtree, path);\n+\t\t\ttraverse_tree(&subtree, path, NULL, strippath);\n \t\t}\n \t\tfree(eltbuf);\n \t}\n@@ -307,6 +318,9 @@ int main(int argc, char **argv)\n \tstruct commit *commit;\n \tstruct tree_desc tree;\n \tstruct strbuf current_path;\n+\tint i, gotsha1 = 0, gotpath = 0;\n+\tconst char *strippath;\n+\tconst char *pathlimit;\n \n \tcurrent_path.buf = xmalloc(PATH_MAX);\n \tcurrent_path.alloc = PATH_MAX;\n@@ -315,19 +329,41 @@ int main(int argc, char **argv)\n \tsetup_git_directory();\n \tgit_config(git_default_config);\n \n-\tswitch (argc) {\n-\tcase 3:\n-\t\tstrbuf_append_string(&current_path, argv[2]);\n-\t\tstrbuf_append_string(&current_path, \"/\");\n-\t\t/* FALLTHROUGH */\n-\tcase 2:\n-\t\tif (get_sha1(argv[1], sha1) < 0)\n+\tfor (i = 1; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\n+\t\tif (*arg != '-') {\n+\t\t\t/* first assume it is an SHA1 ref */\n+\t\t\tif (!gotsha1) {\n+\t\t\t\tif (get_sha1(arg, sha1) >= 0) {\n+\t\t\t\t\tgotsha1 = 1;\n+\t\t\t\t\tcontinue;\n+\t\t\t\t}\n+\t\t\t}\n+\n+\t\t\t/* now assume it is the path prefix */\n+\t\t\tif (!gotpath) {\n+\t\t\t\tstrbuf_append_string(&current_path, arg);\n+\t\t\t\tstrbuf_append_string(&current_path, \"/\");\n+\t\t\t\tgotpath = 1;\n+\t\t\t\tcontinue;\n+\t\t\t}\n+\n+\t\t\t/* we're still here? */\n+\t\t\tusage(tar_tree_usage);\n+\n+\t\t} else if (!strncmp(arg, \"--strippath=\", 12)) {\n+\t\t\tstrippath = strdup(arg+12);\n+\t\t} else if (!strncmp(arg, \"--pathlimit=\", 12)) {\n+\t\t\tpathlimit = strdup(arg+12);\n+\t\t} else\n \t\t\tusage(tar_tree_usage);\n-\t\tbreak;\n-\tdefault:\n-\t\tusage(tar_tree_usage);\n \t}\n \n+\t/* be sure we have an SHA1 ref */\n+\tif (!gotsha1)\n+\t\tusage(tar_tree_usage);\n+\n \tcommit = lookup_commit_reference_gently(sha1, 1);\n \tif (commit) {\n \t\twrite_global_extended_header(commit->object.sha1);\n@@ -343,7 +379,7 @@ int main(int argc, char **argv)\n \n \tif (current_path.len > 0)\n \t\twrite_entry(tree_sha1, &current_path, 040777, NULL, 0);\n-\ttraverse_tree(&tree, &current_path);\n+\ttraverse_tree(&tree, &current_path, pathlimit, strippath);\n \twrite_trailer();\n \tfree(current_path.buf);\n \treturn 0;\n-- \n1.4.1\n"},{"id":"24386","messageId":"44CCFE93.7040500@gmail.com","threadId":"5044","inReplyTo":"20060730174847.GA32574@eve.kumria.com","subject":"Re: [PATCH 1/1] Make git-tar-tree more flexible","fromName":"A Large Angry SCM","fromEmail":"gitzilla@gmail.com","sentAt":"2006-07-30T18:46:43Z","receivedAt":"2006-07-30T18:46:43Z","isPatch":true,"sender":{"key":"gitzilla@gmail.com","avatar":"https://gravatar.com/avatar/354625c442439908ff3dd99757dee330e29e9df7847472384faf7a00add247fb?d=mp&s=160"},"body":"Anand Kumria wrote:\n>   If you have a project which is setup like:\n>      project\n>      website\n>   and you decide you wish to generate a tar archive of _just_ the 'project'\n>   portion, git-tar-tree is not able to help. This patch adds two parameters\n>   which can assist.\n> \n>   The first is '--pathlimit', which forces git-tar-tree to only generate the\n>   tar archive for project; as in:\n>     'git tar-tree --pathlimit=project project-1.0 tag-1.0'\n> \n>   The above command will mean that paths in the tar archive look like:\n>     project-1.0/project/src/main.c\n>   etc.\n> \n>   The second parameter allows you two strip the extraneous project, as in:\n>     'git tar-tree --strippath=project --pathlimit=project project-1.0 tag-1.0     Which will result in tar archives looking like:\n>     project-1.0/src/main.c\n> \n\nThis could be made more general and more Git-ish instead, by \nimplementing a strip common prefix option and using a double dash option \nto signal that the remaining arguments are the paths of interest.\n\nThe synopsis would then look like:\n\n\tgit-tar-tree [--remote=<repo>] [ --strip-common-prefix ]\n\t\t<tree-ish> [ <base> ] [ -- <paths>... ]\n"},{"id":"24388","messageId":"7vbqr6dd4t.fsf@assigned-by-dhcp.cox.net","threadId":"5044","inReplyTo":"20060730174847.GA32574@eve.kumria.com","subject":"Re: [PATCH 1/1] Make git-tar-tree more flexible","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-07-30T20:57:38Z","receivedAt":"2006-07-30T20:57:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Anand Kumria <wildfire@progsoc.org> writes:\n\n>   If you have a project which is setup like:\n>      project\n>      website\n>   and you decide you wish to generate a tar archive of _just_ the 'project'\n>   portion, git-tar-tree is not able to help. This patch adds two parameters\n>   which can assist.\n\nNo need I see.\n\n\tgit tar-tree tag-1.0:project project-1.0/project\n\tgit tar-tree tag-1.0:project project-1.0\n"},{"id":"24395","messageId":"Pine.LNX.4.63.0607310225190.29667@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"5044","inReplyTo":"7vbqr6dd4t.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/1] Make git-tar-tree more flexible","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-07-31T00:26:27Z","receivedAt":"2006-07-31T00:26:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 30 Jul 2006, Junio C Hamano wrote:\n\n> Anand Kumria <wildfire@progsoc.org> writes:\n> \n> >   If you have a project which is setup like:\n> >      project\n> >      website\n> >   and you decide you wish to generate a tar archive of _just_ the 'project'\n> >   portion, git-tar-tree is not able to help. This patch adds two parameters\n> >   which can assist.\n> \n> No need I see.\n> \n> \tgit tar-tree tag-1.0:project project-1.0/project\n> \tgit tar-tree tag-1.0:project project-1.0\n\nSo how about this:\n\n-- 8< --\n[PATCH] tar-tree: illustrate an obscure feature better\n\nSince you can tar just a subdirectory of a certain revision, tell\nthe users so, by showing an example how to do it.\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n\n---\n\n Documentation/git-tar-tree.txt |    5 +++++\n 1 files changed, 5 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-tar-tree.txt b/Documentation/git-tar-tree.txt\nindex 7a99acf..1e1c7fa 100644\n--- a/Documentation/git-tar-tree.txt\n+++ b/Documentation/git-tar-tree.txt\n@@ -71,6 +71,11 @@ git tar-tree --remote=example.com:git.gi\n \n \tGet a tarball v1.4.0 from example.com.\n \n+git tar-tree HEAD:Documentation/ git-docs > git-1.4.0-docs.tar::\n+\n+\tPut everything in the current head's Documentation/ directory\n+\tinto 'git-1.4.0-docs.tar', with the prefix 'git-docs/'.\n+\n Author\n ------\n Written by Rene Scharfe.\n"},{"id":"24401","messageId":"7v4pwybmih.fsf@assigned-by-dhcp.cox.net","threadId":"5044","inReplyTo":"Pine.LNX.4.63.0607310225190.29667@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH 1/1] Make git-tar-tree more flexible","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-07-31T01:17:58Z","receivedAt":"2006-07-31T01:17:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> So how about this:\n>\n> -- 8< --\n> [PATCH] tar-tree: illustrate an obscure feature better\n>\n> Since you can tar just a subdirectory of a certain revision, tell\n> the users so, by showing an example how to do it.\n\nSounds sensible.  Thanks.\n"}]}