[PATCH] Show dissimilarity index for D and N case.
[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 static int gitdiff_dissimilarity(const char *line, struct patch *patch)
340 {
341         return 0;
342 }
343
344 /*
345  * This is normal for a diff that doesn't change anything: we'll fall through
346  * into the next diff. Tell the parser to break out.
347  */
348 static int gitdiff_unrecognized(const char *line, struct patch *patch)
349 {
350         return -1;
351 }
352
353 static char *git_header_name(char *line)
354 {
355         int len;
356         char *name, *second;
357
358         /*
359          * Find the first '/'
360          */
361         name = line;
362         for (;;) {
363                 char c = *name++;
364                 if (c == '\n')
365                         return NULL;
366                 if (c == '/')
367                         break;
368         }
369
370         /*
371          * We don't accept absolute paths (/dev/null) as possibly valid
372          */
373         if (name == line+1)
374                 return NULL;
375
376         /*
377          * Accept a name only if it shows up twice, exactly the same
378          * form.
379          */
380         for (len = 0 ; ; len++) {
381                 char c = name[len];
382
383                 switch (c) {
384                 default:
385                         continue;
386                 case '\n':
387                         break;
388                 case '\t': case ' ':
389                         second = name+len;
390                         for (;;) {
391                                 char c = *second++;
392                                 if (c == '\n')
393                                         return NULL;
394                                 if (c == '/')
395                                         break;
396                         }
397                         if (second[len] == '\n' && !memcmp(name, second, len)) {
398                                 char *ret = xmalloc(len + 1);
399                                 memcpy(ret, name, len);
400                                 ret[len] = 0;
401                                 return ret;
402                         }
403                 }
404         }
405         return NULL;
406 }
407
408 /* Verify that we recognize the lines following a git header */
409 static int parse_git_header(char *line, int len, unsigned int size, struct patch *patch)
410 {
411         unsigned long offset;
412
413         /* A git diff has explicit new/delete information, so we don't guess */
414         patch->is_new = 0;
415         patch->is_delete = 0;
416
417         /*
418          * Some things may not have the old name in the
419          * rest of the headers anywhere (pure mode changes,
420          * or removing or adding empty files), so we get
421          * the default name from the header.
422          */
423         patch->def_name = git_header_name(line + strlen("diff --git "));
424
425         line += len;
426         size -= len;
427         linenr++;
428         for (offset = len ; size > 0 ; offset += len, size -= len, line += len, linenr++) {
429                 static const struct opentry {
430                         const char *str;
431                         int (*fn)(const char *, struct patch *);
432                 } optable[] = {
433                         { "@@ -", gitdiff_hdrend },
434                         { "--- ", gitdiff_oldname },
435                         { "+++ ", gitdiff_newname },
436                         { "old mode ", gitdiff_oldmode },
437                         { "new mode ", gitdiff_newmode },
438                         { "deleted file mode ", gitdiff_delete },
439                         { "new file mode ", gitdiff_newfile },
440                         { "copy from ", gitdiff_copysrc },
441                         { "copy to ", gitdiff_copydst },
442                         { "rename from ", gitdiff_renamesrc },
443                         { "rename to ", gitdiff_renamedst },
444                         { "similarity index ", gitdiff_similarity },
445                         { "dissimilarity index ", gitdiff_dissimilarity },
446                         { "", gitdiff_unrecognized },
447                 };
448                 int i;
449
450                 len = linelen(line, size);
451                 if (!len || line[len-1] != '\n')
452                         break;
453                 for (i = 0; i < sizeof(optable) / sizeof(optable[0]); i++) {
454                         const struct opentry *p = optable + i;
455                         int oplen = strlen(p->str);
456                         if (len < oplen || memcmp(p->str, line, oplen))
457                                 continue;
458                         if (p->fn(line + oplen, patch) < 0)
459                                 return offset;
460                         break;
461                 }
462         }
463
464         return offset;
465 }
466
467 static int parse_num(const char *line, unsigned long *p)
468 {
469         char *ptr;
470
471         if (!isdigit(*line))
472                 return 0;
473         *p = strtoul(line, &ptr, 10);
474         return ptr - line;
475 }
476
477 static int parse_range(const char *line, int len, int offset, const char *expect,
478                         unsigned long *p1, unsigned long *p2)
479 {
480         int digits, ex;
481
482         if (offset < 0 || offset >= len)
483                 return -1;
484         line += offset;
485         len -= offset;
486
487         digits = parse_num(line, p1);
488         if (!digits)
489                 return -1;
490
491         offset += digits;
492         line += digits;
493         len -= digits;
494
495         *p2 = *p1;
496         if (*line == ',') {
497                 digits = parse_num(line+1, p2);
498                 if (!digits)
499                         return -1;
500
501                 offset += digits+1;
502                 line += digits+1;
503                 len -= digits+1;
504         }
505
506         ex = strlen(expect);
507         if (ex > len)
508                 return -1;
509         if (memcmp(line, expect, ex))
510                 return -1;
511
512         return offset + ex;
513 }
514
515 /*
516  * Parse a unified diff fragment header of the
517  * form "@@ -a,b +c,d @@"
518  */
519 static int parse_fragment_header(char *line, int len, struct fragment *fragment)
520 {
521         int offset;
522
523         if (!len || line[len-1] != '\n')
524                 return -1;
525
526         /* Figure out the number of lines in a fragment */
527         offset = parse_range(line, len, 4, " +", &fragment->oldpos, &fragment->oldlines);
528         offset = parse_range(line, len, offset, " @@", &fragment->newpos, &fragment->newlines);
529
530         return offset;
531 }
532
533 static int find_header(char *line, unsigned long size, int *hdrsize, struct patch *patch)
534 {
535         unsigned long offset, len;
536
537         patch->is_rename = patch->is_copy = 0;
538         patch->is_new = patch->is_delete = -1;
539         patch->old_mode = patch->new_mode = 0;
540         patch->old_name = patch->new_name = NULL;
541         for (offset = 0; size > 0; offset += len, size -= len, line += len, linenr++) {
542                 unsigned long nextlen;
543
544                 len = linelen(line, size);
545                 if (!len)
546                         break;
547
548                 /* Testing this early allows us to take a few shortcuts.. */
549                 if (len < 6)
550                         continue;
551
552                 /*
553                  * Make sure we don't find any unconnected patch fragmants.
554                  * That's a sign that we didn't find a header, and that a
555                  * patch has become corrupted/broken up.
556                  */
557                 if (!memcmp("@@ -", line, 4)) {
558                         struct fragment dummy;
559                         if (parse_fragment_header(line, len, &dummy) < 0)
560                                 continue;
561                         error("patch fragment without header at line %d: %.*s", linenr, len-1, line);
562                 }
563
564                 if (size < len + 6)
565                         break;
566
567                 /*
568                  * Git patch? It might not have a real patch, just a rename
569                  * or mode change, so we handle that specially
570                  */
571                 if (!memcmp("diff --git ", line, 11)) {
572                         int git_hdr_len = parse_git_header(line, len, size, patch);
573                         if (git_hdr_len < 0)
574                                 continue;
575                         if (!patch->old_name && !patch->new_name)
576                                 die("git diff header lacks filename information");
577                         *hdrsize = git_hdr_len;
578                         return offset;
579                 }
580
581                 /** --- followed by +++ ? */
582                 if (memcmp("--- ", line,  4) || memcmp("+++ ", line + len, 4))
583                         continue;
584
585                 /*
586                  * We only accept unified patches, so we want it to
587                  * at least have "@@ -a,b +c,d @@\n", which is 14 chars
588                  * minimum
589                  */
590                 nextlen = linelen(line + len, size - len);
591                 if (size < nextlen + 14 || memcmp("@@ -", line + len + nextlen, 4))
592                         continue;
593
594                 /* Ok, we'll consider it a patch */
595                 parse_traditional_patch(line, line+len, patch);
596                 *hdrsize = len + nextlen;
597                 linenr += 2;
598                 return offset;
599         }
600         return -1;
601 }
602
603 /*
604  * Parse a unified diff. Note that this really needs
605  * to parse each fragment separately, since the only
606  * way to know the difference between a "---" that is
607  * part of a patch, and a "---" that starts the next
608  * patch is to look at the line counts..
609  */
610 static int parse_fragment(char *line, unsigned long size, struct patch *patch, struct fragment *fragment)
611 {
612         int added, deleted;
613         int len = linelen(line, size), offset;
614         unsigned long pos[4], oldlines, newlines;
615
616         offset = parse_fragment_header(line, len, fragment);
617         if (offset < 0)
618                 return -1;
619         oldlines = fragment->oldlines;
620         newlines = fragment->newlines;
621
622         if (patch->is_new < 0 && (pos[0] || oldlines))
623                 patch->is_new = 0;
624         if (patch->is_delete < 0 && (pos[1] || newlines))
625                 patch->is_delete = 0;
626
627         /* Parse the thing.. */
628         line += len;
629         size -= len;
630         linenr++;
631         added = deleted = 0;
632         for (offset = len; size > 0; offset += len, size -= len, line += len, linenr++) {
633                 if (!oldlines && !newlines)
634                         break;
635                 len = linelen(line, size);
636                 if (!len || line[len-1] != '\n')
637                         return -1;
638                 switch (*line) {
639                 default:
640                         return -1;
641                 case ' ':
642                         oldlines--;
643                         newlines--;
644                         break;
645                 case '-':
646                         deleted++;
647                         oldlines--;
648                         break;
649                 case '+':
650                         added++;
651                         newlines--;
652                         break;
653                 /* We allow "\ No newline at end of file" */
654                 case '\\':
655                         break;
656                 }
657         }
658         patch->lines_added += added;
659         patch->lines_deleted += deleted;
660         return offset;
661 }
662
663 static int parse_single_patch(char *line, unsigned long size, struct patch *patch)
664 {
665         unsigned long offset = 0;
666         struct fragment **fragp = &patch->fragments;
667
668         while (size > 4 && !memcmp(line, "@@ -", 4)) {
669                 struct fragment *fragment;
670                 int len;
671
672                 fragment = xmalloc(sizeof(*fragment));
673                 memset(fragment, 0, sizeof(*fragment));
674                 len = parse_fragment(line, size, patch, fragment);
675                 if (len <= 0)
676                         die("corrupt patch at line %d", linenr);
677
678                 fragment->patch = line;
679                 fragment->size = len;
680
681                 *fragp = fragment;
682                 fragp = &fragment->next;
683
684                 offset += len;
685                 line += len;
686                 size -= len;
687         }
688         return offset;
689 }
690
691 static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
692 {
693         int hdrsize, patchsize;
694         int offset = find_header(buffer, size, &hdrsize, patch);
695
696         if (offset < 0)
697                 return offset;
698
699         patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch);
700
701         return offset + hdrsize + patchsize;
702 }
703
704 const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
705 const char minuses[]= "----------------------------------------------------------------------";
706
707 static void show_stats(struct patch *patch)
708 {
709         char *name = patch->old_name;
710         int len, max, add, del;
711
712         if (!name)
713                 name = patch->new_name;
714
715         /*
716          * "scale" the filename
717          */
718         len = strlen(name);
719         max = max_len;
720         if (max > 50)
721                 max = 50;
722         if (len > max)
723                 name += len - max;
724         len = max;
725
726         /*
727          * scale the add/delete
728          */
729         max = max_change;
730         if (max + len > 70)
731                 max = 70 - len;
732         
733         add = (patch->lines_added * max + max_change/2) / max_change;
734         del = (patch->lines_deleted * max + max_change/2) / max_change;
735         printf(" %-*s |%5d %.*s%.*s\n",
736                 len, name, patch->lines_added + patch->lines_deleted,
737                 add, pluses, del, minuses);
738 }
739
740 static int check_patch(struct patch *patch)
741 {
742         struct stat st;
743         const char *old_name = patch->old_name;
744         const char *new_name = patch->new_name;
745
746         if (old_name) {
747                 int pos = cache_name_pos(old_name, strlen(old_name));
748                 int changed;
749
750                 if (pos < 0)
751                         return error("%s: does not exist in index", old_name);
752                 if (patch->is_new < 0)
753                         patch->is_new = 0;
754                 if (lstat(old_name, &st) < 0)
755                         return error("%s: %s\n", strerror(errno));
756                 changed = ce_match_stat(active_cache[pos], &st);
757                 if (changed)
758                         return error("%s: does not match index", old_name);
759                 if (!patch->old_mode)
760                         patch->old_mode = st.st_mode;
761         }
762
763         if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
764                 if (cache_name_pos(new_name, strlen(new_name)) >= 0)
765                         return error("%s: already exists in index", new_name);
766                 if (!lstat(new_name, &st))
767                         return error("%s: already exists in working directory", new_name);
768                 if (errno != ENOENT)
769                         return error("%s: %s", new_name, strerror(errno));
770         }
771         return 0;
772 }
773
774 static int check_patch_list(struct patch *patch)
775 {
776         int error = 0;
777
778         for (;patch ; patch = patch->next)
779                 error |= check_patch(patch);
780         return error;
781 }
782
783 static void show_file(int c, unsigned int mode, const char *name)
784 {
785         printf("%c %o %s\n", c, mode, name);
786 }
787
788 static void show_file_list(struct patch *patch)
789 {
790         for (;patch ; patch = patch->next) {
791                 if (patch->is_rename) {
792                         show_file('-', patch->old_mode, patch->old_name);
793                         show_file('+', patch->new_mode, patch->new_name);
794                         continue;
795                 }
796                 if (patch->is_copy || patch->is_new) {
797                         show_file('+', patch->new_mode, patch->new_name);
798                         continue;
799                 }
800                 if (patch->is_delete) {
801                         show_file('-', patch->old_mode, patch->old_name);
802                         continue;
803                 }
804                 if (patch->old_mode && patch->new_mode && patch->old_mode != patch->new_mode) {
805                         printf("M %o:%o %s\n", patch->old_mode, patch->new_mode, patch->old_name);
806                         continue;
807                 }
808                 printf("M %o %s\n", patch->old_mode, patch->old_name);
809         }
810 }
811
812 static void stat_patch_list(struct patch *patch)
813 {
814         int files, adds, dels;
815
816         for (files = adds = dels = 0 ; patch ; patch = patch->next) {
817                 files++;
818                 adds += patch->lines_added;
819                 dels += patch->lines_deleted;
820                 show_stats(patch);
821         }
822
823         printf(" %d files changed, %d insertions(+), %d deletions(-)\n", files, adds, dels);
824 }
825
826 static void patch_stats(struct patch *patch)
827 {
828         int lines = patch->lines_added + patch->lines_deleted;
829
830         if (lines > max_change)
831                 max_change = lines;
832         if (patch->old_name) {
833                 int len = strlen(patch->old_name);
834                 if (len > max_len)
835                         max_len = len;
836         }
837         if (patch->new_name) {
838                 int len = strlen(patch->new_name);
839                 if (len > max_len)
840                         max_len = len;
841         }
842 }
843
844 static int apply_patch(int fd)
845 {
846         unsigned long offset, size;
847         char *buffer = read_patch_file(fd, &size);
848         struct patch *list = NULL, **listp = &list;
849
850         if (!buffer)
851                 return -1;
852         offset = 0;
853         while (size > 0) {
854                 struct patch *patch;
855                 int nr;
856
857                 patch = xmalloc(sizeof(*patch));
858                 memset(patch, 0, sizeof(*patch));
859                 nr = parse_chunk(buffer + offset, size, patch);
860                 if (nr < 0)
861                         break;
862                 patch_stats(patch);
863                 *listp = patch;
864                 listp = &patch->next;
865                 offset += nr;
866                 size -= nr;
867         }
868
869         if ((check || apply) && check_patch_list(list) < 0)
870                 exit(1);
871
872         if (show_files)
873                 show_file_list(list);
874
875         if (diffstat)
876                 stat_patch_list(list);
877
878         free(buffer);
879         return 0;
880 }
881
882 int main(int argc, char **argv)
883 {
884         int i;
885         int read_stdin = 1;
886
887         if (read_cache() < 0)
888                 die("unable to read index file");
889
890         for (i = 1; i < argc; i++) {
891                 const char *arg = argv[i];
892                 int fd;
893
894                 if (!strcmp(arg, "-")) {
895                         apply_patch(0);
896                         read_stdin = 0;
897                         continue;
898                 }
899                 if (!strcmp(arg, "--no-merge")) {
900                         merge_patch = 0;
901                         continue;
902                 }
903                 if (!strcmp(arg, "--stat")) {
904                         apply = 0;
905                         diffstat = 1;
906                         continue;
907                 }
908                 if (!strcmp(arg, "--check")) {
909                         apply = 0;
910                         check = 1;
911                         continue;
912                 }
913                 if (!strcmp(arg, "--show-files")) {
914                         show_files = 1;
915                         continue;
916                 }
917                 fd = open(arg, O_RDONLY);
918                 if (fd < 0)
919                         usage(apply_usage);
920                 read_stdin = 0;
921                 apply_patch(fd);
922                 close(fd);
923         }
924         if (read_stdin)
925                 apply_patch(0);
926         return 0;
927 }