From: Junio C Hamano Date: Fri, 17 Oct 2008 08:52:32 +0000 (-0700) Subject: Merge branch 'maint' X-Git-Tag: v1.6.1-rc1~144 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/46dc1b0e332612aa32c139007fa33f4b429de9d1?ds=inline;hp=-c Merge branch 'maint' * maint: t1301-shared-repo.sh: don't let a default ACL interfere with the test git-check-attr(1): add output and example sections xdiff-interface.c: strip newline (and cr) from line before pattern matching t4018-diff-funcname: demonstrate end of line funcname matching flaw t4018-diff-funcname: rework negated last expression test Typo "does not exists" when git remote update remote. remote.c: correct the check for a leading '/' in a remote name Add testcase to ensure merging an early part of a branch is done properly Conflicts: t/t7600-merge.sh --- 46dc1b0e332612aa32c139007fa33f4b429de9d1 diff --combined remote.c index d5efadd93d,7688f3b04d..8a04066d61 --- a/remote.c +++ b/remote.c @@@ -69,7 -69,7 +69,7 @@@ static const char *alias_url(const cha if (!longest) return url; - ret = malloc(rewrite[longest_i]->baselen + + ret = xmalloc(rewrite[longest_i]->baselen + (strlen(url) - longest->len) + 1); strcpy(ret, rewrite[longest_i]->base); strcpy(ret + rewrite[longest_i]->baselen, url + longest->len); @@@ -152,7 -152,7 +152,7 @@@ static struct branch *make_branch(cons ret->name = xstrndup(name, len); else ret->name = xstrdup(name); - refname = malloc(strlen(name) + strlen("refs/heads/") + 1); + refname = xmalloc(strlen(name) + strlen("refs/heads/") + 1); strcpy(refname, "refs/heads/"); strcpy(refname + strlen("refs/heads/"), ret->name); ret->refname = refname; @@@ -245,7 -245,7 +245,7 @@@ static void read_branches_file(struct r { const char *slash = strchr(remote->name, '/'); char *frag; - struct strbuf branch; + struct strbuf branch = STRBUF_INIT; int n = slash ? slash - remote->name : 1000; FILE *f = fopen(git_path("branches/%.*s", n, remote->name), "r"); char *s, *p; @@@ -283,6 -283,7 +283,6 @@@ * #branch specified. The "master" (or specified) branch is * fetched and stored in the local branch of the same name. */ - strbuf_init(&branch, 0); frag = strchr(p, '#'); if (frag) { *(frag++) = '\0'; @@@ -341,13 -342,14 +341,14 @@@ static int handle_config(const char *ke if (prefixcmp(key, "remote.")) return 0; name = key + 7; + if (*name == '/') { + warning("Config remote shorthand cannot begin with '/': %s", + name); + return 0; + } subkey = strrchr(name, '.'); if (!subkey) return error("Config with no key for remote %s", name); - if (*subkey == '/') { - warning("Config remote shorthand cannot begin with '/': %s", name); - return 0; - } remote = make_remote(name, subkey - name); if (!strcmp(subkey, ".mirror")) remote->mirror = git_config_bool(key, value); @@@ -448,26 -450,6 +449,26 @@@ static int verify_refname(char *name, i return result; } +/* + * This function frees a refspec array. + * Warning: code paths should be checked to ensure that the src + * and dst pointers are always freeable pointers as well + * as the refspec pointer itself. + */ +static void free_refspecs(struct refspec *refspec, int nr_refspec) +{ + int i; + + if (!refspec) + return; + + for (i = 0; i < nr_refspec; i++) { + free(refspec[i].src); + free(refspec[i].dst); + } + free(refspec); +} + static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify) { int i; @@@ -586,12 -568,7 +587,12 @@@ invalid: if (verify) { - free(rs); + /* + * nr_refspec must be greater than zero and i must be valid + * since it is only possible to reach this point from within + * the for loop above. + */ + free_refspecs(rs, i+1); return NULL; } die("Invalid refspec '%s'", refspec[i]); @@@ -603,7 -580,7 +604,7 @@@ int valid_fetch_refspec(const char *fet struct refspec *refspec; refspec = parse_refspec_internal(1, fetch_refspec, 1, 1); - free(refspec); + free_refspecs(refspec, 1); return !!refspec; } @@@ -612,7 -589,7 +613,7 @@@ struct refspec *parse_fetch_refspec(in return parse_refspec_internal(nr_refspec, refspec, 1, 0); } -struct refspec *parse_push_refspec(int nr_refspec, const char **refspec) +static struct refspec *parse_push_refspec(int nr_refspec, const char **refspec) { return parse_refspec_internal(nr_refspec, refspec, 0, 0); } @@@ -750,7 -727,8 +751,7 @@@ int remote_find_tracking(struct remote struct ref *alloc_ref(unsigned namelen) { - struct ref *ret = xmalloc(sizeof(struct ref) + namelen); - memset(ret, 0, sizeof(struct ref) + namelen); + struct ref *ret = xcalloc(1, sizeof(struct ref) + namelen); return ret; } @@@ -781,7 -759,7 +782,7 @@@ struct ref *copy_ref_list(const struct return ret; } -void free_ref(struct ref *ref) +static void free_ref(struct ref *ref) { if (!ref) return; diff --combined t/t4018-diff-funcname.sh index 0320e19770,398bf4b5d8..be541348c6 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@@ -32,7 -32,7 +32,7 @@@ EO sed 's/beer\\/beer,\\/' < Beer.java > Beer-correct.java -builtin_patterns="bibtex java pascal ruby tex" +builtin_patterns="bibtex html java objc pascal php python ruby tex" for p in $builtin_patterns do test_expect_success "builtin $p pattern compiles" ' @@@ -65,7 -65,14 +65,14 @@@ test_expect_success 'custom pattern' test_expect_success 'last regexp must not be negated' ' git config diff.java.funcname "!static" && - test_must_fail git diff --no-index Beer.java Beer-correct.java + git diff --no-index Beer.java Beer-correct.java 2>&1 | + grep "fatal: Last expression must not be negated:" + ' + + test_expect_success 'pattern which matches to end of line' ' + git config diff.java.funcname "Beer$" && + git diff --no-index Beer.java Beer-correct.java | + grep "^@@.*@@ Beer" ' test_expect_success 'alternation in pattern' ' diff --combined t/t7600-merge.sh index 7313ac278c,5abce3119b..3a36a95b9a --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@@ -230,10 -230,6 +230,10 @@@ test_expect_success 'test option parsin test_must_fail git merge ' +test_expect_success 'reject non-strategy with a git-merge-foo name' ' + test_must_fail git merge -s index c1 +' + test_expect_success 'merge c0 with c1' ' git reset --hard c0 && git merge c1 && @@@ -511,13 -507,30 +511,37 @@@ test_expect_success 'in-index merge' test_debug 'gitk --all' +test_expect_success 'refresh the index before merging' ' + git reset --hard c1 && + sleep 1 && + touch file && + git merge c3 +' + + cat >expected < c4.c && + git add c4.c && + git commit -m c4 && + git tag c4 && + echo c5 > c5.c && + git add c5.c && + git commit -m c5 && + git tag c5 && + git reset --hard c3 && + echo c6 > c6.c && + git add c6.c && + git commit -m c6 && + git tag c6 && + git merge c5~1 && + git show -s --pretty=format:%s HEAD > actual && + test_cmp actual expected + ' + test_debug 'gitk --all' test_done diff --combined xdiff-interface.c index f3f6db3297,3bf83f81e3..49e06af710 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@@ -1,12 -1,5 +1,12 @@@ #include "cache.h" #include "xdiff-interface.h" +#include "strbuf.h" + +struct xdiff_emit_state { + xdiff_emit_consume_fn consume; + void *consume_callback_data; + struct strbuf remainder; +}; static int parse_num(char **cp_p, int *num_p) { @@@ -62,13 -55,13 +62,13 @@@ static void consume_one(void *priv_, ch unsigned long this_size; ep = memchr(s, '\n', size); this_size = (ep == NULL) ? size : (ep - s + 1); - priv->consume(priv, s, this_size); + priv->consume(priv->consume_callback_data, s, this_size); size -= this_size; s += this_size; } } -int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) +static int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) { struct xdiff_emit_state *priv = priv_; int i; @@@ -76,22 -69,36 +76,22 @@@ for (i = 0; i < nbuf; i++) { if (mb[i].ptr[mb[i].size-1] != '\n') { /* Incomplete line */ - priv->remainder = xrealloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - priv->remainder_size += mb[i].size; + strbuf_add(&priv->remainder, mb[i].ptr, mb[i].size); continue; } /* we have a complete line */ - if (!priv->remainder) { + if (!priv->remainder.len) { consume_one(priv, mb[i].ptr, mb[i].size); continue; } - priv->remainder = xrealloc(priv->remainder, - priv->remainder_size + - mb[i].size); - memcpy(priv->remainder + priv->remainder_size, - mb[i].ptr, mb[i].size); - consume_one(priv, priv->remainder, - priv->remainder_size + mb[i].size); - free(priv->remainder); - priv->remainder = NULL; - priv->remainder_size = 0; + strbuf_add(&priv->remainder, mb[i].ptr, mb[i].size); + consume_one(priv, priv->remainder.buf, priv->remainder.len); + strbuf_reset(&priv->remainder); } - if (priv->remainder) { - consume_one(priv, priv->remainder, priv->remainder_size); - free(priv->remainder); - priv->remainder = NULL; - priv->remainder_size = 0; + if (priv->remainder.len) { + consume_one(priv, priv->remainder.buf, priv->remainder.len); + strbuf_reset(&priv->remainder); } return 0; } @@@ -134,25 -141,6 +134,25 @@@ int xdi_diff(mmfile_t *mf1, mmfile_t *m return xdl_diff(&a, &b, xpp, xecfg, xecb); } +int xdi_diff_outf(mmfile_t *mf1, mmfile_t *mf2, + xdiff_emit_consume_fn fn, void *consume_callback_data, + xpparam_t const *xpp, + xdemitconf_t const *xecfg, xdemitcb_t *xecb) +{ + int ret; + struct xdiff_emit_state state; + + memset(&state, 0, sizeof(state)); + state.consume = fn; + state.consume_callback_data = consume_callback_data; + xecb->outf = xdiff_outf; + xecb->priv = &state; + strbuf_init(&state.remainder, 0); + ret = xdi_diff(mf1, mf2, xpp, xecfg, xecb); + strbuf_release(&state.remainder); + return ret; +} + int read_mmfile(mmfile_t *ptr, const char *filename) { struct stat st; @@@ -194,11 -182,10 +194,21 @@@ static long ff_regexp(const char *line char *line_buffer; struct ff_regs *regs = priv; regmatch_t pmatch[2]; - int result = 0, i; + int i; + int result = -1; + + /* Exclude terminating newline (and cr) from matching */ + if (len > 0 && line[len-1] == '\n') { ++ if (len > 1 && line[len-2] == '\r') ++ len -= 2; ++ else ++ len--; ++ } ++ ++ line_buffer = xstrndup(line, len); /* make NUL terminated */ + + /* Exclude terminating newline (and cr) from matching */ + if (len > 0 && line[len-1] == '\n') { if (len > 1 && line[len-2] == '\r') len -= 2; else @@@ -209,24 -196,22 +219,24 @@@ for (i = 0; i < regs->nr; i++) { struct ff_reg *reg = regs->array + i; - if (reg->negate ^ !!regexec(®->re, - line_buffer, 2, pmatch, 0)) { - free(line_buffer); - return -1; + if (!regexec(®->re, line_buffer, 2, pmatch, 0)) { + if (reg->negate) + goto fail; + break; } } + if (regs->nr <= i) + goto fail; i = pmatch[1].rm_so >= 0 ? 1 : 0; line += pmatch[i].rm_so; result = pmatch[i].rm_eo - pmatch[i].rm_so; if (result > buffer_size) result = buffer_size; else - while (result > 0 && (isspace(line[result - 1]) || - line[result - 1] == '\n')) + while (result > 0 && (isspace(line[result - 1]))) result--; memcpy(buffer, line, result); + fail: free(line_buffer); return result; } @@@ -262,23 -247,3 +272,23 @@@ void xdiff_set_find_func(xdemitconf_t * value = ep + 1; } } + +int git_xmerge_style = -1; + +int git_xmerge_config(const char *var, const char *value, void *cb) +{ + if (!strcasecmp(var, "merge.conflictstyle")) { + if (!value) + die("'%s' is not a boolean", var); + if (!strcmp(value, "diff3")) + git_xmerge_style = XDL_MERGE_DIFF3; + else if (!strcmp(value, "merge")) + git_xmerge_style = 0; + else + die("unknown style '%s' given for '%s'", + value, var); + return 0; + } + return git_default_config(var, value, cb); +} +