builtin-write-tree.con commit git-svn: allow 'init' to act as multi-init (dadc6d2)
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "builtin.h"
   7#include "cache.h"
   8#include "tree.h"
   9#include "cache-tree.h"
  10
  11static const char write_tree_usage[] =
  12"git-write-tree [--missing-ok] [--prefix=<prefix>/]";
  13
  14int write_tree(unsigned char *sha1, int missing_ok, const char *prefix)
  15{
  16        int entries, was_valid, newfd;
  17
  18        /* We can't free this memory, it becomes part of a linked list parsed atexit() */
  19        struct lock_file *lock_file = xcalloc(1, sizeof(struct lock_file));
  20
  21        newfd = hold_lock_file_for_update(lock_file, get_index_file(), 0);
  22
  23        entries = read_cache();
  24        if (entries < 0)
  25                die("git-write-tree: error reading cache");
  26
  27        if (!active_cache_tree)
  28                active_cache_tree = cache_tree();
  29
  30        was_valid = cache_tree_fully_valid(active_cache_tree);
  31
  32        if (!was_valid) {
  33                if (cache_tree_update(active_cache_tree,
  34                                      active_cache, active_nr,
  35                                      missing_ok, 0) < 0)
  36                        die("git-write-tree: error building trees");
  37                if (0 <= newfd) {
  38                        if (!write_cache(newfd, active_cache, active_nr)
  39                                        && !close(newfd))
  40                                commit_lock_file(lock_file);
  41                }
  42                /* Not being able to write is fine -- we are only interested
  43                 * in updating the cache-tree part, and if the next caller
  44                 * ends up using the old index with unupdated cache-tree part
  45                 * it misses the work we did here, but that is just a
  46                 * performance penalty and not a big deal.
  47                 */
  48        }
  49
  50        if (prefix) {
  51                struct cache_tree *subtree =
  52                        cache_tree_find(active_cache_tree, prefix);
  53                hashcpy(sha1, subtree->sha1);
  54        }
  55        else
  56                hashcpy(sha1, active_cache_tree->sha1);
  57
  58        rollback_lock_file(lock_file);
  59
  60        return 0;
  61}
  62
  63int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
  64{
  65        int missing_ok = 0, ret;
  66        const char *prefix = NULL;
  67        unsigned char sha1[20];
  68
  69        while (1 < argc) {
  70                const char *arg = argv[1];
  71                if (!strcmp(arg, "--missing-ok"))
  72                        missing_ok = 1;
  73                else if (!prefixcmp(arg, "--prefix="))
  74                        prefix = arg + 9;
  75                else
  76                        usage(write_tree_usage);
  77                argc--; argv++;
  78        }
  79
  80        if (argc > 2)
  81                die("too many options");
  82
  83        ret = write_tree(sha1, missing_ok, prefix);
  84        printf("%s\n", sha1_to_hex(sha1));
  85
  86        return ret;
  87}