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