4 * Copyright (C) Linus Torvalds, 2005
6 * This applies patches on top of some (arbitrary) version of the SCM.
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
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.
19 // We default to the merge behaviour, since that's what most people would
21 static int merge_patch
= 1;
22 static const char apply_usage
[] = "git-apply <patch>";
25 * Various "current state", notably line numbers and what
26 * file (and how) we're patching right now.. The "is_xxxx"
27 * things are flags, where -1 means "don't know yet".
29 static int linenr
= 1;
30 static char *def_name
= NULL
;
33 unsigned long oldpos
, oldlines
;
34 unsigned long newpos
, newlines
;
37 struct fragment
*next
;
41 char *new_name
, *old_name
;
42 unsigned int old_mode
, new_mode
;
43 int is_rename
, is_copy
, is_new
, is_delete
;
44 struct fragment
*fragments
;
48 #define CHUNKSIZE (8192)
51 static void *read_patch_file(int fd
, unsigned long *sizep
)
53 unsigned long size
= 0, alloc
= CHUNKSIZE
;
54 void *buffer
= xmalloc(alloc
);
57 int nr
= alloc
- size
;
60 buffer
= xrealloc(buffer
, alloc
);
63 nr
= read(fd
, buffer
+ size
, nr
);
69 die("git-apply: read returned %s", strerror(errno
));
76 * Make sure that we have some slop in the buffer
77 * so that we can do speculative "memcmp" etc, and
78 * see to it that it is NUL-filled.
80 if (alloc
< size
+ SLOP
)
81 buffer
= xrealloc(buffer
, size
+ SLOP
);
82 memset(buffer
+ size
, 0, SLOP
);
86 static unsigned long linelen(char *buffer
, unsigned long size
)
88 unsigned long len
= 0;
91 if (*buffer
++ == '\n')
97 static int is_dev_null(const char *str
)
99 return !memcmp("/dev/null", str
, 9) && isspace(str
[9]);
106 static int name_terminate(const char *name
, int namelen
, int c
, int terminate
)
108 if (c
== ' ' && !(terminate
& TERM_SPACE
))
110 if (c
== '\t' && !(terminate
& TERM_TAB
))
114 * Do we want an existing name? Return false and
115 * continue if it's not there.
117 if (terminate
& TERM_EXIST
)
118 return cache_name_pos(name
, namelen
) >= 0;
123 static char * find_name(const char *line
, char *def
, int p_value
, int terminate
)
126 const char *start
= line
;
135 if (name_terminate(start
, line
-start
, c
, terminate
))
139 if (c
== '/' && !--p_value
)
149 * Generally we prefer the shorter name, especially
150 * if the other one is just a variation of that with
151 * something else tacked on to the end (ie "file.orig"
155 int deflen
= strlen(def
);
156 if (deflen
< len
&& !strncmp(start
, def
, deflen
))
160 name
= xmalloc(len
+ 1);
161 memcpy(name
, start
, len
);
168 * Get the name etc info from the --/+++ lines of a traditional patch header
170 * NOTE! This hardcodes "-p1" behaviour in filename detection.
172 * FIXME! The end-of-filename heuristics are kind of screwy. For existing
173 * files, we can happily check the index for a match, but for creating a
174 * new file we should try to match whatever "patch" does. I have no idea.
176 static void parse_traditional_patch(const char *first
, const char *second
, struct patch
*patch
)
181 first
+= 4; // skip "--- "
182 second
+= 4; // skip "+++ "
183 if (is_dev_null(first
)) {
185 patch
->is_delete
= 0;
186 name
= find_name(second
, def_name
, p_value
, TERM_SPACE
| TERM_TAB
);
187 patch
->new_name
= name
;
188 } else if (is_dev_null(second
)) {
190 patch
->is_delete
= 1;
191 name
= find_name(first
, def_name
, p_value
, TERM_EXIST
| TERM_SPACE
| TERM_TAB
);
192 patch
->old_name
= name
;
194 name
= find_name(first
, def_name
, p_value
, TERM_EXIST
| TERM_SPACE
| TERM_TAB
);
195 name
= find_name(second
, name
, p_value
, TERM_EXIST
| TERM_SPACE
| TERM_TAB
);
196 patch
->old_name
= patch
->new_name
= name
;
199 die("unable to find filename in patch at line %d", linenr
);
202 static int gitdiff_hdrend(const char *line
, struct patch
*patch
)
208 * We're anal about diff header consistency, to make
209 * sure that we don't end up having strange ambiguous
210 * patches floating around.
212 * As a result, gitdiff_{old|new}name() will check
213 * their names against any previous information, just
216 static char *gitdiff_verify_name(const char *line
, int isnull
, char *orig_name
, const char *oldnew
)
221 if (!orig_name
&& !isnull
)
222 return find_name(line
, NULL
, 1, 0);
230 die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name
, linenr
);
243 if (memcmp(line
, name
, len
) || line
[len
] != '\n')
247 die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew
, linenr
);
251 static int gitdiff_oldname(const char *line
, struct patch
*patch
)
253 patch
->old_name
= gitdiff_verify_name(line
, patch
->is_new
, patch
->old_name
, "old");
257 static int gitdiff_newname(const char *line
, struct patch
*patch
)
259 patch
->new_name
= gitdiff_verify_name(line
, patch
->is_delete
, patch
->new_name
, "new");
263 static int gitdiff_oldmode(const char *line
, struct patch
*patch
)
265 patch
->old_mode
= strtoul(line
, NULL
, 8);
269 static int gitdiff_newmode(const char *line
, struct patch
*patch
)
271 patch
->new_mode
= strtoul(line
, NULL
, 8);
275 static int gitdiff_delete(const char *line
, struct patch
*patch
)
277 patch
->is_delete
= 1;
278 return gitdiff_oldmode(line
, patch
);
281 static int gitdiff_newfile(const char *line
, struct patch
*patch
)
284 return gitdiff_newmode(line
, patch
);
287 static int gitdiff_copysrc(const char *line
, struct patch
*patch
)
290 patch
->old_name
= find_name(line
, NULL
, 0, 0);
294 static int gitdiff_copydst(const char *line
, struct patch
*patch
)
297 patch
->new_name
= find_name(line
, NULL
, 0, 0);
301 static int gitdiff_renamesrc(const char *line
, struct patch
*patch
)
303 patch
->is_rename
= 1;
304 patch
->old_name
= find_name(line
, NULL
, 0, 0);
308 static int gitdiff_renamedst(const char *line
, struct patch
*patch
)
310 patch
->is_rename
= 1;
311 patch
->new_name
= find_name(line
, NULL
, 0, 0);
315 static int gitdiff_similarity(const char *line
, struct patch
*patch
)
321 * This is normal for a diff that doesn't change anything: we'll fall through
322 * into the next diff. Tell the parser to break out.
324 static int gitdiff_unrecognized(const char *line
, struct patch
*patch
)
329 /* Verify that we recognize the lines following a git header */
330 static int parse_git_header(char *line
, int len
, unsigned int size
, struct patch
*patch
)
332 unsigned long offset
;
334 /* A git diff has explicit new/delete information, so we don't guess */
336 patch
->is_delete
= 0;
341 for (offset
= len
; size
> 0 ; offset
+= len
, size
-= len
, line
+= len
, linenr
++) {
342 static const struct opentry
{
344 int (*fn
)(const char *, struct patch
*);
346 { "@@ -", gitdiff_hdrend
},
347 { "--- ", gitdiff_oldname
},
348 { "+++ ", gitdiff_newname
},
349 { "old mode ", gitdiff_oldmode
},
350 { "new mode ", gitdiff_newmode
},
351 { "deleted file mode ", gitdiff_delete
},
352 { "new file mode ", gitdiff_newfile
},
353 { "copy from ", gitdiff_copysrc
},
354 { "copy to ", gitdiff_copydst
},
355 { "rename from ", gitdiff_renamesrc
},
356 { "rename to ", gitdiff_renamedst
},
357 { "similarity index ", gitdiff_similarity
},
358 { "", gitdiff_unrecognized
},
362 len
= linelen(line
, size
);
363 if (!len
|| line
[len
-1] != '\n')
365 for (i
= 0; i
< sizeof(optable
) / sizeof(optable
[0]); i
++) {
366 const struct opentry
*p
= optable
+ i
;
367 int oplen
= strlen(p
->str
);
368 if (len
< oplen
|| memcmp(p
->str
, line
, oplen
))
370 if (p
->fn(line
+ oplen
, patch
) < 0)
379 static int parse_num(const char *line
, int len
, int offset
, const char *expect
, unsigned long *p
)
384 if (offset
< 0 || offset
>= len
)
391 *p
= strtoul(line
, &ptr
, 10);
402 if (memcmp(line
, expect
, ex
))
409 * Parse a unified diff fragment header of the
410 * form "@@ -a,b +c,d @@"
412 static int parse_fragment_header(char *line
, int len
, struct fragment
*fragment
)
416 if (!len
|| line
[len
-1] != '\n')
419 /* Figure out the number of lines in a fragment */
420 offset
= parse_num(line
, len
, 4, ",", &fragment
->oldpos
);
421 offset
= parse_num(line
, len
, offset
, " +", &fragment
->oldlines
);
422 offset
= parse_num(line
, len
, offset
, ",", &fragment
->newpos
);
423 offset
= parse_num(line
, len
, offset
, " @@", &fragment
->newlines
);
428 static int find_header(char *line
, unsigned long size
, int *hdrsize
, struct patch
*patch
)
430 unsigned long offset
, len
;
432 patch
->is_rename
= patch
->is_copy
= 0;
433 patch
->is_new
= patch
->is_delete
= -1;
434 patch
->old_mode
= patch
->new_mode
= 0;
435 patch
->old_name
= patch
->new_name
= NULL
;
436 for (offset
= 0; size
> 0; offset
+= len
, size
-= len
, line
+= len
, linenr
++) {
437 unsigned long nextlen
;
439 len
= linelen(line
, size
);
443 /* Testing this early allows us to take a few shortcuts.. */
448 * Make sure we don't find any unconnected patch fragmants.
449 * That's a sign that we didn't find a header, and that a
450 * patch has become corrupted/broken up.
452 if (!memcmp("@@ -", line
, 4)) {
453 struct fragment dummy
;
454 if (parse_fragment_header(line
, len
, &dummy
) < 0)
456 error("patch fragment without header at line %d: %.*s", linenr
, len
-1, line
);
463 * Git patch? It might not have a real patch, just a rename
464 * or mode change, so we handle that specially
466 if (!memcmp("diff --git ", line
, 11)) {
467 int git_hdr_len
= parse_git_header(line
, len
, size
, patch
);
471 *hdrsize
= git_hdr_len
;
475 /** --- followed by +++ ? */
476 if (memcmp("--- ", line
, 4) || memcmp("+++ ", line
+ len
, 4))
480 * We only accept unified patches, so we want it to
481 * at least have "@@ -a,b +c,d @@\n", which is 14 chars
484 nextlen
= linelen(line
+ len
, size
- len
);
485 if (size
< nextlen
+ 14 || memcmp("@@ -", line
+ len
+ nextlen
, 4))
488 /* Ok, we'll consider it a patch */
489 parse_traditional_patch(line
, line
+len
, patch
);
490 *hdrsize
= len
+ nextlen
;
498 * Parse a unified diff. Note that this really needs
499 * to parse each fragment separately, since the only
500 * way to know the difference between a "---" that is
501 * part of a patch, and a "---" that starts the next
502 * patch is to look at the line counts..
504 static int parse_fragment(char *line
, unsigned long size
, struct patch
*patch
, struct fragment
*fragment
)
506 int len
= linelen(line
, size
), offset
;
507 unsigned long pos
[4], oldlines
, newlines
;
509 offset
= parse_fragment_header(line
, len
, fragment
);
512 oldlines
= fragment
->oldlines
;
513 newlines
= fragment
->newlines
;
515 if (patch
->is_new
< 0 && (pos
[0] || oldlines
))
517 if (patch
->is_delete
< 0 && (pos
[1] || newlines
))
518 patch
->is_delete
= 0;
520 /* Parse the thing.. */
524 for (offset
= len
; size
> 0; offset
+= len
, size
-= len
, line
+= len
, linenr
++) {
525 if (!oldlines
&& !newlines
)
527 len
= linelen(line
, size
);
528 if (!len
|| line
[len
-1] != '\n')
548 static int parse_single_patch(char *line
, unsigned long size
, struct patch
*patch
)
550 unsigned long offset
= 0;
551 struct fragment
**fragp
= &patch
->fragments
;
553 while (size
> 4 && !memcmp(line
, "@@ -", 4)) {
554 struct fragment
*fragment
;
557 fragment
= xmalloc(sizeof(*fragment
));
558 memset(fragment
, 0, sizeof(*fragment
));
559 len
= parse_fragment(line
, size
, patch
, fragment
);
561 die("corrupt patch at line %d", linenr
);
563 fragment
->patch
= line
;
564 fragment
->size
= len
;
567 fragp
= &fragment
->next
;
576 static int parse_chunk(char *buffer
, unsigned long size
, struct patch
*patch
)
578 int hdrsize
, patchsize
;
579 int offset
= find_header(buffer
, size
, &hdrsize
, patch
);
584 patchsize
= parse_single_patch(buffer
+ offset
+ hdrsize
, size
- offset
- hdrsize
, patch
);
586 return offset
+ hdrsize
+ patchsize
;
589 static void apply_patch_list(struct patch
*patch
)
592 die("no patch found");
594 const char *old_name
= patch
->old_name
;
595 const char *new_name
= patch
->new_name
;
596 struct fragment
*frag
;
599 if (cache_name_pos(old_name
, strlen(old_name
)) < 0)
600 die("file %s does not exist", old_name
);
601 if (patch
->is_new
< 0)
604 if (new_name
&& (patch
->is_new
| patch
->is_rename
| patch
->is_copy
)) {
605 if (cache_name_pos(new_name
, strlen(new_name
)) >= 0)
606 die("file %s already exists", new_name
);
609 printf("Applying patch to %s\n", new_name
);
610 printf(" new=%d delete=%d copy=%d rename=%d\n",
611 patch
->is_new
, patch
->is_delete
, patch
->is_copy
, patch
->is_rename
);
612 if (patch
->old_mode
!= patch
->new_mode
)
613 printf(" %o->%o\n", patch
->old_mode
, patch
->new_mode
);
614 frag
= patch
->fragments
;
616 printf("Fragment %lu,%lu -> %lu,%lu\n%.*s",
617 frag
->oldpos
, frag
->oldlines
,
618 frag
->newpos
, frag
->newlines
,
619 frag
->size
, frag
->patch
);
623 } while ((patch
= patch
->next
) != NULL
);
626 static int apply_patch(int fd
)
628 unsigned long offset
, size
;
629 char *buffer
= read_patch_file(fd
, &size
);
630 struct patch
*list
= NULL
, **listp
= &list
;
639 patch
= xmalloc(sizeof(*patch
));
640 memset(patch
, 0, sizeof(*patch
));
641 nr
= parse_chunk(buffer
+ offset
, size
, patch
);
645 listp
= &patch
->next
;
650 apply_patch_list(list
);
656 int main(int argc
, char **argv
)
661 if (read_cache() < 0)
662 die("unable to read index file");
664 for (i
= 1; i
< argc
; i
++) {
665 const char *arg
= argv
[i
];
668 if (!strcmp(arg
, "-")) {
673 if (!strcmp(arg
, "--no-merge")) {
677 fd
= open(arg
, O_RDONLY
);