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 intunpack_tree(unsigned char*sha1) 11{ 12void*buffer; 13unsigned long size; 14int ret; 15 16 buffer =read_object_with_reference(sha1,"tree", &size, NULL); 17if(!buffer) 18return-1; 19 ret =read_tree(buffer, size, stage); 20free(buffer); 21return ret; 22} 23 24static char*lockfile_name; 25 26static voidremove_lock_file(void) 27{ 28if(lockfile_name) 29unlink(lockfile_name); 30} 31 32static intpath_matches(struct cache_entry *a,struct cache_entry *b) 33{ 34int len =ce_namelen(a); 35returnce_namelen(b) == len && 36!memcmp(a->name, b->name, len); 37} 38 39static intsame(struct cache_entry *a,struct cache_entry *b) 40{ 41return 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, 55struct cache_entry *b, 56struct cache_entry *c) 57{ 58int len =ce_namelen(a); 59 60/* 61 * Are they all the same filename? We won't do 62 * any name merging 63 */ 64if(ce_namelen(b) != len || 65ce_namelen(c) != len || 66memcmp(a->name, b->name, len) || 67memcmp(a->name, c->name, len)) 68return 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 */ 87if(same(b,c)) 88return c; 89if(same(a,b)) 90return c; 91if(same(a,c)) 92return b; 93return 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 voidverify_uptodate(struct cache_entry *ce) 101{ 102struct stat st; 103 104if(!lstat(ce->name, &st)) { 105unsigned changed =ce_match_stat(ce, &st); 106if(!changed) 107return; 108 errno =0; 109} 110if(errno == ENOENT) 111return; 112die("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 voidverify_cleared(struct cache_entry *ce) 122{ 123if(ce) 124die("Entry '%s' would be overwritten by merge. Cannot merge.", ce->name); 125} 126 127static intold_match(struct cache_entry *old,struct cache_entry *a) 128{ 129return old &&path_matches(old, a) &&same(old, a); 130} 131 132static voidtrivially_merge_cache(struct cache_entry **src,int nr) 133{ 134struct cache_entry **dst = src; 135struct cache_entry *old = NULL; 136 137while(nr) { 138struct cache_entry *ce, *result; 139 140 ce = src[0]; 141 142/* We throw away original cache entries except for the stat information */ 143if(!ce_stage(ce)) { 144verify_cleared(old); 145 old = ce; 146 src++; 147 nr--; 148 active_nr--; 149continue; 150} 151if(nr >2&& (result =merge_entries(ce, src[1], src[2])) != NULL) { 152/* 153 * See if we can re-use the old CE directly? 154 * That way we get the uptodate stat info. 155 */ 156if(old_match(old, result)) { 157*result = *old; 158 old = NULL; 159} 160 ce = result; 161 ce->ce_flags &= ~htons(CE_STAGEMASK); 162 src +=2; 163 nr -=2; 164 active_nr -=2; 165} 166 167/* 168 * If we had an old entry that we now effectively 169 * overwrite, make sure it wasn't dirty. 170 */ 171if(old_match(old, ce)) { 172verify_uptodate(old); 173 old = NULL; 174} 175*dst++ = ce; 176 src++; 177 nr--; 178} 179verify_cleared(old); 180} 181 182static voidmerge_stat_info(struct cache_entry **src,int nr) 183{ 184static struct cache_entry null_entry; 185struct cache_entry **dst = src; 186struct cache_entry *old = &null_entry; 187 188while(nr) { 189struct cache_entry *ce; 190 191 ce = src[0]; 192 193/* We throw away original cache entries except for the stat information */ 194if(!ce_stage(ce)) { 195 old = ce; 196 src++; 197 nr--; 198 active_nr--; 199continue; 200} 201if(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 212intmain(int argc,char**argv) 213{ 214int i, newfd, merge; 215unsigned char sha1[20]; 216static char lockfile[MAXPATHLEN+1]; 217const char*indexfile =get_index_file(); 218 219snprintf(lockfile,sizeof(lockfile),"%s.lock", indexfile); 220 221 newfd =open(lockfile, O_RDWR | O_CREAT | O_EXCL,0600); 222if(newfd <0) 223die("unable to create new cachefile"); 224atexit(remove_lock_file); 225 lockfile_name = lockfile; 226 227 merge =0; 228for(i =1; i < argc; i++) { 229const char*arg = argv[i]; 230 231/* "-m" stands for "merge", meaning we start in stage 1 */ 232if(!strcmp(arg,"-m")) { 233int i; 234if(stage) 235die("-m needs to come first"); 236read_cache(); 237for(i =0; i < active_nr; i++) { 238if(ce_stage(active_cache[i])) 239die("you need to resolve your current index first"); 240} 241 stage =1; 242 merge =1; 243continue; 244} 245if(get_sha1(arg, sha1) <0) 246usage(read_tree_usage); 247if(stage >3) 248usage(read_tree_usage); 249if(unpack_tree(sha1) <0) 250die("failed to unpack tree object%s", arg); 251 stage++; 252} 253if(merge) { 254switch(stage) { 255case4:/* Three-way merge */ 256trivially_merge_cache(active_cache, active_nr); 257break; 258case2:/* Just read a tree, merge with old cache contents */ 259merge_stat_info(active_cache, active_nr); 260break; 261default: 262die("just how do you expect me to merge%dtrees?", stage-1); 263} 264} 265if(write_cache(newfd, active_cache, active_nr) ||rename(lockfile, indexfile)) 266die("unable to write new index file"); 267 lockfile_name = NULL; 268return0; 269}