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