X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=checkout-index.c;h=f54c606414c27a7fc42a557fb0dee438b2abffec;hb=0c1fc940eeae051e890304c40d1e66a478afadc8;hp=dab3778a9585bcfde98be436255542df13aacddb;hpb=8fc66df237afce0b4318657f166b3583831949f3;p=git.git diff --git a/checkout-index.c b/checkout-index.c index dab3778a..f54c6064 100644 --- a/checkout-index.c +++ b/checkout-index.c @@ -22,6 +22,10 @@ * * find . -name '*.h' -print0 | xargs -0 git-checkout-index -f -- * + * or: + * + * find . -name '*.h' -print0 | git-checkout-index -f -z --stdin + * * 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 @@ -33,6 +37,12 @@ * but get used to it in scripting!). */ #include "cache.h" +#include "strbuf.h" +#include "quote.h" + +static const char *prefix; +static int prefix_length; +static int checkout_stage; /* default to checkout stage0 */ static struct checkout state = { .base_dir = "", @@ -45,20 +55,36 @@ static struct checkout state = { static int checkout_file(const char *name) { - int pos = cache_name_pos(name, strlen(name)); - if (pos < 0) { - if (!state.quiet) { - pos = -pos - 1; - fprintf(stderr, - "git-checkout-index: %s is %s.\n", - name, - (pos < active_nr && - !strcmp(active_cache[pos]->name, name)) ? - "unmerged" : "not in the cache"); - } - return -1; + int namelen = strlen(name); + int pos = cache_name_pos(name, namelen); + int has_same_name = 0; + + if (pos < 0) + pos = -pos - 1; + + while (pos < active_nr) { + struct cache_entry *ce = active_cache[pos]; + if (ce_namelen(ce) != namelen || + memcmp(ce->name, name, namelen)) + break; + has_same_name = 1; + if (checkout_stage == ce_stage(ce)) + return checkout_entry(ce, &state); + pos++; + } + + if (!state.quiet) { + fprintf(stderr, "git-checkout-index: %s ", name); + if (!has_same_name) + fprintf(stderr, "is not in the cache"); + else if (checkout_stage) + fprintf(stderr, "does not exist at stage %d", + checkout_stage); + else + fprintf(stderr, "is unmerged"); + fputc('\n', stderr); } - return checkout_entry(active_cache[pos], &state); + return -1; } static int checkout_all(void) @@ -67,7 +93,11 @@ static int checkout_all(void) for (i = 0; i < active_nr ; i++) { struct cache_entry *ce = active_cache[i]; - if (ce_stage(ce)) + if (ce_stage(ce) != checkout_stage) + continue; + if (prefix && *prefix && + (ce_namelen(ce) <= prefix_length || + memcmp(prefix, ce->name, prefix_length))) continue; if (checkout_entry(ce, &state) < 0) errs++; @@ -81,7 +111,7 @@ static int checkout_all(void) } static const char checkout_cache_usage[] = -"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--prefix=] [--] ..."; +"git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]] [--prefix=] [--] ..."; static struct cache_file cache_file; @@ -90,6 +120,12 @@ int main(int argc, char **argv) int i; int newfd = -1; int all = 0; + int read_from_stdin = 0; + int line_termination = '\n'; + + prefix = setup_git_directory(); + git_config(git_default_config); + prefix_length = prefix ? strlen(prefix) : 0; if (read_cache() < 0) { die("invalid cache"); @@ -128,11 +164,30 @@ int main(int argc, char **argv) die("cannot open index.lock file."); continue; } - if (!memcmp(arg, "--prefix=", 9)) { + if (!strcmp(arg, "-z")) { + line_termination = 0; + continue; + } + if (!strcmp(arg, "--stdin")) { + if (i != argc - 1) + die("--stdin must be at the end"); + read_from_stdin = 1; + i++; /* do not consider arg as a file name */ + break; + } + if (!strncmp(arg, "--prefix=", 9)) { state.base_dir = arg+9; state.base_dir_len = strlen(state.base_dir); continue; } + if (!strncmp(arg, "--stage=", 8)) { + int ch = arg[8]; + if ('1' <= ch && ch <= '3') + checkout_stage = arg[8] - '0'; + else + die("stage should be between 1 and 3"); + continue; + } if (arg[0] == '-') usage(checkout_cache_usage); break; @@ -155,7 +210,29 @@ int main(int argc, char **argv) if (all) die("git-checkout-index: don't mix '--all' and explicit filenames"); - checkout_file(arg); + if (read_from_stdin) + die("git-checkout-index: don't mix '--stdin' and explicit filenames"); + checkout_file(prefix_path(prefix, prefix_length, arg)); + } + + if (read_from_stdin) { + struct strbuf buf; + if (all) + die("git-checkout-index: don't mix '--all' and '--stdin'"); + strbuf_init(&buf); + while (1) { + char *path_name; + read_line(&buf, stdin, line_termination); + if (buf.eof) + break; + if (line_termination && buf.buf[0] == '"') + path_name = unquote_c_style(buf.buf, NULL); + else + path_name = buf.buf; + checkout_file(prefix_path(prefix, prefix_length, path_name)); + if (path_name != buf.buf) + free(path_name); + } } if (all)