Index: checkout-cache.c =================================================================== --- 4708925e3e3b955ffcb417fc4acdbb0aafdf8dc0/checkout-cache.c (mode:100644) +++ uncommitted/checkout-cache.c (mode:100644) @@ -3,8 +3,6 @@ * * Copyright (C) 2005 Linus Torvalds * - * Careful: order of argument flags does matter. For example, - * * git-checkout-cache -a -f file.c * * Will first check out all files listed in the cache (but not @@ -14,7 +12,7 @@ * * Also, just doing "git-checkout-cache" does nothing. You probably * meant "git-checkout-cache -a". And if you want to force it, you - * want "git-checkout-cache -f -a". + * want "git-checkout-cache -A". * * Intuitiveness is not the goal here. Repeatability is. The * reason for the "no arguments means no work" thing is that @@ -25,7 +23,7 @@ * which will force all existing *.h files to be replaced with * their cached copies. If an empty command line implied "all", * then this would force-refresh everything in the cache, which - * was not the point. + * was not the point. However, please note the -r option of xargs. * * Oh, and the "--" is just a good idea when you know the rest * will be filenames. Just so that you wouldn't have a filename @@ -35,8 +33,12 @@ #include #include #include "cache.h" +#include +const char *argp_program_version = VERSION; static int force = 0, quiet = 0, not_new = 0, refresh_cache = 0; +static int force_opt = 0, force_all = 0, all = 0; +static const char *base_opt = ""; static void create_directories(const char *path) { @@ -226,68 +228,67 @@ return 0; } +static const char doc[] = "Populate working tree with files from cache"; + +static struct argp_option options[] = { + {"prefix", 1, "base", 0, "Prepend base to each file before checkout"}, + {"all", 'a', 0, 0, "Checkout entire cache, will NOT overwrite"}, + {"forceall", 'A', 0, 0, "Checkout entire cache, with overwrite"}, + {"force", 'f', 0, 0, "Checkout files listed on command line, with overwrite"}, + {"quiet", 'q', 0, 0, "Suppress warnings"}, + {"not-new", 'n', 0, 0, "Checkout existing files only"}, + {"update", 'u', 0, 0, "Update cache with new stat info"}, + { } +}; + +static error_t parse_opt (int key, char *arg, struct argp_state *state) +{ + switch (key) { + case 'a': all = 1; break; + case 'q': quiet = 1; break; + case 'n': not_new = 1; break; + case 'f': force_opt = 1; break; + case 1: base_opt = arg; break; + case 'u': refresh_cache = 1; break; + case 'A': force_all = 1; all = 1; break; + default: return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static const struct argp argp = { options, parse_opt, "[FILES...]", doc }; + int main(int argc, char **argv) { - int i, force_filename = 0; - const char *base_dir = ""; struct cache_file cache_file; - int newfd = -1; + int i, idx, newfd = -1; if (read_cache() < 0) { die("invalid cache"); } - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; - if (!force_filename) { - if (!strcmp(arg, "-a")) { - checkout_all(base_dir); - continue; - } - if (!strcmp(arg, "--")) { - force_filename = 1; - continue; - } - if (!strcmp(arg, "-f")) { - force = 1; - continue; - } - if (!strcmp(arg, "-q")) { - quiet = 1; - continue; - } - if (!strcmp(arg, "-n")) { - not_new = 1; - continue; - } - if (!strcmp(arg, "-u")) { - refresh_cache = 1; - if (newfd < 0) - newfd = hold_index_file_for_update - (&cache_file, - get_index_file()); - if (newfd < 0) - die("cannot open index.lock file."); - continue; - } - if (!memcmp(arg, "--prefix=", 9)) { - base_dir = arg+9; - continue; - } - } - if (base_dir[0]) { - /* when --prefix is specified we do not - * want to update cache. - */ - if (refresh_cache) { - close(newfd); newfd = -1; - rollback_index_file(&cache_file); - } - refresh_cache = 0; - } - checkout_file(arg, base_dir); + error_t rc = argp_parse(&argp, argc, argv, 0, &idx, NULL); + if (rc) { + fprintf(stderr, "argument failed: %s\n", strerror(rc)); + return 1; } + if (refresh_cache) { + if (base_opt[0]) + die("cannot update cache when --prefix option is used"); + newfd = hold_index_file_for_update(&cache_file, get_index_file()); + if (newfd < 0) + die("cannot open index.lock file."); + } + + force = force_all; + if (all) + checkout_all(base_opt); + + force = force_opt; + for (i = idx; i < argc; i++) + checkout_file(argv[i], base_opt); + if (0 <= newfd && (write_cache(newfd, active_cache, active_nr) || commit_index_file(&cache_file))) Index: Documentation/git-checkout-cache.txt =================================================================== --- 4708925e3e3b955ffcb417fc4acdbb0aafdf8dc0/Documentation/git-checkout-cache.txt (mode:100644) +++ uncommitted/Documentation/git-checkout-cache.txt (mode:100644) @@ -9,8 +9,8 @@ SYNOPSIS -------- -'git-checkout-cache' [-u] [-q] [-a] [-f] [-n] [--prefix=] - [--] ... +'git-checkout-cache' [-u] [-q] [-a] [-A] [-f] [-n] [--prefix=] + [--] [file]... DESCRIPTION ----------- @@ -24,15 +24,20 @@ the cache file. -q:: - be quiet if files exist or are not in the cache + be quiet if files exist or are not in the cache. -f:: - forces overwrite of existing files + forces overwrite when checking out files listed on the + command line (does not apply to -a option). -a:: checks out all files in the cache (will then continue to process listed files). +-A:: + checks out all files in the cache, forces overwrite of + existing files. + -n:: Don't checkout new files, only refresh files already checked out. @@ -44,7 +49,7 @@ --:: Do not interpret any more arguments as options. -Note that the order of the flags matters: +Example: git-checkout-cache -a -f file.c @@ -54,7 +59,7 @@ Also, just doing "git-checkout-cache" does nothing. You probably meant "git-checkout-cache -a". And if you want to force it, you want -"git-checkout-cache -f -a". +"git-checkout-cache -A". Intuitiveness is not the goal here. Repeatability is. The reason for the "no arguments means no work" thing is that from scripts you are