[PATCH] mkdelta enhancements (take 2)
[git.git] / apply.c
1 /*
2  * apply.c
3  *
4  * Copyright (C) Linus Torvalds, 2005
5  *
6  * This applies patches on top of some (arbitrary) version of the SCM.
7  *
8  * NOTE! It does all its work in the index file, and only cares about
9  * the files in the working directory if you tell it to "merge" the
10  * patch apply.
11  *
12  * Even when merging it always takes the source from the index, and
13  * uses the working tree as a "branch" for a 3-way merge.
14  */
15 #include <ctype.h>
16
17 #include "cache.h"
18
19 // We default to the merge behaviour, since that's what most people would
20 // expect.
21 //
22 //  --check turns on checking that the working tree matches the
23 //    files that are being modified, but doesn't apply the patch
24 //  --stat does just a diffstat, and doesn't actually apply
25 //  --show-files shows the directory changes
26 //
27 static int merge_patch = 1;
28 static int diffstat = 0;
29 static int check = 0;
30 static int apply = 1;
31 static int show_files = 0;
32 static const char apply_usage[] = "git-apply [--stat] [--check] [--show-files] <patch>";
33
34 /*
35  * For "diff-stat" like behaviour, we keep track of the biggest change
36  * we've seen, and the longest filename. That allows us to do simple
37  * scaling.
38  */
39 static int max_change, max_len;
40
41 /*
42  * Various "current state", notably line numbers and what
43  * file (and how) we're patching right now.. The "is_xxxx"
44  * things are flags, where -1 means "don't know yet".
45  */
46 static int linenr = 1;
47
48 struct fragment {
49         unsigned long oldpos, oldlines;
50         unsigned long newpos, newlines;
51         const char *patch;
52         int size;
53         struct fragment *next;
54 };
55
56 struct patch {
57         char *new_name, *old_name, *def_name;
58         unsigned int old_mode, new_mode;
59         int is_rename, is_copy, is_new, is_delete;
60         int lines_added, lines_deleted;
61         struct fragment *fragments;
62         struct patch *next;
63 };
64
65 #define CHUNKSIZE (8192)
66 #define SLOP (16)
67
68 static void *read_patch_file(int fd, unsigned long *sizep)
69 {
70         unsigned long size = 0, alloc = CHUNKSIZE;
71         void *buffer = xmalloc(alloc);
72
73         for (;;) {
74                 int nr = alloc - size;
75                 if (nr < 1024) {
76                         alloc += CHUNKSIZE;
77                         buffer = xrealloc(buffer, alloc);
78                         nr = alloc - size;
79                 }
80                 nr = read(fd, buffer + size, nr);
81                 if (!nr)
82                         break;
83                 if (nr < 0) {
84                         if (errno == EAGAIN)
85                                 continue;
86                         die("git-apply: read returned %s", strerror(errno));
87                 }
88                 size += nr;
89         }
90         *sizep = size;
91
92         /*
93          * Make sure that we have some slop in the buffer
94          * so that we can do speculative "memcmp" etc, and
95          * see to it that it is NUL-filled.
96          */
97         if (alloc < size + SLOP)
98                 buffer = xrealloc(buffer, size + SLOP);
99         memset(buffer + size, 0, SLOP);
100         return buffer;
101 }
102
103 static unsigned long linelen(char *buffer, unsigned long size)
104 {
105         unsigned long len = 0;
106         while (size--) {
107                 len++;
108                 if (*buffer++ == '\n')
109                         break;
110         }
111         return len;
112 }
113
114 static int is_dev_null(const char *str)
115 {
116         return !memcmp("/dev/null", str, 9) && isspace(str[9]);
117 }
118
119 #define TERM_EXIST      1
120 #define TERM_SPACE      2
121 #define TERM_TAB        4
122
123 static int name_terminate(const char *name, int namelen, int c, int terminate)
124 {
125         if (c == ' ' && !(terminate & TERM_SPACE))
126                 return 0;
127         if (c == '\t' && !(terminate & TERM_TAB))
128                 return 0;
129
130         /*
131          * Do we want an existing name? Return false and
132          * continue if it's not there.
133          */
134         if (terminate & TERM_EXIST)
135                 return cache_name_pos(name, namelen) >= 0;
136
137         return 1;
138 }
139
140 static char * find_name(const char *line, char *def, int p_value, int terminate)
141 {
142         int len;
143         const char *start = line;
144         char *name;
145
146         for (;;) {
147                 char c = *line;
148
149                 if (isspace(c)) {
150                         if (c == '\n')
151                                 break;
152                         if (name_terminate(start, line-start, c, terminate))
153                                 break;
154                 }
155                 line++;
156                 if (c == '/' && !--p_value)
157                         start = line;
158         }
159         if (!start)
160                 return def;
161         len = line - start;
162         if (!len)
163                 return def;
164
165         /*
166          * Generally we prefer the shorter name, especially
167          * if the other one is just a variation of that with
168          * something else tacked on to the end (ie "file.orig"
169          * or "file~").
170          */
171         if (def) {
172                 int deflen = strlen(def);
173                 if (deflen < len && !strncmp(start, def, deflen))
174                         return def;
175         }
176
177         name = xmalloc(len + 1);
178         memcpy(name, start, len);
179         name[len] = 0;
180         free(def);
181         return name;
182 }
183
184 /*
185  * Get the name etc info from the --/+++ lines of a traditional patch header
186  *
187  * NOTE! This hardcodes "-p1" behaviour in filename detection.
188  *
189  * FIXME! The end-of-filename heuristics are kind of screwy. For existing
190  * files, we can happily check the index for a match, but for creating a
191  * new file we should try to match whatever "patch" does. I have no idea.
192  */
193 static void parse_traditional_patch(const char *first, const char *second, struct patch *patch)
194 {
195         int p_value = 1;
196         char *name;
197
198         first += 4;     // skip "--- "
199         second += 4;    // skip "+++ "
200         if (is_dev_null(first)) {
201                 patch->is_new = 1;
202                 patch->is_delete = 0;
203                 name = find_name(second, NULL, p_value, TERM_SPACE | TERM_TAB);
204                 patch->new_name = name;
205         } else if (is_dev_null(second)) {
206                 patch->is_new = 0;
207                 patch->is_delete = 1;
208                 name = find_name(first, NULL, p_value, TERM_EXIST | TERM_SPACE | TERM_TAB);
209                 patch->old_name = name;
210         } else {
211                 name = find_name(first, NULL, p_value, TERM_EXIST | TERM_SPACE | TERM_TAB);
212                 name = find_name(second, name, p_value, TERM_EXIST | TERM_SPACE | TERM_TAB);
213                 patch->old_name = patch->new_name = name;
214         }
215         if (!name)
216                 die("unable to find filename in patch at line %d", linenr);
217 }
218
219 static int gitdiff_hdrend(const char *line, struct patch *patch)
220 {
221         return -1;
222 }
223
224 /*
225  * We're anal about diff header consistency, to make
226  * sure that we don't end up having strange ambiguous
227  * patches floating around.
228  *
229  * As a result, gitdiff_{old|new}name() will check
230  * their names against any previous information, just
231  * to make sure..
232  */
233 static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
234 {
235         int len;
236         const char *name;
237
238         if (!orig_name && !isnull)
239                 return find_name(line, NULL, 1, 0);
240
241         name = "/dev/null";
242         len = 9;
243         if (orig_name) {
244                 name = orig_name;
245                 len = strlen(name);
246                 if (isnull)
247                         die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
248         }
249
250         if (*name == '/')
251                 goto absolute_path;
252
253         for (;;) {
254                 char c = *line++;
255                 if (c == '\n')
256                         break;
257                 if (c != '/')
258                         continue;
259 absolute_path:
260                 if (memcmp(line, name, len) || line[len] != '\n')
261                         break;
262                 return orig_name;
263         }
264         die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
265         return NULL;
266 }
267
268 static int gitdiff_oldname(const char *line, struct patch *patch)
269 {
270         patch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, "old");
271         return 0;
272 }
273
274 static int gitdiff_newname(const char *line, struct patch *patch)
275 {
276         patch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, "new");
277         return 0;
278 }
279
280 static int gitdiff_oldmode(const char *line, struct patch *patch)
281 {
282         patch->old_mode = strtoul(line, NULL, 8);
283         return 0;
284 }
285
286 static int gitdiff_newmode(const char *line, struct patch *patch)
287 {
288         patch->new_mode = strtoul(line, NULL, 8);
289         return 0;
290 }
291
292 static int gitdiff_delete(const char *line, struct patch *patch)
293 {
294         patch->is_delete = 1;
295         patch->old_name = patch->def_name;
296         return gitdiff_oldmode(line, patch);
297 }
298
299 static int gitdiff_newfile(const char *line, struct patch *patch)
300 {
301         patch->is_new = 1;
302         patch->new_name = patch->def_name;
303         return gitdiff_newmode(line, patch);
304 }
305
306 static int gitdiff_copysrc(const char *line, struct patch *patch)
307 {
308         patch->is_copy = 1;
309         patch->old_name = find_name(line, NULL, 0, 0);
310         return 0;
311 }
312
313 static int gitdiff_copydst(const char *line, struct patch *patch)
314 {
315         patch->is_copy = 1;
316         patch->new_name = find_name(line, NULL, 0, 0);
317         return 0;
318 }
319
320 static int gitdiff_renamesrc(const char *line, struct patch *patch)
321 {
322         patch->is_rename = 1;
323         patch->old_name = find_name(line, NULL, 0, 0);
324         return 0;
325 }
326
327 static int gitdiff_renamedst(const char *line, struct patch *patch)
328 {
329         patch->is_rename = 1;
330         patch->new_name = find_name(line, NULL, 0, 0);
331         return 0;
332 }
333
334 static int gitdiff_similarity(const char *line, struct patch *patch)
335 {
336         return 0;
337 }
338
339 /*
340  * This is normal for a diff that doesn't change anything: we'll fall through
341  * into the next diff. Tell the parser to break out.
342  */
343 static int gitdiff_unrecognized(const char *line, struct patch *patch)
344 {
345         return -1;
346 }
347
348 static char *git_header_name(char *line)
349 {
350         int len;
351         char *name, *second;
352
353         /*
354          * Find the first '/'
355          */
356         name = line;
357         for (;;) {
358                 char c = *name++;
359                 if (c == '\n')
360                         return NULL;
361                 if (c == '/')
362                         break;
363         }
364
365         /*
366          * We don't accept absolute paths (/dev/null) as possibly valid
367          */
368         if (name == line+1)
369                 return NULL;
370
371         /*
372          * Accept a name only if it shows up twice, exactly the same
373          * form.
374          */
375         for (len = 0 ; ; len++) {
376                 char c = name[len];
377
378                 switch (c) {
379                 default:
380                         continue;
381                 case '\n':
382                         break;
383                 case '\t': case ' ':
384                         second = name+len;
385                         for (;;) {
386                                 char c = *second++;
387                                 if (c == '\n')
388                                         return NULL;
389                                 if (c == '/')
390                                         break;
391                         }
392                         if (second[len] == '\n' && !memcmp(name, second, len)) {
393                                 char *ret = xmalloc(len + 1);
394                                 memcpy(ret, name, len);
395                                 ret[len] = 0;
396                                 return ret;
397                         }
398                 }
399         }
400         return NULL;
401 }
402
403 /* Verify that we recognize the lines following a git header */
404 static int parse_git_header(char *line, int len, unsigned int size, struct patch *patch)
405 {
406         unsigned long offset;
407
408         /* A git diff has explicit new/delete information, so we don't guess */
409         patch->is_new = 0;
410         patch->is_delete = 0;
411
412         /*
413          * Some things may not have the old name in the
414          * rest of the headers anywhere (pure mode changes,
415          * or removing or adding empty files), so we get
416          * the default name from the header.
417          */
418         patch->def_name = git_header_name(line + strlen("diff --git "));
419
420         line += len;
421         size -= len;
422         linenr++;
423         for (offset = len ; size > 0 ; offset += len, size -= len, line += len, linenr++) {
424                 static const struct opentry {
425                         const char *str;
426                         int (*fn)(const char *, struct patch *);
427                 } optable[] = {
428                         { "@@ -", gitdiff_hdrend },
429                         { "--- ", gitdiff_oldname },
430                         { "+++ ", gitdiff_newname },
431                         { "old mode ", gitdiff_oldmode },
432                         { "new mode ", gitdiff_newmode },
433                         { "deleted file mode ", gitdiff_delete },
434                         { "new file mode ", gitdiff_newfile },
435                         { "copy from ", gitdiff_copysrc },
436                         { "copy to ", gitdiff_copydst },
437                         { "rename from ", gitdiff_renamesrc },
438                         { "rename to ", gitdiff_renamedst },
439                         { "similarity index ", gitdiff_similarity },
440                         { "", gitdiff_unrecognized },
441                 };
442                 int i;
443
444                 len = linelen(line, size);
445                 if (!len || line[len-1] != '\n')
446                         break;
447                 for (i = 0; i < sizeof(optable) / sizeof(optable[0]); i++) {
448                         const struct opentry *p = optable + i;
449                         int oplen = strlen(p->str);
450                         if (len < oplen || memcmp(p->str, line, oplen))
451                                 continue;
452                         if (p->fn(line + oplen, patch) < 0)
453                                 return offset;
454                         break;
455                 }
456         }
457
458         return offset;
459 }
460
461 static int parse_num(const char *line, unsigned long *p)
462 {
463         char *ptr;
464
465         if (!isdigit(*line))
466                 return 0;
467         *p = strtoul(line, &ptr, 10);
468         return ptr - line;
469 }
470
471 static int parse_range(const char *line, int len, int offset, const char *expect,
472                         unsigned long *p1, unsigned long *p2)
473 {
474         int digits, ex;
475
476         if (offset < 0 || offset >= len)
477                 return -1;
478         line += offset;
479         len -= offset;
480
481         digits = parse_num(line, p1);
482         if (!digits)
483                 return -1;
484
485         offset += digits;
486         line += digits;
487         len -= digits;
488
489         *p2 = *p1;
490         if (*line == ',') {
491                 digits = parse_num(line+1, p2);
492                 if (!digits)
493                         return -1;
494
495                 offset += digits+1;
496                 line += digits+1;
497                 len -= digits+1;
498         }
499
500         ex = strlen(expect);
501         if (ex > len)
502                 return -1;
503         if (memcmp(line, expect, ex))
504                 return -1;
505
506         return offset + ex;
507 }
508
509 /*
510  * Parse a unified diff fragment header of the
511  * form "@@ -a,b +c,d @@"
512  */
513 static int parse_fragment_header(char *line, int len, struct fragment *fragment)
514 {
515         int offset;
516
517         if (!len || line[len-1] != '\n')
518                 return -1;
519
520         /* Figure out the number of lines in a fragment */
521         offset = parse_range(line, len, 4, " +", &fragment->oldpos, &fragment->oldlines);
522         offset = parse_range(line, len, offset, " @@", &fragment->newpos, &fragment->newlines);
523
524         return offset;
525 }
526
527 static int find_header(char *line, unsigned long size, int *hdrsize, struct patch *patch)
528 {
529         unsigned long offset, len;
530
531         patch->is_rename = patch->is_copy = 0;
532         patch->is_new = patch->is_delete = -1;
533         patch->old_mode = patch->new_mode = 0;
534         patch->old_name = patch->new_name = NULL;
535         for (offset = 0; size > 0; offset += len, size -= len, line += len, linenr++) {
536                 unsigned long nextlen;
537
538                 len = linelen(line, size);
539                 if (!len)
540                         break;
541
542                 /* Testing this early allows us to take a few shortcuts.. */
543                 if (len < 6)
544                         continue;
545
546                 /*
547                  * Make sure we don't find any unconnected patch fragmants.
548                  * That's a sign that we didn't find a header, and that a
549                  * patch has become corrupted/broken up.
550                  */
551                 if (!memcmp("@@ -", line, 4)) {
552                         struct fragment dummy;
553                         if (parse_fragment_header(line, len, &dummy) < 0)
554                                 continue;
555                         error("patch fragment without header at line %d: %.*s", linenr, len-1, line);
556                 }
557
558                 if (size < len + 6)
559                         break;
560
561                 /*
562                  * Git patch? It might not have a real patch, just a rename
563                  * or mode change, so we handle that specially
564                  */
565                 if (!memcmp("diff --git ", line, 11)) {
566                         int git_hdr_len = parse_git_header(line, len, size, patch);
567                         if (git_hdr_len < 0)
568                                 continue;
569                         if (!patch->old_name && !patch->new_name)
570                                 die("git diff header lacks filename information");
571                         *hdrsize = git_hdr_len;
572                         return offset;
573                 }
574
575                 /** --- followed by +++ ? */
576                 if (memcmp("--- ", line,  4) || memcmp("+++ ", line + len, 4))
577                         continue;
578
579                 /*
580                  * We only accept unified patches, so we want it to
581                  * at least have "@@ -a,b +c,d @@\n", which is 14 chars
582                  * minimum
583                  */
584                 nextlen = linelen(line + len, size - len);
585                 if (size < nextlen + 14 || memcmp("@@ -", line + len + nextlen, 4))
586                         continue;
587
588                 /* Ok, we'll consider it a patch */
589                 parse_traditional_patch(line, line+len, patch);
590                 *hdrsize = len + nextlen;
591                 linenr += 2;
592                 return offset;
593         }
594         return -1;
595 }
596
597 /*
598  * Parse a unified diff. Note that this really needs
599  * to parse each fragment separately, since the only
600  * way to know the difference between a "---" that is
601  * part of a patch, and a "---" that starts the next
602  * patch is to look at the line counts..
603  */
604 static int parse_fragment(char *line, unsigned long size, struct patch *patch, struct fragment *fragment)
605 {
606         int added, deleted;
607         int len = linelen(line, size), offset;
608         unsigned long pos[4], oldlines, newlines;
609
610         offset = parse_fragment_header(line, len, fragment);
611         if (offset < 0)
612                 return -1;
613         oldlines = fragment->oldlines;
614         newlines = fragment->newlines;
615
616         if (patch->is_new < 0 && (pos[0] || oldlines))
617                 patch->is_new = 0;
618         if (patch->is_delete < 0 && (pos[1] || newlines))
619                 patch->is_delete = 0;
620
621         /* Parse the thing.. */
622         line += len;
623         size -= len;
624         linenr++;
625         added = deleted = 0;
626         for (offset = len; size > 0; offset += len, size -= len, line += len, linenr++) {
627                 if (!oldlines && !newlines)
628                         break;
629                 len = linelen(line, size);
630                 if (!len || line[len-1] != '\n')
631                         return -1;
632                 switch (*line) {
633                 default:
634                         return -1;
635                 case ' ':
636                         oldlines--;
637                         newlines--;
638                         break;
639                 case '-':
640                         deleted++;
641                         oldlines--;
642                         break;
643                 case '+':
644                         added++;
645                         newlines--;
646                         break;
647                 /* We allow "\ No newline at end of file" */
648                 case '\\':
649                         break;
650                 }
651         }
652         patch->lines_added += added;
653         patch->lines_deleted += deleted;
654         return offset;
655 }
656
657 static int parse_single_patch(char *line, unsigned long size, struct patch *patch)
658 {
659         unsigned long offset = 0;
660         struct fragment **fragp = &patch->fragments;
661
662         while (size > 4 && !memcmp(line, "@@ -", 4)) {
663                 struct fragment *fragment;
664                 int len;
665
666                 fragment = xmalloc(sizeof(*fragment));
667                 memset(fragment, 0, sizeof(*fragment));
668                 len = parse_fragment(line, size, patch, fragment);
669                 if (len <= 0)
670                         die("corrupt patch at line %d", linenr);
671
672                 fragment->patch = line;
673                 fragment->size = len;
674
675                 *fragp = fragment;
676                 fragp = &fragment->next;
677
678                 offset += len;
679                 line += len;
680                 size -= len;
681         }
682         return offset;
683 }
684
685 static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
686 {
687         int hdrsize, patchsize;
688         int offset = find_header(buffer, size, &hdrsize, patch);
689
690         if (offset < 0)
691                 return offset;
692
693         patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch);
694
695         return offset + hdrsize + patchsize;
696 }
697
698 const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
699 const char minuses[]= "----------------------------------------------------------------------";
700
701 static void show_stats(struct patch *patch)
702 {
703         char *name = patch->old_name;
704         int len, max, add, del;
705
706         if (!name)
707                 name = patch->new_name;
708
709         /*
710          * "scale" the filename
711          */
712         len = strlen(name);
713         max = max_len;
714         if (max > 50)
715                 max = 50;
716         if (len > max)
717                 name += len - max;
718         len = max;
719
720         /*
721          * scale the add/delete
722          */
723         max = max_change;
724         if (max + len > 70)
725                 max = 70 - len;
726         
727         add = (patch->lines_added * max + max_change/2) / max_change;
728         del = (patch->lines_deleted * max + max_change/2) / max_change;
729         printf(" %-*s |%5d %.*s%.*s\n",
730                 len, name, patch->lines_added + patch->lines_deleted,
731                 add, pluses, del, minuses);
732 }
733
734 static int check_patch(struct patch *patch)
735 {
736         struct stat st;
737         const char *old_name = patch->old_name;
738         const char *new_name = patch->new_name;
739
740         if (old_name) {
741                 int pos = cache_name_pos(old_name, strlen(old_name));
742                 int changed;
743
744                 if (pos < 0)
745                         return error("%s: does not exist in index", old_name);
746                 if (patch->is_new < 0)
747                         patch->is_new = 0;
748                 if (lstat(old_name, &st) < 0)
749                         return error("%s: %s\n", strerror(errno));
750                 changed = ce_match_stat(active_cache[pos], &st);
751                 if (changed)
752                         return error("%s: does not match index", old_name);
753                 if (!patch->old_mode)
754                         patch->old_mode = st.st_mode;
755         }
756
757         if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
758                 if (cache_name_pos(new_name, strlen(new_name)) >= 0)
759                         return error("%s: already exists in index", new_name);
760                 if (!lstat(new_name, &st))
761                         return error("%s: already exists in working directory", new_name);
762                 if (errno != ENOENT)
763                         return error("%s: %s", new_name, strerror(errno));
764         }
765         return 0;
766 }
767
768 static int check_patch_list(struct patch *patch)
769 {
770         int error = 0;
771
772         for (;patch ; patch = patch->next)
773                 error |= check_patch(patch);
774         return error;
775 }
776
777 static void show_file(int c, unsigned int mode, const char *name)
778 {
779         printf("%c %o %s\n", c, mode, name);
780 }
781
782 static void show_file_list(struct patch *patch)
783 {
784         for (;patch ; patch = patch->next) {
785                 if (patch->is_rename) {
786                         show_file('-', patch->old_mode, patch->old_name);
787                         show_file('+', patch->new_mode, patch->new_name);
788                         continue;
789                 }
790                 if (patch->is_copy || patch->is_new) {
791                         show_file('+', patch->new_mode, patch->new_name);
792                         continue;
793                 }
794                 if (patch->is_delete) {
795                         show_file('-', patch->old_mode, patch->old_name);
796                         continue;
797                 }
798                 if (patch->old_mode && patch->new_mode && patch->old_mode != patch->new_mode) {
799                         printf("M %o:%o %s\n", patch->old_mode, patch->new_mode, patch->old_name);
800                         continue;
801                 }
802                 printf("M %o %s\n", patch->old_mode, patch->old_name);
803         }
804 }
805
806 static void stat_patch_list(struct patch *patch)
807 {
808         int files, adds, dels;
809
810         for (files = adds = dels = 0 ; patch ; patch = patch->next) {
811                 files++;
812                 adds += patch->lines_added;
813                 dels += patch->lines_deleted;
814                 show_stats(patch);
815         }
816
817         printf(" %d files changed, %d insertions(+), %d deletions(-)\n", files, adds, dels);
818 }
819
820 static void patch_stats(struct patch *patch)
821 {
822         int lines = patch->lines_added + patch->lines_deleted;
823
824         if (lines > max_change)
825                 max_change = lines;
826         if (patch->old_name) {
827                 int len = strlen(patch->old_name);
828                 if (len > max_len)
829                         max_len = len;
830         }
831         if (patch->new_name) {
832                 int len = strlen(patch->new_name);
833                 if (len > max_len)
834                         max_len = len;
835         }
836 }
837
838 static int apply_patch(int fd)
839 {
840         unsigned long offset, size;
841         char *buffer = read_patch_file(fd, &size);
842         struct patch *list = NULL, **listp = &list;
843
844         if (!buffer)
845                 return -1;
846         offset = 0;
847         while (size > 0) {
848                 struct patch *patch;
849                 int nr;
850
851                 patch = xmalloc(sizeof(*patch));
852                 memset(patch, 0, sizeof(*patch));
853                 nr = parse_chunk(buffer + offset, size, patch);
854                 if (nr < 0)
855                         break;
856                 patch_stats(patch);
857                 *listp = patch;
858                 listp = &patch->next;
859                 offset += nr;
860                 size -= nr;
861         }
862
863         if ((check || apply) && check_patch_list(list) < 0)
864                 exit(1);
865
866         if (show_files)
867                 show_file_list(list);
868
869         if (diffstat)
870                 stat_patch_list(list);
871
872         free(buffer);
873         return 0;
874 }
875
876 int main(int argc, char **argv)
877 {
878         int i;
879         int read_stdin = 1;
880
881         if (read_cache() < 0)
882                 die("unable to read index file");
883
884         for (i = 1; i < argc; i++) {
885                 const char *arg = argv[i];
886                 int fd;
887
888                 if (!strcmp(arg, "-")) {
889                         apply_patch(0);
890                         read_stdin = 0;
891                         continue;
892                 }
893                 if (!strcmp(arg, "--no-merge")) {
894                         merge_patch = 0;
895                         continue;
896                 }
897                 if (!strcmp(arg, "--stat")) {
898                         apply = 0;
899                         diffstat = 1;
900                         continue;
901                 }
902                 if (!strcmp(arg, "--check")) {
903                         apply = 0;
904                         check = 1;
905                         continue;
906                 }
907                 if (!strcmp(arg, "--show-files")) {
908                         show_files = 1;
909                         continue;
910                 }
911                 fd = open(arg, O_RDONLY);
912                 if (fd < 0)
913                         usage(apply_usage);
914                 read_stdin = 0;
915                 apply_patch(fd);
916                 close(fd);
917         }
918         if (read_stdin)
919                 apply_patch(0);
920         return 0;
921 }