unsigned long deflate_origlen;
int lines_added, lines_deleted;
int score;
+ int inaccurate_eof:1;
struct fragment *fragments;
char *result;
unsigned long resultsize;
buffer = xrealloc(buffer, alloc);
nr = alloc - size;
}
- nr = xread(fd, buffer + size, nr);
+ nr = xread(fd, (char *) buffer + size, nr);
if (!nr)
break;
if (nr < 0)
*/
if (alloc < size + SLOP)
buffer = xrealloc(buffer, size + SLOP);
- memset(buffer + size, 0, SLOP);
+ memset((char *) buffer + size, 0, SLOP);
return buffer;
}
return error("unable to open %s", path);
got = 0;
for (;;) {
- int ret = xread(fd, buf + got, size - got);
+ int ret = xread(fd, (char *) buf + got, size - got);
if (ret <= 0)
break;
got += ret;
return plen;
}
-static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
+static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag,
+ int inaccurate_eof)
{
+ int match_beginning, match_end;
char *buf = desc->buffer;
const char *patch = frag->patch;
int offset, size = frag->size;
size -= len;
}
-#ifdef NO_ACCURATE_DIFF
- if (oldsize > 0 && old[oldsize - 1] == '\n' &&
+ if (inaccurate_eof && oldsize > 0 && old[oldsize - 1] == '\n' &&
newsize > 0 && new[newsize - 1] == '\n') {
oldsize--;
newsize--;
}
-#endif
oldlines = old;
newlines = new;
leading = frag->leading;
trailing = frag->trailing;
+
+ /*
+ * If we don't have any leading/trailing data in the patch,
+ * we want it to match at the beginning/end of the file.
+ */
+ match_beginning = !leading && (frag->oldpos == 1);
+ match_end = !trailing;
+
lines = 0;
pos = frag->newpos;
for (;;) {
offset = find_offset(buf, desc->size, oldlines, oldsize, pos, &lines);
+ if (match_end && offset + oldsize != desc->size)
+ offset = -1;
+ if (match_beginning && offset)
+ offset = -1;
if (offset >= 0) {
int diff = newsize - oldsize;
unsigned long size = desc->size + diff;
/* Am I at my context limits? */
if ((leading <= p_context) && (trailing <= p_context))
break;
+ if (match_beginning || match_end) {
+ match_beginning = match_end = 0;
+ continue;
+ }
/* Reduce the number of context lines
* Reduce both leading and trailing if they are equal
* otherwise just reduce the larger context.
return apply_binary(desc, patch);
while (frag) {
- if (apply_one_fragment(desc, frag) < 0)
+ if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0)
return error("patch failed: %s:%ld",
name, frag->oldpos);
frag = frag->next;
}
}
-static struct cache_file cache_file;
+static struct lock_file lock_file;
static struct excludes {
struct excludes *next;
return 1;
}
-static int apply_patch(int fd, const char *filename)
+static int apply_patch(int fd, const char *filename, int inaccurate_eof)
{
unsigned long offset, size;
char *buffer = read_patch_file(fd, &size);
int nr;
patch = xcalloc(1, sizeof(*patch));
+ patch->inaccurate_eof = inaccurate_eof;
nr = parse_chunk(buffer + offset, size, patch);
if (nr < 0)
break;
apply = 0;
write_index = check_index && apply;
- if (write_index && newfd < 0)
- newfd = hold_index_file_for_update(&cache_file, get_index_file());
+ if (write_index && newfd < 0) {
+ newfd = hold_lock_file_for_update(&lock_file,
+ get_index_file());
+ if (newfd < 0)
+ die("unable to create new index file");
+ }
if (check_index) {
if (read_cache() < 0)
die("unable to read index file");
{
int i;
int read_stdin = 1;
+ int inaccurate_eof = 0;
+
const char *whitespace_option = NULL;
for (i = 1; i < argc; i++) {
int fd;
if (!strcmp(arg, "-")) {
- apply_patch(0, "<stdin>");
+ apply_patch(0, "<stdin>", inaccurate_eof);
read_stdin = 0;
continue;
}
parse_whitespace_option(arg + 13);
continue;
}
+ if (!strcmp(arg, "--inaccurate-eof")) {
+ inaccurate_eof = 1;
+ continue;
+ }
if (check_index && prefix_length < 0) {
prefix = setup_git_directory();
usage(apply_usage);
read_stdin = 0;
set_default_whitespace_mode(whitespace_option);
- apply_patch(fd, arg);
+ apply_patch(fd, arg, inaccurate_eof);
close(fd);
}
set_default_whitespace_mode(whitespace_option);
if (read_stdin)
- apply_patch(0, "<stdin>");
+ apply_patch(0, "<stdin>", inaccurate_eof);
if (whitespace_error) {
if (squelch_whitespace_errors &&
squelch_whitespace_errors < whitespace_error) {
if (write_index) {
if (write_cache(newfd, active_cache, active_nr) ||
- commit_index_file(&cache_file))
- die("Unable to write new cachefile");
+ close(newfd) || commit_lock_file(&lock_file))
+ die("Unable to write new index file");
}
return 0;