static int line_termination = '\n';
static unsigned long p_context = ULONG_MAX;
static const char apply_usage[] =
-"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>...";
+"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|fix|error|error-all>] <patch>...";
static enum ws_error_action {
nowarn_ws_error,
unsigned int old_mode, new_mode;
int is_new, is_delete; /* -1 = unknown, 0 = false, 1 = true */
int rejected;
+ unsigned ws_rule;
unsigned long deflate_origlen;
int lines_added, lines_deleted;
int score;
}
}
}
- return NULL;
}
/* Verify that we recognize the lines following a git header */
return -1;
}
-static void check_whitespace(const char *line, int len)
+static void check_whitespace(const char *line, int len, unsigned ws_rule)
{
- const char *err = "Adds trailing whitespace";
- int seen_space = 0;
- int i;
-
- /*
- * We know len is at least two, since we have a '+' and we
- * checked that the last character was a '\n' before calling
- * this function. That is, an addition of an empty line would
- * check the '+' here. Sneaky...
- */
- if ((whitespace_rule & WS_TRAILING_SPACE) && isspace(line[len-2]))
- goto error;
-
- /*
- * Make sure that there is no space followed by a tab in
- * indentation.
- */
- if (whitespace_rule & WS_SPACE_BEFORE_TAB) {
- err = "Space in indent is followed by a tab";
- for (i = 1; i < len; i++) {
- if (line[i] == '\t') {
- if (seen_space)
- goto error;
- }
- else if (line[i] == ' ')
- seen_space = 1;
- else
- break;
- }
- }
-
- /*
- * Make sure that the indentation does not contain more than
- * 8 spaces.
- */
- if ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
- (8 < len) && !strncmp("+ ", line, 9)) {
- err = "Indent more than 8 places with spaces";
- goto error;
- }
- return;
+ char *err;
+ unsigned result = check_and_emit_line(line + 1, len - 1, ws_rule,
+ NULL, NULL, NULL, NULL);
+ if (!result)
+ return;
- error:
whitespace_error++;
if (squelch_whitespace_errors &&
squelch_whitespace_errors < whitespace_error)
;
- else
- fprintf(stderr, "%s.\n%s:%d:%.*s\n",
- err, patch_input_file, linenr, len-2, line+1);
+ else {
+ err = whitespace_error_string(result);
+ fprintf(stderr, "%s:%d: %s.\n%.*s\n",
+ patch_input_file, linenr, err, len - 2, line + 1);
+ free(err);
+ }
}
/*
case '-':
if (apply_in_reverse &&
ws_error_action != nowarn_ws_error)
- check_whitespace(line, len);
+ check_whitespace(line, len, patch->ws_rule);
deleted++;
oldlines--;
trailing = 0;
case '+':
if (!apply_in_reverse &&
ws_error_action != nowarn_ws_error)
- check_whitespace(line, len);
+ check_whitespace(line, len, patch->ws_rule);
added++;
newlines--;
trailing = 0;
if (offset < 0)
return offset;
+ patch->ws_rule = whitespace_rule(patch->new_name
+ ? patch->new_name
+ : patch->old_name);
+
patchsize = parse_single_patch(buffer + offset + hdrsize,
size - offset - hdrsize, patch);
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;
*rsize = offset + 1;
}
-static int apply_line(char *output, const char *patch, int plen)
+static int apply_line(char *output, const char *patch, int plen,
+ unsigned ws_rule)
{
/*
* plen is number of bytes to be copied from patch,
int i;
int add_nl_to_tail = 0;
int fixed = 0;
- int last_tab_in_indent = -1;
- int last_space_in_indent = -1;
+ int last_tab_in_indent = 0;
+ int last_space_in_indent = 0;
int need_fix_leading_space = 0;
char *buf;
/*
* Strip trailing whitespace
*/
- if ((whitespace_rule & WS_TRAILING_SPACE) &&
+ if ((ws_rule & WS_TRAILING_SPACE) &&
(1 < plen && isspace(patch[plen-1]))) {
if (patch[plen] == '\n')
add_nl_to_tail = 1;
char ch = patch[i];
if (ch == '\t') {
last_tab_in_indent = i;
- if ((whitespace_rule & WS_SPACE_BEFORE_TAB) &&
- 0 <= last_space_in_indent)
+ 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 ((whitespace_rule & WS_INDENT_WITH_NON_TAB) &&
- last_tab_in_indent < 0 &&
- 8 <= i)
+ if ((ws_rule & WS_INDENT_WITH_NON_TAB) &&
+ 8 <= i - last_tab_in_indent)
need_fix_leading_space = 1;
}
else
int consecutive_spaces = 0;
int last = last_tab_in_indent + 1;
- if (whitespace_rule & WS_INDENT_WITH_NON_TAB) {
+ 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;
}
static int apply_one_fragment(struct strbuf *buf, struct fragment *frag,
- int inaccurate_eof)
+ int inaccurate_eof, unsigned ws_rule)
{
int match_beginning, match_end;
const char *patch = frag->patch;
case '+':
if (first != '+' || !no_add) {
int added = apply_line(new + newsize, patch,
- plen);
+ plen, ws_rule);
newsize += added;
if (first == '+' &&
added == 1 && new[newsize-1] == '\n')
{
struct fragment *frag = patch->fragments;
const char *name = patch->old_name ? patch->old_name : patch->new_name;
+ unsigned ws_rule = patch->ws_rule;
+ unsigned inaccurate_eof = patch->inaccurate_eof;
if (patch->is_binary)
return apply_binary(buf, patch);
while (frag) {
- if (apply_one_fragment(buf, frag, patch->inaccurate_eof)) {
+ if (apply_one_fragment(buf, frag, inaccurate_eof, ws_rule)) {
error("patch failed: %s:%ld", name, frag->oldpos);
if (!apply_with_reject)
return -1;
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 ce_match_stat(ce, st, 1);
+ return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID);
}
static int check_patch(struct patch *patch, struct patch *prev_patch)
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;
}
whitespace_error,
whitespace_error == 1 ? "" : "s",
whitespace_error == 1 ? "s" : "");
- if (applied_after_fixing_ws)
+ if (applied_after_fixing_ws && apply)
fprintf(stderr, "warning: %d line%s applied after"
" fixing whitespace errors.\n",
applied_after_fixing_ws,
if (update_index) {
if (write_cache(newfd, active_cache, active_nr) ||
- close(newfd) || commit_locked_index(&lock_file))
+ commit_locked_index(&lock_file))
die("Unable to write new index file");
}