read-tree.con commit Make fiel checkout function available to the git library (12dccc1)
   1/*
   2 * GIT - The information manager from hell
   3 *
   4 * Copyright (C) Linus Torvalds, 2005
   5 */
   6#include "cache.h"
   7
   8static int stage = 0;
   9
  10static int unpack_tree(unsigned char *sha1)
  11{
  12        void *buffer;
  13        unsigned long size;
  14        int ret;
  15
  16        buffer = read_object_with_reference(sha1, "tree", &size, NULL);
  17        if (!buffer)
  18                return -1;
  19        ret = read_tree(buffer, size, stage);
  20        free(buffer);
  21        return ret;
  22}
  23
  24static char *lockfile_name;
  25
  26static void remove_lock_file(void)
  27{
  28        if (lockfile_name)
  29                unlink(lockfile_name);
  30}
  31
  32static int path_matches(struct cache_entry *a, struct cache_entry *b)
  33{
  34        int len = ce_namelen(a);
  35        return ce_namelen(b) == len &&
  36                !memcmp(a->name, b->name, len);
  37}
  38
  39static int same(struct cache_entry *a, struct cache_entry *b)
  40{
  41        return a->ce_mode == b->ce_mode && 
  42                !memcmp(a->sha1, b->sha1, 20);
  43}
  44
  45
  46/*
  47 * This removes all trivial merges that don't change the tree
  48 * and collapses them to state 0.
  49 *
  50 * _Any_ other merge is left to user policy.  That includes "both
  51 * created the same file", and "both removed the same file" - which are
  52 * trivial, but the user might still want to _note_ it. 
  53 */
  54static struct cache_entry *merge_entries(struct cache_entry *a,
  55                                         struct cache_entry *b,
  56                                         struct cache_entry *c)
  57{
  58        int len = ce_namelen(a);
  59
  60        /*
  61         * Are they all the same filename? We won't do
  62         * any name merging
  63         */
  64        if (ce_namelen(b) != len ||
  65            ce_namelen(c) != len ||
  66            memcmp(a->name, b->name, len) ||
  67            memcmp(a->name, c->name, len))
  68                return NULL;
  69
  70        /*
  71         * Ok, all three entries describe the same
  72         * filename, but maybe the contents or file
  73         * mode have changed?
  74         *
  75         * The trivial cases end up being the ones where two
  76         * out of three files are the same:
  77         *  - both destinations the same, trivially take either
  78         *  - one of the destination versions hasn't changed,
  79         *    take the other.
  80         *
  81         * The "all entries exactly the same" case falls out as
  82         * a special case of any of the "two same" cases.
  83         *
  84         * Here "a" is "original", and "b" and "c" are the two
  85         * trees we are merging.
  86         */
  87        if (same(b,c))
  88                return c;
  89        if (same(a,b))
  90                return c;
  91        if (same(a,c))
  92                return b;
  93        return NULL;
  94}
  95
  96/*
  97 * When a CE gets turned into an unmerged entry, we
  98 * want it to be up-to-date
  99 */
 100static void verify_uptodate(struct cache_entry *ce)
 101{
 102        struct stat st;
 103
 104        if (!lstat(ce->name, &st)) {
 105                unsigned changed = ce_match_stat(ce, &st);
 106                if (!changed)
 107                        return;
 108                errno = 0;
 109        }
 110        if (errno == ENOENT)
 111                return;
 112        die("Entry '%s' not uptodate. Cannot merge.", ce->name);
 113}
 114
 115/*
 116 * If the old tree contained a CE that isn't even in the
 117 * result, that's always a problem, regardless of whether
 118 * it's up-to-date or not (ie it can be a file that we
 119 * have updated but not committed yet).
 120 */
 121static void reject_merge(struct cache_entry *ce)
 122{
 123        die("Entry '%s' would be overwritten by merge. Cannot merge.", ce->name);
 124}
 125
 126#define CHECK_OLD(ce) if (old && same(old, ce)) { verify_uptodate(old); old = NULL; }
 127
 128static void trivially_merge_cache(struct cache_entry **src, int nr)
 129{
 130        struct cache_entry **dst = src;
 131        struct cache_entry *old = NULL;
 132
 133        while (nr) {
 134                struct cache_entry *ce, *result;
 135
 136                ce = src[0];
 137
 138                /* We throw away original cache entries except for the stat information */
 139                if (!ce_stage(ce)) {
 140                        if (old)
 141                                reject_merge(old);
 142                        old = ce;
 143                        src++;
 144                        nr--;
 145                        active_nr--;
 146                        continue;
 147                }
 148                if (old && !path_matches(old, ce))
 149                        reject_merge(old);
 150                if (nr > 2 && (result = merge_entries(ce, src[1], src[2])) != NULL) {
 151                        /*
 152                         * See if we can re-use the old CE directly?
 153                         * That way we get the uptodate stat info.
 154                         */
 155                        if (old && same(old, result)) {
 156                                *result = *old;
 157                                old = NULL;
 158                        }
 159                        CHECK_OLD(ce);
 160                        CHECK_OLD(src[1]);
 161                        CHECK_OLD(src[2]);
 162                        ce = result;
 163                        ce->ce_flags &= ~htons(CE_STAGEMASK);
 164                        src += 2;
 165                        nr -= 2;
 166                        active_nr -= 2;
 167                }
 168
 169                /*
 170                 * If we had an old entry that we now effectively
 171                 * overwrite, make sure it wasn't dirty.
 172                 */
 173                CHECK_OLD(ce);
 174                *dst++ = ce;
 175                src++;
 176                nr--;
 177        }
 178        if (old)
 179                reject_merge(old);
 180}
 181
 182static void merge_stat_info(struct cache_entry **src, int nr)
 183{
 184        static struct cache_entry null_entry;
 185        struct cache_entry **dst = src;
 186        struct cache_entry *old = &null_entry;
 187
 188        while (nr) {
 189                struct cache_entry *ce;
 190
 191                ce = src[0];
 192
 193                /* We throw away original cache entries except for the stat information */
 194                if (!ce_stage(ce)) {
 195                        old = ce;
 196                        src++;
 197                        nr--;
 198                        active_nr--;
 199                        continue;
 200                }
 201                if (path_matches(ce, old) && same(ce, old))
 202                        *ce = *old;
 203                ce->ce_flags &= ~htons(CE_STAGEMASK);
 204                *dst++ = ce;
 205                src++;
 206                nr--;
 207        }
 208}
 209
 210static char *read_tree_usage = "git-read-tree (<sha> | -m <sha1> [<sha2> <sha3>])";
 211
 212int main(int argc, char **argv)
 213{
 214        int i, newfd, merge;
 215        unsigned char sha1[20];
 216        static char lockfile[MAXPATHLEN+1];
 217        const char *indexfile = get_index_file();
 218
 219        snprintf(lockfile, sizeof(lockfile), "%s.lock", indexfile);
 220
 221        newfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600);
 222        if (newfd < 0)
 223                die("unable to create new cachefile");
 224        atexit(remove_lock_file);
 225        lockfile_name = lockfile;
 226
 227        merge = 0;
 228        for (i = 1; i < argc; i++) {
 229                const char *arg = argv[i];
 230
 231                /* "-m" stands for "merge", meaning we start in stage 1 */
 232                if (!strcmp(arg, "-m")) {
 233                        int i;
 234                        if (stage)
 235                                die("-m needs to come first");
 236                        read_cache();
 237                        for (i = 0; i < active_nr; i++) {
 238                                if (ce_stage(active_cache[i]))
 239                                        die("you need to resolve your current index first");
 240                        }
 241                        stage = 1;
 242                        merge = 1;
 243                        continue;
 244                }
 245                if (get_sha1(arg, sha1) < 0)
 246                        usage(read_tree_usage);
 247                if (stage > 3)
 248                        usage(read_tree_usage);
 249                if (unpack_tree(sha1) < 0)
 250                        die("failed to unpack tree object %s", arg);
 251                stage++;
 252        }
 253        if (merge) {
 254                switch (stage) {
 255                case 4: /* Three-way merge */
 256                        trivially_merge_cache(active_cache, active_nr);
 257                        break;
 258                case 2: /* Just read a tree, merge with old cache contents */
 259                        merge_stat_info(active_cache, active_nr);
 260                        break;
 261                default:
 262                        die("just how do you expect me to merge %d trees?", stage-1);
 263                }
 264        }
 265        if (write_cache(newfd, active_cache, active_nr) || rename(lockfile, indexfile))
 266                die("unable to write new index file");
 267        lockfile_name = NULL;
 268        return 0;
 269}