builtin-write-tree.con commit Make git-archimport log entries more consistent (608403d)
   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_locked_index(lock_file, 1);
  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                                newfd = -1;
  42                        }
  43                }
  44                /* Not being able to write is fine -- we are only interested
  45                 * in updating the cache-tree part, and if the next caller
  46                 * ends up using the old index with unupdated cache-tree part
  47                 * it misses the work we did here, but that is just a
  48                 * performance penalty and not a big deal.
  49                 */
  50        }
  51
  52        if (prefix) {
  53                struct cache_tree *subtree =
  54                        cache_tree_find(active_cache_tree, prefix);
  55                if (!subtree)
  56                        die("git-write-tree: prefix %s not found", prefix);
  57                hashcpy(sha1, subtree->sha1);
  58        }
  59        else
  60                hashcpy(sha1, active_cache_tree->sha1);
  61
  62        if (0 <= newfd)
  63                close(newfd);
  64        rollback_lock_file(lock_file);
  65
  66        return 0;
  67}
  68
  69int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
  70{
  71        int missing_ok = 0, ret;
  72        const char *prefix = NULL;
  73        unsigned char sha1[20];
  74
  75        git_config(git_default_config);
  76        while (1 < argc) {
  77                const char *arg = argv[1];
  78                if (!strcmp(arg, "--missing-ok"))
  79                        missing_ok = 1;
  80                else if (!prefixcmp(arg, "--prefix="))
  81                        prefix = arg + 9;
  82                else
  83                        usage(write_tree_usage);
  84                argc--; argv++;
  85        }
  86
  87        if (argc > 2)
  88                die("too many options");
  89
  90        ret = write_tree(sha1, missing_ok, prefix);
  91        printf("%s\n", sha1_to_hex(sha1));
  92
  93        return ret;
  94}