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