{"thread":{"id":"5577","subject":"[PATCH] git-tar-tree: devolve git-tar-tree into a wrapper for git-archive","startedAt":"2006-09-16T19:20:36Z","lastAt":"2006-09-16T19:20:36Z","messageCount":1,"participants":["Rene Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"27010","messageId":"450C4E84.3000803@lsrfire.ath.cx","threadId":"5577","inReplyTo":null,"subject":"[PATCH] git-tar-tree: devolve git-tar-tree into a wrapper for git-archive","fromName":"Rene Scharfe","fromEmail":"rene.scharfe@lsrfire.ath.cx","sentAt":"2006-09-16T19:20:36Z","receivedAt":"2006-09-16T19:20:36Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"This patch removes the custom tree walker tree_traverse(), and makes\ngenerate_tar() use write_tar_archive() and the infrastructure provided\nby git-archive instead.\n\nAs a kind of side effect, make write_tar_archive() able to handle NULL\nas base directory, as this is what the new and simple generate_tar()\nuses to indicate the absence of a base directory.  This was simpler\nand cleaner than playing tricks with empty strings.\n\nThe behaviour of git-tar-tree should be unchanged (quick tests didn't\nindicate otherwise) except for the text of some error messages.\n\nSigned-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>\n---\n\n builtin-tar-tree.c |   90 ++++++++++-------------------------------------------\n 1 file changed, 18 insertions(+), 72 deletions(-)\n\ndiff --git a/builtin-tar-tree.c b/builtin-tar-tree.c\nindex f2679a8..437eb72 100644\n--- a/builtin-tar-tree.c\n+++ b/builtin-tar-tree.c\n@@ -3,7 +3,6 @@\n  */\n #include <time.h>\n #include \"cache.h\"\n-#include \"tree-walk.h\"\n #include \"commit.h\"\n #include \"strbuf.h\"\n #include \"tar.h\"\n@@ -248,37 +247,6 @@ 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-{\n-\tint pathlen = path->len;\n-\tstruct name_entry entry;\n-\n-\twhile (tree_entry(tree, &entry)) {\n-\t\tvoid *eltbuf;\n-\t\tchar elttype[20];\n-\t\tunsigned long eltsize;\n-\n-\t\teltbuf = read_sha1_file(entry.sha1, elttype, &eltsize);\n-\t\tif (!eltbuf)\n-\t\t\tdie(\"cannot read %s\", sha1_to_hex(entry.sha1));\n-\n-\t\tpath->len = pathlen;\n-\t\tstrbuf_append_string(path, entry.path);\n-\t\tif (S_ISDIR(entry.mode))\n-\t\t\tstrbuf_append_string(path, \"/\");\n-\n-\t\twrite_entry(entry.sha1, path, entry.mode, eltbuf, eltsize);\n-\n-\t\tif (S_ISDIR(entry.mode)) {\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}\n-\t\tfree(eltbuf);\n-\t}\n-}\n-\n static int git_tar_config(const char *var, const char *value)\n {\n \tif (!strcmp(var, \"tar.umask\")) {\n@@ -295,51 +263,29 @@ static int git_tar_config(const char *va\n \n static int generate_tar(int argc, const char **argv, const char *prefix)\n {\n-\tunsigned char sha1[20], tree_sha1[20];\n-\tstruct commit *commit;\n-\tstruct tree_desc tree;\n-\tstruct strbuf current_path;\n-\tvoid *buffer;\n-\n-\tcurrent_path.buf = xmalloc(PATH_MAX);\n-\tcurrent_path.alloc = PATH_MAX;\n-\tcurrent_path.len = current_path.eof = 0;\n+\tstruct archiver_args args;\n+\tint result;\n+\tchar *base = NULL;\n \n \tgit_config(git_tar_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))\n-\t\t\tdie(\"Not a valid object name %s\", argv[1]);\n-\t\tbreak;\n-\tdefault:\n+\tmemset(&args, 0, sizeof(args));\n+\tif (argc != 2 && argc != 3)\n \t\tusage(tar_tree_usage);\n+\tif (argc == 3) {\n+\t\tint baselen = strlen(argv[2]);\n+\t\tbase = xmalloc(baselen + 2);\n+\t\tmemcpy(base, argv[2], baselen);\n+\t\tbase[baselen] = '/';\n+\t\tbase[baselen + 1] = '\\0';\n \t}\n+\targs.base = base;\n+\tparse_treeish_arg(argv + 1, &args, NULL);\n \n-\tcommit = lookup_commit_reference_gently(sha1, 1);\n-\tif (commit) {\n-\t\twrite_global_extended_header(commit->object.sha1);\n-\t\tarchive_time = commit->date;\n-\t} else\n-\t\tarchive_time = time(NULL);\n-\n-\ttree.buf = buffer = read_object_with_reference(sha1, tree_type,\n-\t                                               &tree.size, tree_sha1);\n-\tif (!tree.buf)\n-\t\tdie(\"not a reference to a tag, commit or tree object: %s\",\n-\t\t    sha1_to_hex(sha1));\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-\twrite_trailer();\n-\tfree(buffer);\n-\tfree(current_path.buf);\n-\treturn 0;\n+\tresult = write_tar_archive(&args);\n+\tfree(base);\n+\n+\treturn result;\n }\n \n static int write_tar_entry(const unsigned char *sha1,\n@@ -383,7 +329,7 @@ static int write_tar_entry(const unsigne\n \n int write_tar_archive(struct archiver_args *args)\n {\n-\tint plen = strlen(args->base);\n+\tint plen = args->base ? strlen(args->base) : 0;\n \n \tgit_config(git_tar_config);\n \n"}]}