From: Ramkumar Ramachandra <artagnon@gmail.com>
To: Git List <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>
Subject: [PATCH 2/2] bundle: rewrite builtin to use parse-options
Date: Thu, 8 Dec 2011 17:37:08 +0530 [thread overview]
Message-ID: <1323346028-9201-3-git-send-email-artagnon@gmail.com> (raw)
In-Reply-To: <1323346028-9201-1-git-send-email-artagnon@gmail.com>
The git-bundle builtin currently parses command-line options by hand;
this is both fragile and cryptic on failure. Since we now have an
OPT_SUBCOMMAND, make use of it to parse the correct subcommand, while
forbidding the use of more than one subcommand in the same invocation.
Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
---
builtin/bundle.c | 111 +++++++++++++++++++++++++++++++++++------------------
1 files changed, 73 insertions(+), 38 deletions(-)
diff --git a/builtin/bundle.c b/builtin/bundle.c
index 92a8a60..c977d9f 100644
--- a/builtin/bundle.c
+++ b/builtin/bundle.c
@@ -1,5 +1,6 @@
#include "builtin.h"
#include "cache.h"
+#include "parse-options.h"
#include "bundle.h"
/*
@@ -9,57 +10,91 @@
* bundle supporting "fetch", "pull", and "ls-remote".
*/
-static const char builtin_bundle_usage[] =
- "git bundle create <file> <git-rev-list args>\n"
- " or: git bundle verify <file>\n"
- " or: git bundle list-heads <file> [<refname>...]\n"
- " or: git bundle unbundle <file> [<refname>...]";
+static const char * builtin_bundle_usage[] = {
+ "git bundle create <file> <git-rev-list args>",
+ "git bundle verify <file>",
+ "git bundle list-heads <file> [<refname>...]",
+ "git bundle unbundle <file> [<refname>...]",
+ NULL
+};
+
+enum bundle_subcommand {
+ BUNDLE_NONE = 0,
+ BUNDLE_CREATE = 1,
+ BUNDLE_VERIFY = 2,
+ BUNDLE_LIST_HEADS = 4,
+ BUNDLE_UNBUNDLE = 8
+};
int cmd_bundle(int argc, const char **argv, const char *prefix)
{
- struct bundle_header header;
- const char *cmd, *bundle_file;
+ int prefix_length;
int bundle_fd = -1;
- char buffer[PATH_MAX];
+ const char *bundle_file;
+ struct bundle_header header;
+ enum bundle_subcommand subcommand = BUNDLE_NONE;
- if (argc < 3)
- usage(builtin_bundle_usage);
+ struct option options[] = {
+ OPT_SUBCOMMAND("create", &subcommand,
+ "create a new bundle",
+ BUNDLE_CREATE),
+ OPT_SUBCOMMAND("verify", &subcommand,
+ "verify clean application of the bundle",
+ BUNDLE_VERIFY),
+ OPT_SUBCOMMAND("list-heads", &subcommand,
+ "list references defined in the bundle",
+ BUNDLE_LIST_HEADS),
+ OPT_SUBCOMMAND("unbundle", &subcommand,
+ "pass objects in the bundle to 'git index-pack'",
+ BUNDLE_UNBUNDLE),
+ OPT_END(),
+ };
- cmd = argv[1];
- bundle_file = argv[2];
- argc -= 2;
- argv += 2;
+ argc = parse_options(argc, argv, NULL,
+ options, builtin_bundle_usage,
+ PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);
- if (prefix && bundle_file[0] != '/') {
- snprintf(buffer, sizeof(buffer), "%s/%s", prefix, bundle_file);
- bundle_file = buffer;
- }
+ if (argc < 2)
+ usage_with_options(builtin_bundle_usage, options);
- memset(&header, 0, sizeof(header));
- if (strcmp(cmd, "create") && (bundle_fd =
- read_bundle_header(bundle_file, &header)) < 0)
- return 1;
+ /* The next parameter on the command line is bundle_file */
+ prefix_length = prefix ? strlen(prefix) : 0;
+ bundle_file = prefix_filename(prefix, prefix_length, argv[1]);
+ argc -= 1;
+ argv += 1;
- if (!strcmp(cmd, "verify")) {
+ /* Read out bundle header, except in BUNDLE_CREATE case */
+ if (subcommand == BUNDLE_VERIFY || subcommand == BUNDLE_LIST_HEADS ||
+ subcommand == BUNDLE_UNBUNDLE) {
+ memset(&header, 0, sizeof(header));
+ bundle_fd = read_bundle_header(bundle_file, &header);
+ if (bundle_fd < 0)
+ die_errno(_("Failed to open bundle file '%s'"), bundle_file);
+ }
+
+ switch (subcommand) {
+ case BUNDLE_CREATE:
+ if (!startup_info->have_repository)
+ die(_("Need a repository to create a bundle."));
+ return create_bundle(&header, bundle_file, argc, argv);
+ case BUNDLE_VERIFY:
close(bundle_fd);
if (verify_bundle(&header, 1))
- return 1;
+ return -1; /* Error already reported */
fprintf(stderr, _("%s is okay\n"), bundle_file);
- return 0;
- }
- if (!strcmp(cmd, "list-heads")) {
+ break;
+ case BUNDLE_LIST_HEADS:
close(bundle_fd);
- return !!list_bundle_refs(&header, argc, argv);
- }
- if (!strcmp(cmd, "create")) {
- if (!startup_info->have_repository)
- die(_("Need a repository to create a bundle."));
- return !!create_bundle(&header, bundle_file, argc, argv);
- } else if (!strcmp(cmd, "unbundle")) {
- if (!startup_info->have_repository)
+ return list_bundle_refs(&header, argc, argv);
+ case BUNDLE_UNBUNDLE:
+ if (!startup_info->have_repository) {
+ close(bundle_fd);
die(_("Need a repository to unbundle."));
- return !!unbundle(&header, bundle_fd, 0) ||
+ }
+ return unbundle(&header, bundle_fd, 0) ||
list_bundle_refs(&header, argc, argv);
- } else
- usage(builtin_bundle_usage);
+ default:
+ usage_with_options(builtin_bundle_usage, options);
+ }
+ return 0;
}
--
1.7.7.3
next prev parent reply other threads:[~2011-12-08 12:08 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-08 12:07 [PATCH 0/2] Parsing a subcommand using parse-options Ramkumar Ramachandra
2011-12-08 12:07 ` [PATCH 1/2] parse-options: introduce OPT_SUBCOMMAND Ramkumar Ramachandra
2011-12-08 12:07 ` Ramkumar Ramachandra [this message]
2011-12-08 19:51 ` [PATCH 0/2] Parsing a subcommand using parse-options Junio C Hamano
-- strict thread matches above, loose matches on Subject: below --
2011-12-08 13:10 [PATCH v2 0/6] Fix '&&' chaining in tests Ramkumar Ramachandra
2011-12-08 13:10 ` [PATCH 2/2] bundle: rewrite builtin to use parse-options Ramkumar Ramachandra
2011-12-08 16:39 ` Jonathan Nieder
2011-12-08 16:47 ` Ramkumar Ramachandra
2011-12-08 17:03 ` Jonathan Nieder
2011-12-08 17:38 ` Ramkumar Ramachandra
2011-12-08 17:59 ` Jonathan Nieder
2011-12-08 19:39 ` Ramkumar Ramachandra
2011-12-08 23:48 ` Junio C Hamano
2011-12-09 13:33 ` Jakub Narebski
2011-12-09 18:24 ` Junio C Hamano
2011-12-15 16:45 ` [PATCH 0/2] Improve git-bundle builtin Ramkumar Ramachandra
2011-12-15 16:45 ` [PATCH 2/2] bundle: rewrite builtin to use parse-options Ramkumar Ramachandra
2011-12-15 21:29 ` Jonathan Nieder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1323346028-9201-3-git-send-email-artagnon@gmail.com \
--to=artagnon@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).