{"thread":{"id":"17966","subject":"[PATCH v5] git-archive: Add new option \"--output\" to write archive to a file instead of stdout.","startedAt":"2009-02-23T08:25:14Z","lastAt":"2009-02-25T06:13:09Z","messageCount":2,"participants":["carlos.duclos@nokia.com","Junio C Hamano"],"isPatch":true,"patchVersion":5,"patchTotal":null},"messages":[{"id":"105882","messageId":"599636D7828020419E3AB2DE5CCC8130036BF8B1E4@NOK-EUMSG-02.mgdnok.nokia.com","threadId":"17966","inReplyTo":null,"subject":"[PATCH v5] git-archive: Add new option \"--output\" to write archive to a file instead of stdout.","fromName":"","fromEmail":"carlos.duclos@nokia.com","sentAt":"2009-02-23T08:25:14Z","receivedAt":"2009-02-23T08:25:14Z","isPatch":true,"sender":{"key":"carlos.duclos@nokia.com","avatar":"https://gravatar.com/avatar/be05d03546ed19ca9104e62d4a330bc40b4115ebcf39d1a4c43884b663667951?d=mp&s=160"},"body":"Patch attached as MIME.\n\nHighlights:\n1. Closing output_fd. Notice this is not needed since dup2 will close newfd.\n2. Moved tests from t0024 to t5000.\n\nCheers!\n\n\nFrom 8bcb1f18b9bf94ad9b2ac5175095394e7db44a1a Mon Sep 17 00:00:00 2001\nFrom: Carlos Manuel Duclos Vergara <carlos.duclos@nokia.com>\nDate: Mon, 16 Feb 2009 18:20:25 +0100\nSubject: [PATCH] git-archive: add --output=<file> to send output to a file instead of stdout.\n When archiving a repository there is no way to specify a file as output.\n This patch adds a new option \"--output\" that redirects the output to a file\n instead of stdout.\n\nSigned-off-by: Carlos Manuel Duclos Vergara <carlos.duclos@nokia.com>\n---\n Documentation/git-archive.txt |    3 +++\n archive.c                     |   18 ++++++++++++++++++\n t/t5000-tar-tree.sh           |    8 ++++++++\n 3 files changed, 29 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt\nindex 41cbf9c..5bde197 100644\n--- a/Documentation/git-archive.txt\n+++ b/Documentation/git-archive.txt\n@@ -47,6 +47,9 @@ OPTIONS\n --prefix=<prefix>/::\n \tPrepend <prefix>/ to each filename in the archive.\n \n+--output=<file>::\n+\tWrite the archive to <file> instead of stdout.\n+\n <extra>::\n \tThis can be any options that the archiver backend understand.\n \tSee next section.\ndiff --git a/archive.c b/archive.c\nindex e6de039..3bf4a73 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -239,6 +239,18 @@ static void parse_treeish_arg(const char **argv,\n \tar_args->time = archive_time;\n }\n \n+static void create_output_file(const char *output_file)\n+{\n+\tint output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n+\tif (output_fd < 0)\n+\t\tdie(\"could not create archive file: %s \", output_file);\n+\tif (output_fd != 1)\n+\t\tif (dup2(output_fd, 1) < 0)\n+\t\t\tdie(\"could not redirect output\");\n+\t\telse\n+\t\t\tclose(output_fd);\n+}\n+\n #define OPT__COMPR(s, v, h, p) \\\n \t{ OPTION_SET_INT, (s), NULL, (v), NULL, (h), \\\n \t  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }\n@@ -253,6 +265,7 @@ static int parse_archive_args(int argc, const char **argv,\n \tconst char *base = NULL;\n \tconst char *remote = NULL;\n \tconst char *exec = NULL;\n+\tconst char *output = NULL;\n \tint compression_level = -1;\n \tint verbose = 0;\n \tint i;\n@@ -262,6 +275,8 @@ static int parse_archive_args(int argc, const char **argv,\n \t\tOPT_STRING(0, \"format\", &format, \"fmt\", \"archive format\"),\n \t\tOPT_STRING(0, \"prefix\", &base, \"prefix\",\n \t\t\t\"prepend prefix to each pathname in the archive\"),\n+\t\tOPT_STRING(0, \"output\", &output, \"file\",\n+\t\t\t\"write the archive to this file\"),\n \t\tOPT__VERBOSE(&verbose),\n \t\tOPT__COMPR('0', &compression_level, \"store only\", 0),\n \t\tOPT__COMPR('1', &compression_level, \"compress faster\", 1),\n@@ -294,6 +309,9 @@ static int parse_archive_args(int argc, const char **argv,\n \tif (!base)\n \t\tbase = \"\";\n \n+\tif (output)\n+\t\tcreate_output_file(output);\n+\n \tif (list) {\n \t\tfor (i = 0; i < ARRAY_SIZE(archivers); i++)\n \t\t\tprintf(\"%s\\n\", archivers[i].name);\ndiff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh\nindex c942c8b..0d60e0e 100755\n--- a/t/t5000-tar-tree.sh\n+++ b/t/t5000-tar-tree.sh\n@@ -79,6 +79,10 @@ test_expect_success \\\n     'diff b.tar b2.tar'\n \n test_expect_success \\\n+    'git archive' \\\n+    'git archive --output=z.tar HEAD'\n+\n+test_expect_success \\\n     'git archive in a bare repo' \\\n     '(cd bare.git && git archive HEAD) >b3.tar'\n \n@@ -172,6 +176,10 @@ test_expect_success \\\n     'git archive --format=zip vs. the same in a bare repo' \\\n     'test_cmp d.zip d1.zip'\n \n+test_expect_success \\\n+    'git archive --format=zip' \\\n+    'git archive --format=zip --output=z.zip HEAD'\n+\n $UNZIP -v >/dev/null 2>&1\n if [ $? -eq 127 ]; then\n \techo \"Skipping ZIP tests, because unzip was not found\"\n-- \n1.6.2.rc0.63.g7cbd0.dirty\n\n"},{"id":"106137","messageId":"7v4oyjdoy2.fsf@gitster.siamese.dyndns.org","threadId":"17966","inReplyTo":"599636D7828020419E3AB2DE5CCC8130036BF8B1E4@NOK-EUMSG-02.mgdnok.nokia.com","subject":"Re: [PATCH] git-archive: add --output=<file> to send output to a file","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-02-25T06:13:09Z","receivedAt":"2009-02-25T06:13:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"When archiving a repository there is no way to specify a file as output.\nThis patch adds a new option \"--output\" that redirects the output to a\nfile instead of stdout.\n\nSigned-off-by: Carlos Manuel Duclos Vergara <carlos.duclos@nokia.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n * I've fixed it up slightly; especially the tests, which were not making\n   sure the results match what are expected.\n\n   Thanks.\n\n Documentation/git-archive.txt |    3 +++\n archive.c                     |   19 +++++++++++++++++++\n t/t5000-tar-tree.sh           |    8 ++++++++\n 3 files changed, 30 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt\nindex 41cbf9c..5bde197 100644\n--- a/Documentation/git-archive.txt\n+++ b/Documentation/git-archive.txt\n@@ -47,6 +47,9 @@ OPTIONS\n --prefix=<prefix>/::\n \tPrepend <prefix>/ to each filename in the archive.\n \n+--output=<file>::\n+\tWrite the archive to <file> instead of stdout.\n+\n <extra>::\n \tThis can be any options that the archiver backend understand.\n \tSee next section.\ndiff --git a/archive.c b/archive.c\nindex e6de039..c6aea83 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -239,6 +239,19 @@ static void parse_treeish_arg(const char **argv,\n \tar_args->time = archive_time;\n }\n \n+static void create_output_file(const char *output_file)\n+{\n+\tint output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n+\tif (output_fd < 0)\n+\t\tdie(\"could not create archive file: %s \", output_file);\n+\tif (output_fd != 1) {\n+\t\tif (dup2(output_fd, 1) < 0)\n+\t\t\tdie(\"could not redirect output\");\n+\t\telse\n+\t\t\tclose(output_fd);\n+\t}\n+}\n+\n #define OPT__COMPR(s, v, h, p) \\\n \t{ OPTION_SET_INT, (s), NULL, (v), NULL, (h), \\\n \t  PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }\n@@ -253,6 +266,7 @@ static int parse_archive_args(int argc, const char **argv,\n \tconst char *base = NULL;\n \tconst char *remote = NULL;\n \tconst char *exec = NULL;\n+\tconst char *output = NULL;\n \tint compression_level = -1;\n \tint verbose = 0;\n \tint i;\n@@ -262,6 +276,8 @@ static int parse_archive_args(int argc, const char **argv,\n \t\tOPT_STRING(0, \"format\", &format, \"fmt\", \"archive format\"),\n \t\tOPT_STRING(0, \"prefix\", &base, \"prefix\",\n \t\t\t\"prepend prefix to each pathname in the archive\"),\n+\t\tOPT_STRING(0, \"output\", &output, \"file\",\n+\t\t\t\"write the archive to this file\"),\n \t\tOPT__VERBOSE(&verbose),\n \t\tOPT__COMPR('0', &compression_level, \"store only\", 0),\n \t\tOPT__COMPR('1', &compression_level, \"compress faster\", 1),\n@@ -294,6 +310,9 @@ static int parse_archive_args(int argc, const char **argv,\n \tif (!base)\n \t\tbase = \"\";\n \n+\tif (output)\n+\t\tcreate_output_file(output);\n+\n \tif (list) {\n \t\tfor (i = 0; i < ARRAY_SIZE(archivers); i++)\n \t\t\tprintf(\"%s\\n\", archivers[i].name);\ndiff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh\nindex c942c8b..b7e3628 100755\n--- a/t/t5000-tar-tree.sh\n+++ b/t/t5000-tar-tree.sh\n@@ -86,6 +86,10 @@ test_expect_success \\\n     'git archive vs. the same in a bare repo' \\\n     'test_cmp b.tar b3.tar'\n \n+test_expect_success 'git archive with --output' \\\n+    'git archive --output=b4.tar HEAD &&\n+    test_cmp b.tar b4.tar'\n+\n test_expect_success \\\n     'validate file modification time' \\\n     'mkdir extract &&\n@@ -172,6 +176,10 @@ test_expect_success \\\n     'git archive --format=zip vs. the same in a bare repo' \\\n     'test_cmp d.zip d1.zip'\n \n+test_expect_success 'git archive --format=zip with --output' \\\n+    'git archive --format=zip --output=d2.zip HEAD &&\n+    test_cmp d.zip d2.zip'\n+\n $UNZIP -v >/dev/null 2>&1\n if [ $? -eq 127 ]; then\n \techo \"Skipping ZIP tests, because unzip was not found\"\n-- \n1.6.2.rc2\n"}]}