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 15 buffer = read_object_with_reference(sha1, "tree", &size, 0); 16 if (!buffer) 17 return -1; 18 return read_tree(buffer, size, stage); 19} 20 21static char *lockfile_name; 22 23static void remove_lock_file(void) 24{ 25 if (lockfile_name) 26 unlink(lockfile_name); 27} 28 29static int path_matches(struct cache_entry *a, struct cache_entry *b) 30{ 31 int len = ce_namelen(a); 32 return ce_namelen(b) == len && 33 !memcmp(a->name, b->name, len); 34} 35 36static int same(struct cache_entry *a, struct cache_entry *b) 37{ 38 return a->ce_mode == b->ce_mode && 39 !memcmp(a->sha1, b->sha1, 20); 40} 41 42 43/* 44 * This removes all trivial merges that don't change the tree 45 * and collapses them to state 0. 46 * 47 * _Any_ other merge is left to user policy. That includes "both 48 * created the same file", and "both removed the same file" - which are 49 * trivial, but the user might still want to _note_ it. 50 */ 51static struct cache_entry *merge_entries(struct cache_entry *a, 52 struct cache_entry *b, 53 struct cache_entry *c) 54{ 55 int len = ce_namelen(a); 56 57 /* 58 * Are they all the same filename? We won't do 59 * any name merging 60 */ 61 if (ce_namelen(b) != len || 62 ce_namelen(c) != len || 63 memcmp(a->name, b->name, len) || 64 memcmp(a->name, c->name, len)) 65 return NULL; 66 67 /* 68 * Ok, all three entries describe the same 69 * filename, but maybe the contents or file 70 * mode have changed? 71 * 72 * The trivial cases end up being the ones where two 73 * out of three files are the same: 74 * - both destinations the same, trivially take either 75 * - one of the destination versions hasn't changed, 76 * take the other. 77 * 78 * The "all entries exactly the same" case falls out as 79 * a special case of any of the "two same" cases. 80 * 81 * Here "a" is "original", and "b" and "c" are the two 82 * trees we are merging. 83 */ 84 if (same(b,c)) 85 return c; 86 if (same(a,b)) 87 return c; 88 if (same(a,c)) 89 return b; 90 return NULL; 91} 92 93static void trivially_merge_cache(struct cache_entry **src, int nr) 94{ 95 static struct cache_entry null_entry; 96 struct cache_entry **dst = src; 97 struct cache_entry *old = &null_entry; 98 99 while (nr) { 100 struct cache_entry *ce, *result; 101 102 ce = src[0]; 103 104 /* We throw away original cache entries except for the stat information */ 105 if (!ce_stage(ce)) { 106 old = ce; 107 src++; 108 nr--; 109 active_nr--; 110 continue; 111 } 112 if (nr > 2 && (result = merge_entries(ce, src[1], src[2])) != NULL) { 113 /* 114 * See if we can re-use the old CE directly? 115 * That way we get the uptodate stat info. 116 */ 117 if (path_matches(result, old) && same(result, old)) 118 *result = *old; 119 ce = result; 120 ce->ce_flags &= ~htons(CE_STAGEMASK); 121 src += 2; 122 nr -= 2; 123 active_nr -= 2; 124 } 125 *dst++ = ce; 126 src++; 127 nr--; 128 } 129} 130 131static void merge_stat_info(struct cache_entry **src, int nr) 132{ 133 static struct cache_entry null_entry; 134 struct cache_entry **dst = src; 135 struct cache_entry *old = &null_entry; 136 137 while (nr) { 138 struct cache_entry *ce; 139 140 ce = src[0]; 141 142 /* We throw away original cache entries except for the stat information */ 143 if (!ce_stage(ce)) { 144 old = ce; 145 src++; 146 nr--; 147 active_nr--; 148 continue; 149 } 150 if (path_matches(ce, old) && same(ce, old)) 151 *ce = *old; 152 ce->ce_flags &= ~htons(CE_STAGEMASK); 153 *dst++ = ce; 154 src++; 155 nr--; 156 } 157} 158 159static char *read_tree_usage = "read-tree (<sha> | -m <sha1> [<sha2> <sha3>])"; 160 161int main(int argc, char **argv) 162{ 163 int i, newfd, merge; 164 unsigned char sha1[20]; 165 static char lockfile[MAXPATHLEN+1]; 166 const char *indexfile = get_index_file(); 167 168 snprintf(lockfile, sizeof(lockfile), "%s.lock", indexfile); 169 170 newfd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0600); 171 if (newfd < 0) 172 die("unable to create new cachefile"); 173 atexit(remove_lock_file); 174 lockfile_name = lockfile; 175 176 merge = 0; 177 for (i = 1; i < argc; i++) { 178 const char *arg = argv[i]; 179 180 /* "-m" stands for "merge", meaning we start in stage 1 */ 181 if (!strcmp(arg, "-m")) { 182 int i; 183 if (stage) 184 die("-m needs to come first"); 185 read_cache(); 186 for (i = 0; i < active_nr; i++) { 187 if (ce_stage(active_cache[i])) 188 die("you need to resolve your current index first"); 189 } 190 stage = 1; 191 merge = 1; 192 continue; 193 } 194 if (get_sha1_hex(arg, sha1) < 0) 195 usage(read_tree_usage); 196 if (stage > 3) 197 usage(read_tree_usage); 198 if (unpack_tree(sha1) < 0) 199 die("failed to unpack tree object %s", arg); 200 stage++; 201 } 202 if (merge) { 203 switch (stage) { 204 case 4: /* Three-way merge */ 205 trivially_merge_cache(active_cache, active_nr); 206 break; 207 case 2: /* Just read a tree, merge with old cache contents */ 208 merge_stat_info(active_cache, active_nr); 209 break; 210 default: 211 die("just how do you expect me to merge %d trees?", stage-1); 212 } 213 } 214 if (write_cache(newfd, active_cache, active_nr) || rename(lockfile, indexfile)) 215 die("unable to write new index file"); 216 lockfile_name = NULL; 217 return 0; 218}