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