cc4298ac4fa501136cfec192c047bc92138d5285
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "cache.h"
   7
   8/*
   9 * Default to not allowing changes to the list of files. The
  10 * tool doesn't actually care, but this makes it harder to add
  11 * files to the revision control by mistake by doing something
  12 * like "git-update-cache *" and suddenly having all the object
  13 * files be revision controlled.
  14 */
  15static int allow_add = 0, allow_remove = 0, allow_replace = 0, not_new = 0, quiet = 0, info_only = 0;
  16static int force_remove;
  17
  18/* Three functions to allow overloaded pointer return; see linux/err.h */
  19static inline void *ERR_PTR(long error)
  20{
  21        return (void *) error;
  22}
  23
  24static inline long PTR_ERR(const void *ptr)
  25{
  26        return (long) ptr;
  27}
  28
  29static inline long IS_ERR(const void *ptr)
  30{
  31        return (unsigned long)ptr > (unsigned long)-1000L;
  32}
  33
  34static int add_file_to_cache(char *path)
  35{
  36        int size, namelen, option, status;
  37        struct cache_entry *ce;
  38        struct stat st;
  39        int fd;
  40        char *target;
  41
  42        status = lstat(path, &st);
  43        if (status < 0 || S_ISDIR(st.st_mode)) {
  44                /* When we used to have "path" and now we want to add
  45                 * "path/file", we need a way to remove "path" before
  46                 * being able to add "path/file".  However,
  47                 * "git-update-cache --remove path" would not work.
  48                 * --force-remove can be used but this is more user
  49                 * friendly, especially since we can do the opposite
  50                 * case just fine without --force-remove.
  51                 */
  52                if (status == 0 || (errno == ENOENT || errno == ENOTDIR)) {
  53                        if (allow_remove)
  54                                return remove_file_from_cache(path);
  55                }
  56                return error("open(\"%s\"): %s", path, strerror(errno));
  57        }
  58        namelen = strlen(path);
  59        size = cache_entry_size(namelen);
  60        ce = xmalloc(size);
  61        memset(ce, 0, size);
  62        memcpy(ce->name, path, namelen);
  63        fill_stat_cache_info(ce, &st);
  64        ce->ce_mode = create_ce_mode(st.st_mode);
  65        ce->ce_flags = htons(namelen);
  66        switch (st.st_mode & S_IFMT) {
  67        case S_IFREG:
  68                fd = open(path, O_RDONLY);
  69                if (fd < 0)
  70                        return -1;
  71                if (index_fd(ce->sha1, fd, &st, !info_only, NULL) < 0)
  72                        return -1;
  73                break;
  74        case S_IFLNK:
  75                target = xmalloc(st.st_size+1);
  76                if (readlink(path, target, st.st_size+1) != st.st_size) {
  77                        free(target);
  78                        return -1;
  79                }
  80                if (info_only) {
  81                        unsigned char hdr[50];
  82                        int hdrlen;
  83                        write_sha1_file_prepare(target, st.st_size, "blob",
  84                                                ce->sha1, hdr, &hdrlen);
  85                } else if (write_sha1_file(target, st.st_size, "blob", ce->sha1))
  86                        return -1;
  87                free(target);
  88                break;
  89        default:
  90                return -1;
  91        }
  92        option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
  93        option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
  94        return add_cache_entry(ce, option);
  95}
  96
  97static int match_data(int fd, void *buffer, unsigned long size)
  98{
  99        while (size) {
 100                char compare[1024];
 101                int ret = read(fd, compare, sizeof(compare));
 102
 103                if (ret <= 0 || ret > size || memcmp(buffer, compare, ret))
 104                        return -1;
 105                size -= ret;
 106                buffer += ret;
 107        }
 108        return 0;
 109}
 110
 111static int compare_data(struct cache_entry *ce, unsigned long expected_size)
 112{
 113        int match = -1;
 114        int fd = open(ce->name, O_RDONLY);
 115
 116        if (fd >= 0) {
 117                void *buffer;
 118                unsigned long size;
 119                char type[20];
 120
 121                buffer = read_sha1_file(ce->sha1, type, &size);
 122                if (buffer) {
 123                        if (size == expected_size && !strcmp(type, "blob"))
 124                                match = match_data(fd, buffer, size);
 125                        free(buffer);
 126                }
 127                close(fd);
 128        }
 129        return match;
 130}
 131
 132static int compare_link(struct cache_entry *ce, unsigned long expected_size)
 133{
 134        int match = -1;
 135        char *target;
 136        void *buffer;
 137        unsigned long size;
 138        char type[10];
 139        int len;
 140
 141        target = xmalloc(expected_size);
 142        len = readlink(ce->name, target, expected_size);
 143        if (len != expected_size) {
 144                free(target);
 145                return -1;
 146        }
 147        buffer = read_sha1_file(ce->sha1, type, &size);
 148        if (!buffer) {
 149                free(target);
 150                return -1;
 151        }
 152        if (size == expected_size)
 153                match = memcmp(buffer, target, size);
 154        free(buffer);
 155        free(target);
 156        return match;
 157}
 158
 159/*
 160 * "refresh" does not calculate a new sha1 file or bring the
 161 * cache up-to-date for mode/content changes. But what it
 162 * _does_ do is to "re-match" the stat information of a file
 163 * with the cache, so that you can refresh the cache for a
 164 * file that hasn't been changed but where the stat entry is
 165 * out of date.
 166 *
 167 * For example, you'd want to do this after doing a "git-read-tree",
 168 * to link up the stat cache details with the proper files.
 169 */
 170static struct cache_entry *refresh_entry(struct cache_entry *ce)
 171{
 172        struct stat st;
 173        struct cache_entry *updated;
 174        int changed, size;
 175
 176        if (lstat(ce->name, &st) < 0)
 177                return ERR_PTR(-errno);
 178
 179        changed = ce_match_stat(ce, &st);
 180        if (!changed)
 181                return ce;
 182
 183        /*
 184         * If the mode or type has changed, there's no point in trying
 185         * to refresh the entry - it's not going to match
 186         */
 187        if (changed & (MODE_CHANGED | TYPE_CHANGED))
 188                return ERR_PTR(-EINVAL);
 189
 190        switch (st.st_mode & S_IFMT) {
 191        case S_IFREG:
 192                if (compare_data(ce, st.st_size))
 193                        return ERR_PTR(-EINVAL);
 194                break;
 195        case S_IFLNK:
 196                if (compare_link(ce, st.st_size))
 197                        return ERR_PTR(-EINVAL);
 198                break;
 199        default:
 200                return ERR_PTR(-EINVAL);
 201        }
 202
 203        size = ce_size(ce);
 204        updated = xmalloc(size);
 205        memcpy(updated, ce, size);
 206        fill_stat_cache_info(updated, &st);
 207        return updated;
 208}
 209
 210static int refresh_cache(void)
 211{
 212        int i;
 213        int has_errors = 0;
 214
 215        for (i = 0; i < active_nr; i++) {
 216                struct cache_entry *ce, *new;
 217                ce = active_cache[i];
 218                if (ce_stage(ce)) {
 219                        printf("%s: needs merge\n", ce->name);
 220                        has_errors = 1;
 221                        while ((i < active_nr) &&
 222                               ! strcmp(active_cache[i]->name, ce->name))
 223                                i++;
 224                        i--;
 225                        continue;
 226                }
 227
 228                new = refresh_entry(ce);
 229                if (IS_ERR(new)) {
 230                        if (not_new && PTR_ERR(new) == -ENOENT)
 231                                continue;
 232                        if (quiet)
 233                                continue;
 234                        printf("%s: needs update\n", ce->name);
 235                        has_errors = 1;
 236                        continue;
 237                }
 238                active_cache_changed = 1;
 239                /* You can NOT just free active_cache[i] here, since it
 240                 * might not be necessarily malloc()ed but can also come
 241                 * from mmap(). */
 242                active_cache[i] = new;
 243        }
 244        return has_errors;
 245}
 246
 247/*
 248 * We fundamentally don't like some paths: we don't want
 249 * dot or dot-dot anywhere, and for obvious reasons don't
 250 * want to recurse into ".git" either.
 251 *
 252 * Also, we don't want double slashes or slashes at the
 253 * end that can make pathnames ambiguous.
 254 */
 255static int verify_dotfile(const char *rest)
 256{
 257        /*
 258         * The first character was '.', but that
 259         * has already been discarded, we now test
 260         * the rest.
 261         */
 262        switch (*rest) {
 263        /* "." is not allowed */
 264        case '\0': case '/':
 265                return 0;
 266
 267        /*
 268         * ".git" followed by  NUL or slash is bad. This
 269         * shares the path end test with the ".." case.
 270         */
 271        case 'g':
 272                if (rest[1] != 'i')
 273                        break;
 274                if (rest[2] != 't')
 275                        break;
 276                rest += 2;
 277        /* fallthrough */
 278        case '.':
 279                if (rest[1] == '\0' || rest[1] == '/')
 280                        return 0;
 281        }
 282        return 1;
 283}
 284
 285static int verify_path(char *path)
 286{
 287        char c;
 288
 289        goto inside;
 290        for (;;) {
 291                if (!c)
 292                        return 1;
 293                if (c == '/') {
 294inside:
 295                        c = *path++;
 296                        switch (c) {
 297                        default:
 298                                continue;
 299                        case '/': case '\0':
 300                                break;
 301                        case '.':
 302                                if (verify_dotfile(path))
 303                                        continue;
 304                        }
 305                        return 0;
 306                }
 307                c = *path++;
 308        }
 309}
 310
 311static int add_cacheinfo(char *arg1, char *arg2, char *arg3)
 312{
 313        int size, len, option;
 314        unsigned int mode;
 315        unsigned char sha1[20];
 316        struct cache_entry *ce;
 317
 318        if (sscanf(arg1, "%o", &mode) != 1)
 319                return -1;
 320        if (get_sha1_hex(arg2, sha1))
 321                return -1;
 322        if (!verify_path(arg3))
 323                return -1;
 324
 325        len = strlen(arg3);
 326        size = cache_entry_size(len);
 327        ce = xmalloc(size);
 328        memset(ce, 0, size);
 329
 330        memcpy(ce->sha1, sha1, 20);
 331        memcpy(ce->name, arg3, len);
 332        ce->ce_flags = htons(len);
 333        ce->ce_mode = create_ce_mode(mode);
 334        option = allow_add ? ADD_CACHE_OK_TO_ADD : 0;
 335        option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0;
 336        return add_cache_entry(ce, option);
 337}
 338
 339static struct cache_file cache_file;
 340
 341int main(int argc, char **argv)
 342{
 343        int i, newfd, entries, has_errors = 0;
 344        int allow_options = 1;
 345
 346        newfd = hold_index_file_for_update(&cache_file, get_index_file());
 347        if (newfd < 0)
 348                die("unable to create new cachefile");
 349
 350        entries = read_cache();
 351        if (entries < 0)
 352                die("cache corrupted");
 353
 354        for (i = 1 ; i < argc; i++) {
 355                char *path = argv[i];
 356
 357                if (allow_options && *path == '-') {
 358                        if (!strcmp(path, "--")) {
 359                                allow_options = 0;
 360                                continue;
 361                        }
 362                        if (!strcmp(path, "-q")) {
 363                                quiet = 1;
 364                                continue;
 365                        }
 366                        if (!strcmp(path, "--add")) {
 367                                allow_add = 1;
 368                                continue;
 369                        }
 370                        if (!strcmp(path, "--replace")) {
 371                                allow_replace = 1;
 372                                continue;
 373                        }
 374                        if (!strcmp(path, "--remove")) {
 375                                allow_remove = 1;
 376                                continue;
 377                        }
 378                        if (!strcmp(path, "--refresh")) {
 379                                has_errors |= refresh_cache();
 380                                continue;
 381                        }
 382                        if (!strcmp(path, "--cacheinfo")) {
 383                                if (i+3 >= argc)
 384                                        die("git-update-cache: --cacheinfo <mode> <sha1> <path>");
 385                                if (add_cacheinfo(argv[i+1], argv[i+2], argv[i+3]))
 386                                        die("git-update-cache: --cacheinfo cannot add %s", argv[i+3]);
 387                                i += 3;
 388                                continue;
 389                        }
 390                        if (!strcmp(path, "--info-only")) {
 391                                info_only = 1;
 392                                continue;
 393                        }
 394                        if (!strcmp(path, "--force-remove")) {
 395                                force_remove = 1;
 396                                continue;
 397                        }
 398
 399                        if (!strcmp(path, "--ignore-missing")) {
 400                                not_new = 1;
 401                                continue;
 402                        }
 403                        die("unknown option %s", path);
 404                }
 405                if (!verify_path(path)) {
 406                        fprintf(stderr, "Ignoring path %s\n", argv[i]);
 407                        continue;
 408                }
 409                if (force_remove) {
 410                        if (remove_file_from_cache(path))
 411                                die("git-update-cache: --force-remove cannot remove %s", path);
 412                        continue;
 413                }
 414                if (add_file_to_cache(path))
 415                        die("Unable to add %s to database", path);
 416        }
 417        if (write_cache(newfd, active_cache, active_nr) ||
 418            commit_index_file(&cache_file))
 419                die("Unable to write new cachefile");
 420
 421        return has_errors ? 1 : 0;
 422}