From: Miklos Vajna <vmiklos@frugalware.org>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: [PATCH] parse-opt: migrate builtin-apply.
Date: Sat, 27 Dec 2008 05:22:07 +0100 [thread overview]
Message-ID: <1230351727-20116-1-git-send-email-vmiklos@frugalware.org> (raw)
The only notable user-visible/incompatible change is that the
--build-fake-ancestor option now conforms to gitcli(7).
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
I know that we do care about incompatible changes a lot, though I think
this is the right direction and probably --build-fake-ancestor is not a
heavily used switch, so I hope that part is OK.
Documentation/git-apply.txt | 4 +-
builtin-apply.c | 360 ++++++++++++++++++++++++++++---------------
2 files changed, 234 insertions(+), 130 deletions(-)
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index e726510..9400f6a 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -10,7 +10,7 @@ SYNOPSIS
--------
[verse]
'git apply' [--stat] [--numstat] [--summary] [--check] [--index]
- [--apply] [--no-add] [--build-fake-ancestor <file>] [-R | --reverse]
+ [--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
[--allow-binary-replacement | --binary] [--reject] [-z]
[-pNUM] [-CNUM] [--inaccurate-eof] [--recount] [--cached]
[--whitespace=<nowarn|warn|fix|error|error-all>]
@@ -64,7 +64,7 @@ OPTIONS
cached data, apply the patch, and store the result in the index,
without using the working tree. This implies '--index'.
---build-fake-ancestor <file>::
+--build-fake-ancestor=<file>::
Newer 'git-diff' output has embedded 'index information'
for each blob to help identify the original version that
the patch applies to. When this flag is given, and if
diff --git a/builtin-apply.c b/builtin-apply.c
index 07244b0..c2a587f 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -14,6 +14,7 @@
#include "builtin.h"
#include "string-list.h"
#include "dir.h"
+#include "parse-options.h"
/*
* --check turns on checking that the working tree matches the
@@ -46,8 +47,10 @@ static int no_add;
static const char *fake_ancestor;
static int line_termination = '\n';
static unsigned long p_context = ULONG_MAX;
-static const char apply_usage[] =
-"git apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|fix|error|error-all>] <patch>...";
+static const char * const apply_usage[] = {
+ "git apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|fix|error|error-all>] <patch>...",
+ NULL
+};
static enum ws_error_action {
nowarn_ws_error,
@@ -61,6 +64,8 @@ static int applied_after_fixing_ws;
static const char *patch_input_file;
static const char *root;
static int root_len;
+static int read_stdin = 1;
+static int options;
static void parse_whitespace_option(const char *option)
{
@@ -3135,150 +3140,249 @@ static int git_apply_config(const char *var, const char *value, void *cb)
return git_default_config(var, value, cb);
}
+static int option_parse_stdin(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *errs = opt->value;
+
+ *errs |= apply_patch(0, "<stdin>", options);
+ read_stdin = 0;
+ return 0;
+}
+
+static int option_parse_exclude(const struct option *opt,
+ const char *arg, int unset)
+{
+ add_name_limit(arg, 1);
+ return 0;
+}
+
+static int option_parse_include(const struct option *opt,
+ const char *arg, int unset)
+{
+ add_name_limit(arg, 0);
+ has_include = 1;
+ return 0;
+}
+
+static int option_parse_p(const struct option *opt,
+ const char *arg, int unset)
+{
+ p_value = atoi(arg);
+ p_value_known = 1;
+ return 0;
+}
+
+static int option_parse_stat(const struct option *opt,
+ const char *arg, int unset)
+{
+ apply = 0;
+ diffstat = 1;
+ return 0;
+}
+
+static int option_parse_numstat(const struct option *opt,
+ const char *arg, int unset)
+{
+ apply = 0;
+ numstat = 1;
+ return 0;
+}
+
+static int option_parse_summary(const struct option *opt,
+ const char *arg, int unset)
+{
+ apply = 0;
+ summary = 1;
+ return 0;
+}
+
+static int option_parse_check(const struct option *opt,
+ const char *arg, int unset)
+{
+ apply = 0;
+ check = 1;
+ return 0;
+}
+
+static int option_parse_index(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *is_not_gitdir = opt->value;
+
+ if (*is_not_gitdir)
+ die("--index outside a repository");
+ check_index = 1;
+ return 0;
+}
+
+static int option_parse_cached(const struct option *opt,
+ const char *arg, int unset)
+{
+ int *is_not_gitdir = opt->value;
+
+ if (*is_not_gitdir)
+ die("--cached outside a repository");
+ check_index = 1;
+ cached = 1;
+ return 0;
+}
+
+static int option_parse_ancestor(const struct option *opt,
+ const char *arg, int unset)
+{
+ apply = 0;
+ fake_ancestor = arg;
+ return 0;
+}
+
+static int option_parse_z(const struct option *opt,
+ const char *arg, int unset)
+{
+ if (unset)
+ line_termination = '\n';
+ else
+ line_termination = 0;
+ return 0;
+}
+
+static int option_parse_whitespace(const struct option *opt,
+ const char *arg, int unset)
+{
+ const char **whitespace_option = opt->value;
+
+ *whitespace_option = arg;
+ parse_whitespace_option(arg);
+ return 0;
+}
+
+static int option_parse_reject(const struct option *opt,
+ const char *arg, int unset)
+{
+ apply = apply_with_reject = apply_verbosely = 1;
+ return 0;
+}
+
+static int option_parse_inaccurate(const struct option *opt,
+ const char *arg, int unset)
+{
+ options |= INACCURATE_EOF;
+ return 0;
+}
+
+static int option_parse_recount(const struct option *opt,
+ const char *arg, int unset)
+{
+ options |= RECOUNT;
+ return 0;
+}
+
+static int option_parse_directory(const struct option *opt,
+ const char *arg, int unset)
+{
+ root_len = strlen(arg);
+ if (root_len && arg[root_len - 1] != '/') {
+ char *new_root;
+ root = new_root = xmalloc(root_len + 2);
+ strcpy(new_root, arg);
+ strcpy(new_root + root_len++, "/");
+ } else
+ root = arg;
+ return 0;
+}
int cmd_apply(int argc, const char **argv, const char *unused_prefix)
{
int i;
- int read_stdin = 1;
- int options = 0;
int errs = 0;
int is_not_gitdir;
+ int binary;
const char *whitespace_option = NULL;
+ struct option builtin_apply_options[] = {
+ { OPTION_CALLBACK, '-', NULL, &errs, NULL,
+ "read the patch from the standard input",
+ PARSE_OPT_NOARG, option_parse_stdin },
+ { OPTION_CALLBACK, 0, "exclude", NULL, "path",
+ "don´t apply changes matching the given path",
+ 0, option_parse_exclude },
+ { OPTION_CALLBACK, 0, "include", NULL, "path",
+ "apply changes matching the given path",
+ 0, option_parse_include },
+ { OPTION_CALLBACK, 'p', NULL, NULL, "num",
+ "remove <num> leading slashes from traditional diff paths",
+ 0, option_parse_p },
+ OPT_BOOLEAN(0, "no-add", &no_add,
+ "ignore additions made by the patch"),
+ { OPTION_CALLBACK, 0, "stat", NULL, NULL,
+ "instead of applying the patch, output diffstat for the input",
+ PARSE_OPT_NOARG, option_parse_stat },
+ OPT_BOOLEAN(0, "allow-binary-replacement", &binary,
+ "now no-op"),
+ OPT_BOOLEAN(0, "binary", &binary,
+ "now no-op"),
+ { OPTION_CALLBACK, 0, "numstat", NULL, NULL,
+ "shows number of added and deleted lines in decimal notation",
+ PARSE_OPT_NOARG, option_parse_numstat },
+ { OPTION_CALLBACK, 0, "summary", NULL, NULL,
+ "instead of applying the patch, output a summary for the input",
+ PARSE_OPT_NOARG, option_parse_summary },
+ { OPTION_CALLBACK, 0, "check", NULL, NULL,
+ "instead of applying the patch, see if the patch is applicable",
+ PARSE_OPT_NOARG, option_parse_check },
+ { OPTION_CALLBACK, 0, "index", &is_not_gitdir, NULL,
+ "make sure the patch is applicable to the current index",
+ PARSE_OPT_NOARG, option_parse_index },
+ { OPTION_CALLBACK, 0, "cached", &is_not_gitdir, NULL,
+ "apply a patch without touching the working tree",
+ PARSE_OPT_NOARG, option_parse_cached },
+ OPT_BOOLEAN(0, "apply", &apply,
+ "also apply the patch (use with --stat/--summary/--check)"),
+ { OPTION_CALLBACK, 0, "build-fake-ancestor", NULL, "file",
+ "build a temporary index based on embedded index information",
+ 0, option_parse_ancestor },
+ { OPTION_CALLBACK, 'z', NULL, NULL, NULL,
+ "paths are separated with NUL character",
+ PARSE_OPT_NOARG, option_parse_z },
+ OPT_INTEGER('C', NULL, &p_context,
+ "ensure at least <n> lines of context match"),
+ { OPTION_CALLBACK, 0, "whitespace", &whitespace_option, "action",
+ "detect new or modified lines that have whitespace errors",
+ 0, option_parse_whitespace },
+ OPT_BOOLEAN('R', "reverse", &apply_in_reverse,
+ "apply the patch in reverse"),
+ OPT_BOOLEAN(0, "unidiff-zero", &unidiff_zero,
+ "don't expect at least one line of context"),
+ { OPTION_CALLBACK, 0, "reject", NULL, NULL,
+ "leave the rejected hunks in corresponding *.rej files",
+ PARSE_OPT_NOARG, option_parse_reject },
+ OPT__VERBOSE(&apply_verbosely),
+ { OPTION_CALLBACK, 0, "inaccurate-eof", NULL, NULL,
+ "tolerate incorrectly detected missing new-line at the end of file",
+ PARSE_OPT_NOARG, option_parse_inaccurate },
+ { OPTION_CALLBACK, 0, "recount", NULL, NULL,
+ "do not trust the line counts in the hunk headers",
+ PARSE_OPT_NOARG, option_parse_recount },
+ { OPTION_CALLBACK, 0, "directory", NULL, "root",
+ "prepend <root> to all filenames",
+ 0, option_parse_directory },
+ OPT_END()
+ };
+
prefix = setup_git_directory_gently(&is_not_gitdir);
prefix_length = prefix ? strlen(prefix) : 0;
git_config(git_apply_config, NULL);
if (apply_default_whitespace)
parse_whitespace_option(apply_default_whitespace);
- for (i = 1; i < argc; i++) {
+ argc = parse_options(argc, argv, builtin_apply_options,
+ apply_usage, 0);
+
+ for (i = 0; i < argc; i++) {
const char *arg = argv[i];
- char *end;
int fd;
- if (!strcmp(arg, "-")) {
- errs |= apply_patch(0, "<stdin>", options);
- read_stdin = 0;
- continue;
- }
- if (!prefixcmp(arg, "--exclude=")) {
- add_name_limit(arg + 10, 1);
- continue;
- }
- if (!prefixcmp(arg, "--include=")) {
- add_name_limit(arg + 10, 0);
- has_include = 1;
- continue;
- }
- if (!prefixcmp(arg, "-p")) {
- p_value = atoi(arg + 2);
- p_value_known = 1;
- continue;
- }
- if (!strcmp(arg, "--no-add")) {
- no_add = 1;
- continue;
- }
- if (!strcmp(arg, "--stat")) {
- apply = 0;
- diffstat = 1;
- continue;
- }
- if (!strcmp(arg, "--allow-binary-replacement") ||
- !strcmp(arg, "--binary")) {
- continue; /* now no-op */
- }
- if (!strcmp(arg, "--numstat")) {
- apply = 0;
- numstat = 1;
- continue;
- }
- if (!strcmp(arg, "--summary")) {
- apply = 0;
- summary = 1;
- continue;
- }
- if (!strcmp(arg, "--check")) {
- apply = 0;
- check = 1;
- continue;
- }
- if (!strcmp(arg, "--index")) {
- if (is_not_gitdir)
- die("--index outside a repository");
- check_index = 1;
- continue;
- }
- if (!strcmp(arg, "--cached")) {
- if (is_not_gitdir)
- die("--cached outside a repository");
- check_index = 1;
- cached = 1;
- continue;
- }
- if (!strcmp(arg, "--apply")) {
- apply = 1;
- continue;
- }
- if (!strcmp(arg, "--build-fake-ancestor")) {
- apply = 0;
- if (++i >= argc)
- die ("need a filename");
- fake_ancestor = argv[i];
- continue;
- }
- if (!strcmp(arg, "-z")) {
- line_termination = 0;
- continue;
- }
- if (!prefixcmp(arg, "-C")) {
- p_context = strtoul(arg + 2, &end, 0);
- if (*end != '\0')
- die("unrecognized context count '%s'", arg + 2);
- continue;
- }
- if (!prefixcmp(arg, "--whitespace=")) {
- whitespace_option = arg + 13;
- parse_whitespace_option(arg + 13);
- continue;
- }
- if (!strcmp(arg, "-R") || !strcmp(arg, "--reverse")) {
- apply_in_reverse = 1;
- continue;
- }
- if (!strcmp(arg, "--unidiff-zero")) {
- unidiff_zero = 1;
- continue;
- }
- if (!strcmp(arg, "--reject")) {
- apply = apply_with_reject = apply_verbosely = 1;
- continue;
- }
- if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
- apply_verbosely = 1;
- continue;
- }
- if (!strcmp(arg, "--inaccurate-eof")) {
- options |= INACCURATE_EOF;
- continue;
- }
- if (!strcmp(arg, "--recount")) {
- options |= RECOUNT;
- continue;
- }
- if (!prefixcmp(arg, "--directory=")) {
- arg += strlen("--directory=");
- root_len = strlen(arg);
- if (root_len && arg[root_len - 1] != '/') {
- char *new_root;
- root = new_root = xmalloc(root_len + 2);
- strcpy(new_root, arg);
- strcpy(new_root + root_len++, "/");
- } else
- root = arg;
- continue;
- }
if (0 < prefix_length)
arg = prefix_filename(prefix, prefix_length, arg);
--
1.6.1.rc1.35.gae26e.dirty
next reply other threads:[~2008-12-27 4:22 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-27 4:22 Miklos Vajna [this message]
2008-12-27 7:29 ` [PATCH] parse-opt: migrate builtin-apply Junio C Hamano
2008-12-27 14:05 ` Miklos Vajna
2008-12-27 14:22 ` [PATCH v2] " Miklos Vajna
2008-12-27 21:47 ` Junio C Hamano
2009-01-05 19:12 ` Pierre Habouzit
2009-01-05 20:06 ` Miklos Vajna
2008-12-27 21:53 ` René Scharfe
2008-12-27 23:03 ` [PATCH] " Miklos Vajna
2008-12-28 0:05 ` Jacob Helwig
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=1230351727-20116-1-git-send-email-vmiklos@frugalware.org \
--to=vmiklos@frugalware.org \
--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).