case S_IFREG:
if (strbuf_read_file(buf, path, st->st_size) != st->st_size)
return error("unable to open or read %s", path);
- convert_to_git(path, buf->buf, buf->len, buf);
+ convert_to_git(path, buf->buf, buf->len, buf, 0);
return 0;
default:
return -1;
}
}
-static int copy_wsfix(char *output, const char *patch, int plen,
- unsigned ws_rule, int count_error)
-{
- /*
- * plen is number of bytes to be copied from patch, starting
- * at patch. Typically patch[plen-1] is '\n', unless this is
- * the incomplete last line.
- */
- int i;
- int add_nl_to_tail = 0;
- int add_cr_to_tail = 0;
- int fixed = 0;
- int last_tab_in_indent = -1;
- int last_space_in_indent = -1;
- int need_fix_leading_space = 0;
- char *buf;
-
- /*
- * Strip trailing whitespace
- */
- if ((ws_rule & WS_TRAILING_SPACE) &&
- (2 < plen && isspace(patch[plen-2]))) {
- if (patch[plen - 1] == '\n') {
- add_nl_to_tail = 1;
- plen--;
- if (1 < plen && patch[plen - 1] == '\r') {
- add_cr_to_tail = !!(ws_rule & WS_CR_AT_EOL);
- plen--;
- }
- }
- if (0 < plen && isspace(patch[plen - 1])) {
- while (0 < plen && isspace(patch[plen-1]))
- plen--;
- fixed = 1;
- }
- }
-
- /*
- * Check leading whitespaces (indent)
- */
- for (i = 0; i < plen; i++) {
- char ch = patch[i];
- if (ch == '\t') {
- last_tab_in_indent = i;
- if ((ws_rule & WS_SPACE_BEFORE_TAB) &&
- 0 <= last_space_in_indent)
- need_fix_leading_space = 1;
- } else if (ch == ' ') {
- last_space_in_indent = i;
- if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
- 8 <= i - last_tab_in_indent)
- need_fix_leading_space = 1;
- } else
- break;
- }
-
- buf = output;
- if (need_fix_leading_space) {
- /* Process indent ourselves */
- int consecutive_spaces = 0;
- int last = last_tab_in_indent + 1;
-
- if (ws_rule & WS_INDENT_WITH_NON_TAB) {
- /* have "last" point at one past the indent */
- if (last_tab_in_indent < last_space_in_indent)
- last = last_space_in_indent + 1;
- else
- last = last_tab_in_indent + 1;
- }
-
- /*
- * between patch[0..last-1], strip the funny spaces,
- * updating them to tab as needed.
- */
- for (i = 0; i < last; i++) {
- char ch = patch[i];
- if (ch != ' ') {
- consecutive_spaces = 0;
- *output++ = ch;
- } else {
- consecutive_spaces++;
- if (consecutive_spaces == 8) {
- *output++ = '\t';
- consecutive_spaces = 0;
- }
- }
- }
- while (0 < consecutive_spaces--)
- *output++ = ' ';
- plen -= last;
- patch += last;
- fixed = 1;
- }
-
- memcpy(output, patch, plen);
- if (add_cr_to_tail)
- output[plen++] = '\r';
- if (add_nl_to_tail)
- output[plen++] = '\n';
- if (fixed && count_error)
- applied_after_fixing_ws++;
- return output + plen - buf;
-}
-
static void update_pre_post_images(struct image *preimage,
struct image *postimage,
char *buf,
int match;
/* Try fixing the line in the preimage */
- fixlen = copy_wsfix(buf, orig, oldlen, ws_rule, 0);
+ fixlen = ws_fix_copy(buf, orig, oldlen, ws_rule, NULL);
/* Try fixing the line in the target */
if (sizeof(tgtfixbuf) < tgtlen)
tgtfix = tgtfixbuf;
else
tgtfix = xmalloc(tgtlen);
- tgtfixlen = copy_wsfix(tgtfix, target, tgtlen, ws_rule, 0);
+ tgtfixlen = ws_fix_copy(tgtfix, target, tgtlen, ws_rule, NULL);
/*
* If they match, either the preimage was based on
added = plen;
}
else {
- added = copy_wsfix(new, patch + 1, plen,
- ws_rule, 1);
+ added = ws_fix_copy(new, patch + 1, plen, ws_rule, &applied_after_fixing_ws);
}
add_line_info(&postimage, new, added,
(first == '+' ? 0 : LINE_COMMON));
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.
+ * A hunk to change lines at the beginning would begin with
+ * @@ -1,L +N,M @@
*
- * But that would break if the patch is generated with
- * --unified=0; sane people wouldn't do that to cause us
- * trouble, but we try to please not so sane ones as well.
+ * And a hunk to add to an empty file would begin with
+ * @@ -0,0 +N,M @@
+ *
+ * In other words, a hunk that is (frag->oldpos <= 1) with or
+ * without leading context must match at the beginning.
*/
- if (unidiff_zero) {
- match_beginning = (!leading && !frag->oldpos);
- match_end = 0;
- }
- else {
- match_beginning = !leading && (frag->oldpos == 1);
- match_end = !trailing;
- }
+ match_beginning = frag->oldpos <= 1;
+
+ /*
+ * A hunk without trailing lines must match at the end.
+ * However, we simply cannot tell if a hunk must match end
+ * from the lack of trailing lines if the patch was generated
+ * with unidiff without any context.
+ */
+ match_end = !unidiff_zero && !trailing;
pos = frag->newpos ? (frag->newpos - 1) : 0;
preimage.buf = oldlines;
if (!ce)
return 0;
- if (S_ISGITLINK(ntohl(ce->ce_mode))) {
+ if (S_ISGITLINK(ce->ce_mode)) {
strbuf_grow(buf, 100);
strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(ce->sha1));
} else {
static int verify_index_match(struct cache_entry *ce, struct stat *st)
{
- if (S_ISGITLINK(ntohl(ce->ce_mode))) {
+ if (S_ISGITLINK(ce->ce_mode)) {
if (!S_ISDIR(st->st_mode))
return -1;
return 0;
return error("%s: does not match index",
old_name);
if (cached)
- st_mode = ntohl(ce->ce_mode);
+ st_mode = ce->ce_mode;
} else if (stat_ret < 0)
return error("%s: %s", old_name, strerror(errno));
if (!cached)
- st_mode = ntohl(ce_mode_from_stat(ce, st.st_mode));
+ st_mode = ce_mode_from_stat(ce, st.st_mode);
if (patch->is_new < 0)
patch->is_new = 0;
ce = xcalloc(1, ce_size);
memcpy(ce->name, path, namelen);
ce->ce_mode = create_ce_mode(mode);
- ce->ce_flags = htons(namelen);
+ ce->ce_flags = namelen;
if (S_ISGITLINK(mode)) {
const char *s = buf;
static int git_apply_config(const char *var, const char *value)
{
if (!strcmp(var, "apply.whitespace")) {
+ if (!value)
+ return config_error_nonbool(var);
apply_default_whitespace = xstrdup(value);
return 0;
}
int read_stdin = 1;
int inaccurate_eof = 0;
int errs = 0;
- int is_not_gitdir = 0;
+ int is_not_gitdir;
const char *whitespace_option = NULL;
fd = open(arg, O_RDONLY);
if (fd < 0)
- usage(apply_usage);
+ die("can't open patch '%s': %s", arg, strerror(errno));
read_stdin = 0;
set_default_whitespace_mode(whitespace_option);
errs |= apply_patch(fd, arg, inaccurate_eof);