parse-opt: migrate builtin-apply.
The only incompatible change is that the user how have to use '--' before a patch file if it is named "--build-fake-ancestor=something". Signed-off-by: Miklos Vajna <vmiklos@frugalware.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Miklos Vajna committed
Dec 28, 2008 at 00:03 UTC
f26c4940c4c7942a95058d9aaef7b01967085a60
2 files changed
+154
-131
Documentation/git-apply.txt
+2
-2
@@ -10,7 +10,7 @@ SYNOPSIS
10
--------
11
[verse]
12
'git apply' [--stat] [--numstat] [--summary] [--check] [--index]
13
- [--apply] [--no-add] [--build-fake-ancestor <file>] [-R | --reverse]
13
+ [--apply] [--no-add] [--build-fake-ancestor=<file>] [-R | --reverse]
14
[--allow-binary-replacement | --binary] [--reject] [-z]
15
[-pNUM] [-CNUM] [--inaccurate-eof] [--recount] [--cached]
16
[--whitespace=<nowarn|warn|fix|error|error-all>]
@@ -64,7 +64,7 @@ OPTIONS
64
cached data, apply the patch, and store the result in the index,
65
without using the working tree. This implies '--index'.
66
67
---build-fake-ancestor <file>::
67
+--build-fake-ancestor=<file>::
68
Newer 'git-diff' output has embedded 'index information'
69
for each blob to help identify the original version that
70
the patch applies to. When this flag is given, and if
builtin-apply.c
+152
-129
@@ -14,6 +14,7 @@
14
#include "builtin.h"
15
#include "string-list.h"
16
#include "dir.h"
17
+#include "parse-options.h"
18
19
/*
20
* --check turns on checking that the working tree matches the
@@ -45,9 +46,11 @@ static int apply_verbosely;
46
static int no_add;
47
static const char *fake_ancestor;
48
static int line_termination = '\n';
48
-static unsigned long p_context = ULONG_MAX;
49
-static const char apply_usage[] =
50
-"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>...";
49
+static unsigned int p_context = UINT_MAX;
50
+static const char * const apply_usage[] = {
51
+ "git apply [options] [<patch>...]",
52
+ NULL
53
+};
54
55
static enum ws_error_action {
56
nowarn_ws_error,
@@ -61,6 +64,8 @@ static int applied_after_fixing_ws;
64
static const char *patch_input_file;
65
static const char *root;
66
static int root_len;
67
+static int read_stdin = 1;
68
+static int options;
69
70
static void parse_whitespace_option(const char *option)
71
{
@@ -3135,150 +3140,168 @@ static int git_apply_config(const char *var, const char *value, void *cb)
3140
return git_default_config(var, value, cb);
3141
}
3142
3143
+static int option_parse_stdin(const struct option *opt,
3144
+ const char *arg, int unset)
3145
+{
3146
+ int *errs = opt->value;
3147
+
3148
+ *errs |= apply_patch(0, "<stdin>", options);
3149
+ read_stdin = 0;
3150
+ return 0;
3151
+}
3152
+
3153
+static int option_parse_exclude(const struct option *opt,
3154
+ const char *arg, int unset)
3155
+{
3156
+ add_name_limit(arg, 1);
3157
+ return 0;
3158
+}
3159
+
3160
+static int option_parse_include(const struct option *opt,
3161
+ const char *arg, int unset)
3162
+{
3163
+ add_name_limit(arg, 0);
3164
+ has_include = 1;
3165
+ return 0;
3166
+}
3167
+
3168
+static int option_parse_p(const struct option *opt,
3169
+ const char *arg, int unset)
3170
+{
3171
+ p_value = atoi(arg);
3172
+ p_value_known = 1;
3173
+ return 0;
3174
+}
3175
+
3176
+static int option_parse_z(const struct option *opt,
3177
+ const char *arg, int unset)
3178
+{
3179
+ if (unset)
3180
+ line_termination = '\n';
3181
+ else
3182
+ line_termination = 0;
3183
+ return 0;
3184
+}
3185
+
3186
+static int option_parse_whitespace(const struct option *opt,
3187
+ const char *arg, int unset)
3188
+{
3189
+ const char **whitespace_option = opt->value;
3190
+
3191
+ *whitespace_option = arg;
3192
+ parse_whitespace_option(arg);
3193
+ return 0;
3194
+}
3195
+
3196
+static int option_parse_directory(const struct option *opt,
3197
+ const char *arg, int unset)
3198
+{
3199
+ root_len = strlen(arg);
3200
+ if (root_len && arg[root_len - 1] != '/') {
3201
+ char *new_root;
3202
+ root = new_root = xmalloc(root_len + 2);
3203
+ strcpy(new_root, arg);
3204
+ strcpy(new_root + root_len++, "/");
3205
+ } else
3206
+ root = arg;
3207
+ return 0;
3208
+}
3209
3210
int cmd_apply(int argc, const char **argv, const char *unused_prefix)
3211
{
3212
int i;
3142
- int read_stdin = 1;
3143
- int options = 0;
3213
int errs = 0;
3214
int is_not_gitdir;
3215
+ int binary;
3216
+ int force_apply = 0;
3217
3218
const char *whitespace_option = NULL;
3219
3220
+ struct option builtin_apply_options[] = {
3221
+ { OPTION_CALLBACK, '-', NULL, &errs, NULL,
3222
+ "read the patch from the standard input",
3223
+ PARSE_OPT_NOARG, option_parse_stdin },
3224
+ { OPTION_CALLBACK, 0, "exclude", NULL, "path",
3225
+ "don´t apply changes matching the given path",
3226
+ 0, option_parse_exclude },
3227
+ { OPTION_CALLBACK, 0, "include", NULL, "path",
3228
+ "apply changes matching the given path",
3229
+ 0, option_parse_include },
3230
+ { OPTION_CALLBACK, 'p', NULL, NULL, "num",
3231
+ "remove <num> leading slashes from traditional diff paths",
3232
+ 0, option_parse_p },
3233
+ OPT_BOOLEAN(0, "no-add", &no_add,
3234
+ "ignore additions made by the patch"),
3235
+ OPT_BOOLEAN(0, "stat", &diffstat,
3236
+ "instead of applying the patch, output diffstat for the input"),
3237
+ OPT_BOOLEAN(0, "allow-binary-replacement", &binary,
3238
+ "now no-op"),
3239
+ OPT_BOOLEAN(0, "binary", &binary,
3240
+ "now no-op"),
3241
+ OPT_BOOLEAN(0, "numstat", &numstat,
3242
+ "shows number of added and deleted lines in decimal notation"),
3243
+ OPT_BOOLEAN(0, "summary", &summary,
3244
+ "instead of applying the patch, output a summary for the input"),
3245
+ OPT_BOOLEAN(0, "check", &check,
3246
+ "instead of applying the patch, see if the patch is applicable"),
3247
+ OPT_BOOLEAN(0, "index", &check_index,
3248
+ "make sure the patch is applicable to the current index"),
3249
+ OPT_BOOLEAN(0, "cached", &cached,
3250
+ "apply a patch without touching the working tree"),
3251
+ OPT_BOOLEAN(0, "apply", &force_apply,
3252
+ "also apply the patch (use with --stat/--summary/--check)"),
3253
+ OPT_STRING(0, "build-fake-ancestor", &fake_ancestor, "file",
3254
+ "build a temporary index based on embedded index information"),
3255
+ { OPTION_CALLBACK, 'z', NULL, NULL, NULL,
3256
+ "paths are separated with NUL character",
3257
+ PARSE_OPT_NOARG, option_parse_z },
3258
+ OPT_INTEGER('C', NULL, &p_context,
3259
+ "ensure at least <n> lines of context match"),
3260
+ { OPTION_CALLBACK, 0, "whitespace", &whitespace_option, "action",
3261
+ "detect new or modified lines that have whitespace errors",
3262
+ 0, option_parse_whitespace },
3263
+ OPT_BOOLEAN('R', "reverse", &apply_in_reverse,
3264
+ "apply the patch in reverse"),
3265
+ OPT_BOOLEAN(0, "unidiff-zero", &unidiff_zero,
3266
+ "don't expect at least one line of context"),
3267
+ OPT_BOOLEAN(0, "reject", &apply_with_reject,
3268
+ "leave the rejected hunks in corresponding *.rej files"),
3269
+ OPT__VERBOSE(&apply_verbosely),
3270
+ OPT_BIT(0, "inaccurate-eof", &options,
3271
+ "tolerate incorrectly detected missing new-line at the end of file",
3272
+ INACCURATE_EOF),
3273
+ OPT_BIT(0, "recount", &options,
3274
+ "do not trust the line counts in the hunk headers",
3275
+ RECOUNT),
3276
+ { OPTION_CALLBACK, 0, "directory", NULL, "root",
3277
+ "prepend <root> to all filenames",
3278
+ 0, option_parse_directory },
3279
+ OPT_END()
3280
+ };
3281
+
3282
prefix = setup_git_directory_gently(&is_not_gitdir);
3283
prefix_length = prefix ? strlen(prefix) : 0;
3284
git_config(git_apply_config, NULL);
3285
if (apply_default_whitespace)
3286
parse_whitespace_option(apply_default_whitespace);
3287
3155
- for (i = 1; i < argc; i++) {
3288
+ argc = parse_options(argc, argv, builtin_apply_options,
3289
+ apply_usage, 0);
3290
+ if (apply_with_reject)
3291
+ apply = apply_verbosely = 1;
3292
+ if (!force_apply && (diffstat || numstat || summary || check || fake_ancestor))
3293
+ apply = 0;
3294
+ if (check_index && is_not_gitdir)
3295
+ die("--index outside a repository");
3296
+ if (cached) {
3297
+ if (is_not_gitdir)
3298
+ die("--cached outside a repository");
3299
+ check_index = 1;
3300
+ }
3301
+ for (i = 0; i < argc; i++) {
3302
const char *arg = argv[i];
3157
- char *end;
3303
int fd;
3304
3160
- if (!strcmp(arg, "-")) {
3161
- errs |= apply_patch(0, "<stdin>", options);
3162
- read_stdin = 0;
3163
- continue;
3164
- }
3165
- if (!prefixcmp(arg, "--exclude=")) {
3166
- add_name_limit(arg + 10, 1);
3167
- continue;
3168
- }
3169
- if (!prefixcmp(arg, "--include=")) {
3170
- add_name_limit(arg + 10, 0);
3171
- has_include = 1;
3172
- continue;
3173
- }
3174
- if (!prefixcmp(arg, "-p")) {
3175
- p_value = atoi(arg + 2);
3176
- p_value_known = 1;
3177
- continue;
3178
- }
3179
- if (!strcmp(arg, "--no-add")) {
3180
- no_add = 1;
3181
- continue;
3182
- }
3183
- if (!strcmp(arg, "--stat")) {
3184
- apply = 0;
3185
- diffstat = 1;
3186
- continue;
3187
- }
3188
- if (!strcmp(arg, "--allow-binary-replacement") ||
3189
- !strcmp(arg, "--binary")) {
3190
- continue; /* now no-op */
3191
- }
3192
- if (!strcmp(arg, "--numstat")) {
3193
- apply = 0;
3194
- numstat = 1;
3195
- continue;
3196
- }
3197
- if (!strcmp(arg, "--summary")) {
3198
- apply = 0;
3199
- summary = 1;
3200
- continue;
3201
- }
3202
- if (!strcmp(arg, "--check")) {
3203
- apply = 0;
3204
- check = 1;
3205
- continue;
3206
- }
3207
- if (!strcmp(arg, "--index")) {
3208
- if (is_not_gitdir)
3209
- die("--index outside a repository");
3210
- check_index = 1;
3211
- continue;
3212
- }
3213
- if (!strcmp(arg, "--cached")) {
3214
- if (is_not_gitdir)
3215
- die("--cached outside a repository");
3216
- check_index = 1;
3217
- cached = 1;
3218
- continue;
3219
- }
3220
- if (!strcmp(arg, "--apply")) {
3221
- apply = 1;
3222
- continue;
3223
- }
3224
- if (!strcmp(arg, "--build-fake-ancestor")) {
3225
- apply = 0;
3226
- if (++i >= argc)
3227
- die ("need a filename");
3228
- fake_ancestor = argv[i];
3229
- continue;
3230
- }
3231
- if (!strcmp(arg, "-z")) {
3232
- line_termination = 0;
3233
- continue;
3234
- }
3235
- if (!prefixcmp(arg, "-C")) {
3236
- p_context = strtoul(arg + 2, &end, 0);
3237
- if (*end != '\0')
3238
- die("unrecognized context count '%s'", arg + 2);
3239
- continue;
3240
- }
3241
- if (!prefixcmp(arg, "--whitespace=")) {
3242
- whitespace_option = arg + 13;
3243
- parse_whitespace_option(arg + 13);
3244
- continue;
3245
- }
3246
- if (!strcmp(arg, "-R") || !strcmp(arg, "--reverse")) {
3247
- apply_in_reverse = 1;
3248
- continue;
3249
- }
3250
- if (!strcmp(arg, "--unidiff-zero")) {
3251
- unidiff_zero = 1;
3252
- continue;
3253
- }
3254
- if (!strcmp(arg, "--reject")) {
3255
- apply = apply_with_reject = apply_verbosely = 1;
3256
- continue;
3257
- }
3258
- if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) {
3259
- apply_verbosely = 1;
3260
- continue;
3261
- }
3262
- if (!strcmp(arg, "--inaccurate-eof")) {
3263
- options |= INACCURATE_EOF;
3264
- continue;
3265
- }
3266
- if (!strcmp(arg, "--recount")) {
3267
- options |= RECOUNT;
3268
- continue;
3269
- }
3270
- if (!prefixcmp(arg, "--directory=")) {
3271
- arg += strlen("--directory=");
3272
- root_len = strlen(arg);
3273
- if (root_len && arg[root_len - 1] != '/') {
3274
- char *new_root;
3275
- root = new_root = xmalloc(root_len + 2);
3276
- strcpy(new_root, arg);
3277
- strcpy(new_root + root_len++, "/");
3278
- } else
3279
- root = arg;
3280
- continue;
3281
- }
3305
if (0 < prefix_length)
3306
arg = prefix_filename(prefix, prefix_length, arg);
3307