builtin-write-tree.con commit compat: Add simplified merge sort implementation from glibc (43fe901)
   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                            !commit_lock_file(lock_file))
  40                                newfd = -1;
  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                if (!subtree)
  54                        die("git-write-tree: prefix %s not found", prefix);
  55                hashcpy(sha1, subtree->sha1);
  56        }
  57        else
  58                hashcpy(sha1, active_cache_tree->sha1);
  59
  60        if (0 <= newfd)
  61                rollback_lock_file(lock_file);
  62
  63        return 0;
  64}
  65
  66int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
  67{
  68        int missing_ok = 0, ret;
  69        const char *prefix = NULL;
  70        unsigned char sha1[20];
  71
  72        git_config(git_default_config);
  73        while (1 < argc) {
  74                const char *arg = argv[1];
  75                if (!strcmp(arg, "--missing-ok"))
  76                        missing_ok = 1;
  77                else if (!prefixcmp(arg, "--prefix="))
  78                        prefix = arg + 9;
  79                else
  80                        usage(write_tree_usage);
  81                argc--; argv++;
  82        }
  83
  84        if (argc > 2)
  85                die("too many options");
  86
  87        ret = write_tree(sha1, missing_ok, prefix);
  88        printf("%s\n", sha1_to_hex(sha1));
  89
  90        return ret;
  91}