@matheusbsbs / matheus-bagliano / commits / f26c4940c4
Fork 0

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