Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Check-out files from the "current cache directory" |
| 3 | * |
| 4 | * Copyright (C) 2005 Linus Torvalds |
| 5 | * |
| 6 | * Careful: order of argument flags does matter. For example, |
| 7 | * |
Junio C Hamano | 215a7ad | 2005-09-07 17:26:23 -0700 | [diff] [blame] | 8 | * git-checkout-index -a -f file.c |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 9 | * |
| 10 | * Will first check out all files listed in the cache (but not |
| 11 | * overwrite any old ones), and then force-checkout "file.c" a |
| 12 | * second time (ie that one _will_ overwrite any old contents |
| 13 | * with the same filename). |
| 14 | * |
Junio C Hamano | 215a7ad | 2005-09-07 17:26:23 -0700 | [diff] [blame] | 15 | * Also, just doing "git-checkout-index" does nothing. You probably |
| 16 | * meant "git-checkout-index -a". And if you want to force it, you |
| 17 | * want "git-checkout-index -f -a". |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 18 | * |
| 19 | * Intuitiveness is not the goal here. Repeatability is. The |
| 20 | * reason for the "no arguments means no work" thing is that |
| 21 | * from scripts you are supposed to be able to do things like |
| 22 | * |
Junio C Hamano | 215a7ad | 2005-09-07 17:26:23 -0700 | [diff] [blame] | 23 | * find . -name '*.h' -print0 | xargs -0 git-checkout-index -f -- |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 24 | * |
| 25 | * which will force all existing *.h files to be replaced with |
| 26 | * their cached copies. If an empty command line implied "all", |
| 27 | * then this would force-refresh everything in the cache, which |
| 28 | * was not the point. |
| 29 | * |
| 30 | * Oh, and the "--" is just a good idea when you know the rest |
| 31 | * will be filenames. Just so that you wouldn't have a filename |
| 32 | * of "-a" causing problems (not possible in the above example, |
| 33 | * but get used to it in scripting!). |
| 34 | */ |
| 35 | #include "cache.h" |
| 36 | |
Junio C Hamano | c3e9a65 | 2005-11-26 00:22:48 -0800 | [diff] [blame] | 37 | static const char *prefix; |
| 38 | static int prefix_length; |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 39 | static int checkout_stage; /* default to checkout stage0 */ |
Junio C Hamano | c3e9a65 | 2005-11-26 00:22:48 -0800 | [diff] [blame] | 40 | |
Linus Torvalds | 12dccc1 | 2005-06-05 21:59:54 -0700 | [diff] [blame] | 41 | static struct checkout state = { |
| 42 | .base_dir = "", |
| 43 | .base_dir_len = 0, |
| 44 | .force = 0, |
| 45 | .quiet = 0, |
| 46 | .not_new = 0, |
| 47 | .refresh_cache = 0, |
| 48 | }; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 49 | |
Junio C Hamano | d7f6ea3 | 2005-05-24 01:51:27 -0700 | [diff] [blame] | 50 | static int checkout_file(const char *name) |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 51 | { |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 52 | int namelen = strlen(name); |
| 53 | int pos = cache_name_pos(name, namelen); |
| 54 | int has_same_name = 0; |
| 55 | |
| 56 | if (pos < 0) |
| 57 | pos = -pos - 1; |
| 58 | |
| 59 | while (pos < active_nr) { |
| 60 | struct cache_entry *ce = active_cache[pos]; |
Junio C Hamano | f4f9ada | 2005-12-13 21:39:56 -0800 | [diff] [blame] | 61 | if (ce_namelen(ce) != namelen || |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 62 | memcmp(ce->name, name, namelen)) |
| 63 | break; |
| 64 | has_same_name = 1; |
| 65 | if (checkout_stage == ce_stage(ce)) |
| 66 | return checkout_entry(ce, &state); |
| 67 | pos++; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 68 | } |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 69 | |
| 70 | if (!state.quiet) { |
| 71 | fprintf(stderr, "git-checkout-index: %s ", name); |
| 72 | if (!has_same_name) |
| 73 | fprintf(stderr, "is not in the cache"); |
| 74 | else if (checkout_stage) |
| 75 | fprintf(stderr, "does not exist at stage %d", |
| 76 | checkout_stage); |
| 77 | else |
| 78 | fprintf(stderr, "is unmerged"); |
| 79 | fputc('\n', stderr); |
| 80 | } |
| 81 | return -1; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 82 | } |
| 83 | |
Junio C Hamano | d7f6ea3 | 2005-05-24 01:51:27 -0700 | [diff] [blame] | 84 | static int checkout_all(void) |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 85 | { |
Junio C Hamano | 4b12dae | 2005-10-03 12:44:48 -0700 | [diff] [blame] | 86 | int i, errs = 0; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 87 | |
| 88 | for (i = 0; i < active_nr ; i++) { |
| 89 | struct cache_entry *ce = active_cache[i]; |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 90 | if (ce_stage(ce) != checkout_stage) |
Linus Torvalds | d9f98ee | 2005-04-17 18:39:14 -0700 | [diff] [blame] | 91 | continue; |
Junio C Hamano | c3e9a65 | 2005-11-26 00:22:48 -0800 | [diff] [blame] | 92 | if (prefix && *prefix && |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 93 | (ce_namelen(ce) <= prefix_length || |
| 94 | memcmp(prefix, ce->name, prefix_length))) |
Junio C Hamano | c3e9a65 | 2005-11-26 00:22:48 -0800 | [diff] [blame] | 95 | continue; |
Linus Torvalds | 12dccc1 | 2005-06-05 21:59:54 -0700 | [diff] [blame] | 96 | if (checkout_entry(ce, &state) < 0) |
Junio C Hamano | 4b12dae | 2005-10-03 12:44:48 -0700 | [diff] [blame] | 97 | errs++; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 98 | } |
Junio C Hamano | 4b12dae | 2005-10-03 12:44:48 -0700 | [diff] [blame] | 99 | if (errs) |
| 100 | /* we have already done our error reporting. |
| 101 | * exit with the same code as die(). |
| 102 | */ |
| 103 | exit(128); |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 104 | return 0; |
| 105 | } |
| 106 | |
Petr Baudis | 4d1f119 | 2005-07-29 11:01:26 +0200 | [diff] [blame] | 107 | static const char checkout_cache_usage[] = |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 108 | "git-checkout-index [-u] [-q] [-a] [-f] [-n] [--stage=[123]] [--prefix=<string>] [--] <file>..."; |
Junio C Hamano | d46ad9c | 2005-07-13 20:25:07 -0700 | [diff] [blame] | 109 | |
James Bottomley | 31f584c | 2005-08-13 10:29:32 -0500 | [diff] [blame] | 110 | static struct cache_file cache_file; |
| 111 | |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 112 | int main(int argc, char **argv) |
| 113 | { |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 114 | int i; |
Junio C Hamano | 415e96c | 2005-05-15 14:23:12 -0700 | [diff] [blame] | 115 | int newfd = -1; |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 116 | int all = 0; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 117 | |
Junio C Hamano | c3e9a65 | 2005-11-26 00:22:48 -0800 | [diff] [blame] | 118 | prefix = setup_git_directory(); |
| 119 | prefix_length = prefix ? strlen(prefix) : 0; |
| 120 | |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 121 | if (read_cache() < 0) { |
Petr Baudis | 2de381f | 2005-04-13 02:28:48 -0700 | [diff] [blame] | 122 | die("invalid cache"); |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 123 | } |
| 124 | |
| 125 | for (i = 1; i < argc; i++) { |
| 126 | const char *arg = argv[i]; |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 127 | |
| 128 | if (!strcmp(arg, "--")) { |
| 129 | i++; |
| 130 | break; |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 131 | } |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 132 | if (!strcmp(arg, "-a") || !strcmp(arg, "--all")) { |
| 133 | all = 1; |
| 134 | continue; |
Junio C Hamano | 415e96c | 2005-05-15 14:23:12 -0700 | [diff] [blame] | 135 | } |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 136 | if (!strcmp(arg, "-f") || !strcmp(arg, "--force")) { |
| 137 | state.force = 1; |
| 138 | continue; |
| 139 | } |
| 140 | if (!strcmp(arg, "-q") || !strcmp(arg, "--quiet")) { |
| 141 | state.quiet = 1; |
| 142 | continue; |
| 143 | } |
| 144 | if (!strcmp(arg, "-n") || !strcmp(arg, "--no-create")) { |
| 145 | state.not_new = 1; |
| 146 | continue; |
| 147 | } |
| 148 | if (!strcmp(arg, "-u") || !strcmp(arg, "--index")) { |
| 149 | state.refresh_cache = 1; |
| 150 | if (newfd < 0) |
| 151 | newfd = hold_index_file_for_update |
| 152 | (&cache_file, |
| 153 | get_index_file()); |
| 154 | if (newfd < 0) |
| 155 | die("cannot open index.lock file."); |
| 156 | continue; |
| 157 | } |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 158 | if (!strncmp(arg, "--prefix=", 9)) { |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 159 | state.base_dir = arg+9; |
| 160 | state.base_dir_len = strlen(state.base_dir); |
| 161 | continue; |
| 162 | } |
Junio C Hamano | 3bd348a | 2005-12-07 00:29:51 -0800 | [diff] [blame] | 163 | if (!strncmp(arg, "--stage=", 8)) { |
| 164 | int ch = arg[8]; |
| 165 | if ('1' <= ch && ch <= '3') |
| 166 | checkout_stage = arg[8] - '0'; |
| 167 | else |
| 168 | die("stage should be between 1 and 3"); |
| 169 | continue; |
| 170 | } |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 171 | if (arg[0] == '-') |
| 172 | usage(checkout_cache_usage); |
| 173 | break; |
| 174 | } |
| 175 | |
| 176 | if (state.base_dir_len) { |
| 177 | /* when --prefix is specified we do not |
| 178 | * want to update cache. |
| 179 | */ |
| 180 | if (state.refresh_cache) { |
| 181 | close(newfd); newfd = -1; |
| 182 | rollback_index_file(&cache_file); |
| 183 | } |
| 184 | state.refresh_cache = 0; |
| 185 | } |
| 186 | |
| 187 | /* Check out named files first */ |
| 188 | for ( ; i < argc; i++) { |
| 189 | const char *arg = argv[i]; |
| 190 | |
| 191 | if (all) |
| 192 | die("git-checkout-index: don't mix '--all' and explicit filenames"); |
Junio C Hamano | c3e9a65 | 2005-11-26 00:22:48 -0800 | [diff] [blame] | 193 | checkout_file(prefix_path(prefix, prefix_length, arg)); |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 194 | } |
Junio C Hamano | 415e96c | 2005-05-15 14:23:12 -0700 | [diff] [blame] | 195 | |
Linus Torvalds | a65a686 | 2005-10-17 17:32:12 -0700 | [diff] [blame] | 196 | if (all) |
| 197 | checkout_all(); |
| 198 | |
Junio C Hamano | 415e96c | 2005-05-15 14:23:12 -0700 | [diff] [blame] | 199 | if (0 <= newfd && |
| 200 | (write_cache(newfd, active_cache, active_nr) || |
| 201 | commit_index_file(&cache_file))) |
| 202 | die("Unable to write new cachefile"); |
Linus Torvalds | 33db5f4 | 2005-04-09 09:53:05 -0700 | [diff] [blame] | 203 | return 0; |
| 204 | } |