From: Junio C Hamano Date: Wed, 5 Apr 2006 00:15:02 +0000 (-0700) Subject: Merge branch 'pb/regex' into next X-Git-Tag: v1.3.0-rc4~42 X-Git-Url: https://git.octo.it/?a=commitdiff_plain;h=afb28f239ff677cc57fc5dad47c2104537aff922;hp=46b8dec038be1125153e9fc816a1e1f0a9d2de77;p=git.git Merge branch 'pb/regex' into next * pb/regex: On some platforms, certain headers need to be included before regex.h --- diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 4764fd25..d2200acd 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.3-rc1.GIT +DEF_VER=v1.3-rc2.GIT # First try git-describe, then see if there is a version file # (included in release tarballs), then default diff --git a/Makefile b/Makefile index c79d6462..145099ad 100644 --- a/Makefile +++ b/Makefile @@ -510,6 +510,9 @@ git$X git.spec \ exec_cmd.o: exec_cmd.c $(CC) -o $*.o -c $(ALL_CFLAGS) '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' $< +http.o: http.c + $(CC) -o $*.o -c $(ALL_CFLAGS) -DGIT_USER_AGENT='"git/$(GIT_VERSION)"' $< + git-%$X: %.o $(GITLIBS) $(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) diff --git a/combine-diff.c b/combine-diff.c index 7693884f..11f5143e 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -4,6 +4,7 @@ #include "diff.h" #include "diffcore.h" #include "quote.h" +#include "xdiff/xdiff.h" static int uninteresting(struct diff_filepair *p) { @@ -110,28 +111,6 @@ static char *grab_blob(const unsigned char *sha1, unsigned long *size) return blob; } -#define TMPPATHLEN 50 -#define MAXLINELEN 10240 - -static void write_to_temp_file(char *tmpfile, void *blob, unsigned long size) -{ - int fd = git_mkstemp(tmpfile, TMPPATHLEN, ".diff_XXXXXX"); - if (fd < 0) - die("unable to create temp-file"); - if (write(fd, blob, size) != size) - die("unable to write temp-file"); - close(fd); -} - -static void write_temp_blob(char *tmpfile, const unsigned char *sha1) -{ - unsigned long size; - void *blob; - blob = grab_blob(sha1, &size); - write_to_temp_file(tmpfile, blob, size); - free(blob); -} - static int parse_num(char **cp_p, unsigned int *num_p) { char *cp = *cp_p; @@ -178,10 +157,9 @@ static int parse_hunk_header(char *line, int len, return -!!memcmp(cp, " @@", 3); } -static void append_lost(struct sline *sline, int n, const char *line) +static void append_lost(struct sline *sline, int n, const char *line, int len) { struct lline *lline; - int len = strlen(line); unsigned long this_mask = (1UL<lost_tail = &lline->next; } -static void combine_diff(const unsigned char *parent, const char *ourtmp, +struct combine_diff_state { + char *remainder; + unsigned long remainder_size; + unsigned int lno, ob, on, nb, nn; + unsigned long nmask; + int num_parent; + int n; + struct sline *sline; + struct sline *lost_bucket; +}; + +static void consume_line(struct combine_diff_state *state, + char *line, + unsigned long len) +{ + if (5 < len && !memcmp("@@ -", line, 4)) { + if (parse_hunk_header(line, len, + &state->ob, &state->on, + &state->nb, &state->nn)) + return; + state->lno = state->nb; + if (!state->nb) + /* @@ -1,2 +0,0 @@ to remove the + * first two lines... + */ + state->nb = 1; + if (state->nn == 0) + /* @@ -X,Y +N,0 @@ removed Y lines + * that would have come *after* line N + * in the result. Our lost buckets hang + * to the line after the removed lines, + */ + state->lost_bucket = &state->sline[state->nb]; + else + state->lost_bucket = &state->sline[state->nb-1]; + if (!state->sline[state->nb-1].p_lno) + state->sline[state->nb-1].p_lno = + xcalloc(state->num_parent, + sizeof(unsigned long)); + state->sline[state->nb-1].p_lno[state->n] = state->ob; + return; + } + if (!state->lost_bucket) + return; /* not in any hunk yet */ + switch (line[0]) { + case '-': + append_lost(state->lost_bucket, state->n, line+1, len-1); + break; + case '+': + state->sline[state->lno-1].flag |= state->nmask; + state->lno++; + break; + } +} + +static int combine_diff_outf(void *priv_, mmbuffer_t *mb, int nbuf) +{ + struct combine_diff_state *priv = priv_; + int i; + for (i = 0; i < nbuf; i++) { + if (mb[i].ptr[mb[i].size-1] != '\n') { + /* Incomplete line */ + priv->remainder = realloc(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; + continue; + } + + /* we have a complete line */ + if (!priv->remainder) { + consume_line(priv, mb[i].ptr, mb[i].size); + continue; + } + priv->remainder = realloc(priv->remainder, + priv->remainder_size + + mb[i].size); + memcpy(priv->remainder + priv->remainder_size, + mb[i].ptr, mb[i].size); + consume_line(priv, priv->remainder, + priv->remainder_size + mb[i].size); + free(priv->remainder); + priv->remainder = NULL; + priv->remainder_size = 0; + } + return 0; +} + +static void combine_diff(const unsigned char *parent, mmfile_t *result_file, struct sline *sline, int cnt, int n, int num_parent) { - FILE *in; - char parent_tmp[TMPPATHLEN]; - char cmd[TMPPATHLEN * 2 + 1024]; - char line[MAXLINELEN]; - unsigned int lno, ob, on, nb, nn, p_lno; + unsigned int p_lno, lno; unsigned long nmask = (1UL << n); - struct sline *lost_bucket = NULL; + xpparam_t xpp; + xdemitconf_t xecfg; + mmfile_t parent_file; + xdemitcb_t ecb; + struct combine_diff_state state; + unsigned long sz; if (!cnt) return; /* result deleted */ - write_temp_blob(parent_tmp, parent); - sprintf(cmd, "diff --unified=0 -La/x -Lb/x '%s' '%s'", - parent_tmp, ourtmp); - in = popen(cmd, "r"); - if (!in) - die("cannot spawn %s", cmd); - - lno = 1; - while (fgets(line, sizeof(line), in) != NULL) { - int len = strlen(line); - if (5 < len && !memcmp("@@ -", line, 4)) { - if (parse_hunk_header(line, len, - &ob, &on, &nb, &nn)) - break; - lno = nb; - if (!nb) - /* @@ -1,2 +0,0 @@ to remove the - * first two lines... - */ - nb = 1; - if (nn == 0) - /* @@ -X,Y +N,0 @@ removed Y lines - * that would have come *after* line N - * in the result. Our lost buckets hang - * to the line after the removed lines, - */ - lost_bucket = &sline[nb]; - else - lost_bucket = &sline[nb-1]; - if (!sline[nb-1].p_lno) - sline[nb-1].p_lno = - xcalloc(num_parent, - sizeof(unsigned long)); - sline[nb-1].p_lno[n] = ob; - continue; - } - if (!lost_bucket) - continue; /* not in any hunk yet */ - switch (line[0]) { - case '-': - append_lost(lost_bucket, n, line+1); - break; - case '+': - sline[lno-1].flag |= nmask; - lno++; - break; - } - } - fclose(in); - unlink(parent_tmp); + parent_file.ptr = grab_blob(parent, &sz); + parent_file.size = sz; + xpp.flags = XDF_NEED_MINIMAL; + xecfg.ctxlen = 0; + xecfg.flags = 0; + ecb.outf = combine_diff_outf; + ecb.priv = &state; + memset(&state, 0, sizeof(state)); + state.nmask = nmask; + state.sline = sline; + state.lno = 1; + state.num_parent = num_parent; + state.n = n; + + xdl_diff(&parent_file, result_file, &xpp, &xecfg, &ecb); + if (state.remainder && state.remainder_size) + consume_line(&state, state.remainder, state.remainder_size); + free(state.remainder); + free(parent_file.ptr); /* Assign line numbers for this parent. * @@ -625,61 +663,56 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, int dense, const char *header, struct diff_options *opt) { - unsigned long size, cnt, lno; + unsigned long result_size, cnt, lno; char *result, *cp, *ep; struct sline *sline; /* survived lines */ int mode_differs = 0; int i, show_hunks, shown_header = 0; - char ourtmp_buf[TMPPATHLEN]; - char *ourtmp = ourtmp_buf; int working_tree_file = !memcmp(elem->sha1, null_sha1, 20); int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV; + mmfile_t result_file; /* Read the result of merge first */ - if (!working_tree_file) { - result = grab_blob(elem->sha1, &size); - write_to_temp_file(ourtmp, result, size); - } + if (!working_tree_file) + result = grab_blob(elem->sha1, &result_size); else { /* Used by diff-tree to read from the working tree */ struct stat st; int fd; - ourtmp = elem->path; - if (0 <= (fd = open(ourtmp, O_RDONLY)) && + if (0 <= (fd = open(elem->path, O_RDONLY)) && !fstat(fd, &st)) { int len = st.st_size; int cnt = 0; elem->mode = canon_mode(st.st_mode); - size = len; + result_size = len; result = xmalloc(len + 1); while (cnt < len) { int done = xread(fd, result+cnt, len-cnt); if (done == 0) break; if (done < 0) - die("read error '%s'", ourtmp); + die("read error '%s'", elem->path); cnt += done; } result[len] = 0; } else { /* deleted file */ - size = 0; + result_size = 0; elem->mode = 0; result = xmalloc(1); result[0] = 0; - ourtmp = "/dev/null"; } if (0 <= fd) close(fd); } - for (cnt = 0, cp = result; cp - result < size; cp++) { + for (cnt = 0, cp = result; cp - result < result_size; cp++) { if (*cp == '\n') cnt++; } - if (size && result[size-1] != '\n') + if (result_size && result[result_size-1] != '\n') cnt++; /* incomplete line */ sline = xcalloc(cnt+1, sizeof(*sline)); @@ -689,7 +722,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, sline[lno].lost_tail = &sline[lno].lost_head; sline[lno].flag = 0; } - for (lno = 0, cp = result; cp - result < size; cp++) { + for (lno = 0, cp = result; cp - result < result_size; cp++) { if (*cp == '\n') { sline[lno].len = cp - sline[lno].bol; lno++; @@ -697,8 +730,11 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, sline[lno].bol = cp + 1; } } - if (size && result[size-1] != '\n') - sline[cnt-1].len = size - (sline[cnt-1].bol - result); + if (result_size && result[result_size-1] != '\n') + sline[cnt-1].len = result_size - (sline[cnt-1].bol - result); + + result_file.ptr = result; + result_file.size = result_size; sline[0].p_lno = xcalloc((cnt+1) * num_parent, sizeof(unsigned long)); for (lno = 0; lno < cnt; lno++) @@ -714,7 +750,7 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, } } if (i <= j) - combine_diff(elem->parent[i].sha1, ourtmp, sline, + combine_diff(elem->parent[i].sha1, &result_file, sline, cnt, i, num_parent); if (elem->parent[i].mode != elem->mode) mode_differs = 1; @@ -767,8 +803,6 @@ static int show_patch_diff(struct combine_diff_path *elem, int num_parent, } dump_sline(sline, cnt, num_parent); } - if (ourtmp == ourtmp_buf) - unlink(ourtmp); free(result); for (i = 0; i < cnt; i++) { diff --git a/git-clone.sh b/git-clone.sh index 823c74b9..c013e481 100755 --- a/git-clone.sh +++ b/git-clone.sh @@ -52,7 +52,8 @@ Perhaps git-update-server-info needs to be run there?" git-http-fetch -v -a -w "$tname" "$name" "$1/" || exit 1 done <"$clone_tmp/refs" rm -fr "$clone_tmp" - http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" + http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" || + rm -f "$GIT_DIR/REMOTE_HEAD" } # Read git-fetch-pack -k output and store the remote branches. @@ -324,7 +325,7 @@ test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp" if test -f "$GIT_DIR/CLONE_HEAD" then - # Figure out where the remote HEAD points at. + # Read git-fetch-pack -k output and store the remote branches. perl -e "$copy_refs" "$GIT_DIR" "$use_separate_remote" "$origin" fi @@ -332,22 +333,25 @@ cd "$D" || exit if test -z "$bare" && test -f "$GIT_DIR/REMOTE_HEAD" then - head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` # Figure out which remote branch HEAD points at. case "$use_separate_remote" in '') remote_top=refs/heads ;; *) remote_top="refs/remotes/$origin" ;; esac - # What to use to track the remote primary branch - if test -n "$use_separate_remote" - then - origin_tracking="remotes/$origin/master" - else - origin_tracking="heads/$origin" - fi + head_sha1=`cat "$GIT_DIR/REMOTE_HEAD"` + case "$head_sha1" in + 'ref: refs/'*) + # Uh-oh, the remote told us (http transport done against + # new style repository with a symref HEAD). + # Ideally we should skip the guesswork but for now + # opt for minimum change. + head_sha1=`expr "$head_sha1" : 'ref: refs/heads/\(.*\)'` + head_sha1=`cat "$GIT_DIR/$remote_top/$head_sha1"` + ;; + esac - # The name under $remote_top the remote HEAD seems to point at + # The name under $remote_top the remote HEAD seems to point at. head_points_at=$( ( echo "master" @@ -368,23 +372,28 @@ then ) ) - # Write out remotes/$origin file. + # Write out remotes/$origin file, and update our "$head_points_at". case "$head_points_at" in ?*) mkdir -p "$GIT_DIR/remotes" && - echo >"$GIT_DIR/remotes/$origin" \ - "URL: $repo -Pull: refs/heads/$head_points_at:refs/$origin_tracking" && + git-symbolic-ref HEAD "refs/heads/$head_points_at" && case "$use_separate_remote" in - t) git-update-ref HEAD "$head_sha1" ;; - *) git-update-ref "refs/heads/$origin" $(git-rev-parse HEAD) ;; + t) origin_track="$remote_top/$head_points_at" + git-update-ref HEAD "$head_sha1" ;; + *) origin_track="$remote_top/$origin" + git-update-ref "refs/heads/$origin" "$head_sha1" ;; esac && + echo >"$GIT_DIR/remotes/$origin" \ + "URL: $repo +Pull: refs/heads/$head_points_at:$origin_track" && (cd "$GIT_DIR/$remote_top" && find . -type f -print) | while read dotslref do name=`expr "$dotslref" : './\(.*\)'` && - test "$head_points_at" = "$name" || - test "$origin" = "$name" || + test "$use_separate_remote" = '' && { + test "$head_points_at" = "$name" || + test "$origin" = "$name" + } || echo "Pull: refs/heads/${name}:$remote_top/${name}" done >>"$GIT_DIR/remotes/$origin" && case "$use_separate_remote" in diff --git a/git-ls-remote.sh b/git-ls-remote.sh index 2c9a588d..b6882a90 100755 --- a/git-ls-remote.sh +++ b/git-ls-remote.sh @@ -53,7 +53,7 @@ http://* | https://* ) if [ -n "$GIT_SSL_NO_VERIFY" ]; then curl_extra_args="-k" fi - curl -nsf $curl_extra_args "$peek_repo/info/refs" || + curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" || echo "failed slurping" ;; diff --git a/http.c b/http.c index 9604e332..0cb42a85 100644 --- a/http.c +++ b/http.c @@ -195,6 +195,8 @@ static CURL* get_curl_handle(void) if (getenv("GIT_CURL_VERBOSE")) curl_easy_setopt(result, CURLOPT_VERBOSE, 1); + curl_easy_setopt(result, CURLOPT_USERAGENT, GIT_USER_AGENT); + return result; } diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 8ea04837..e81bca63 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -349,12 +349,7 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, kvdf += xe->xdf2.nreff + 1; kvdb += xe->xdf2.nreff + 1; - /* - * Classical integer square root approximation using shifts. - */ - xenv.mxcost = 1; - for (; ndiags; ndiags >>= 2) - xenv.mxcost <<= 1; + xenv.mxcost = xdl_bogosqrt(ndiags); if (xenv.mxcost < XDL_MAX_COST_MIN) xenv.mxcost = XDL_MAX_COST_MIN; xenv.snake_cnt = XDL_SNAKE_CNT; diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index 27a08791..add5a75c 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -25,6 +25,7 @@ #define XDL_KPDIS_RUN 4 +#define XDL_MAX_EQLIMIT 1024 @@ -305,26 +306,48 @@ void xdl_free_env(xdfenv_t *xe) { static int xdl_clean_mmatch(char const *dis, long i, long s, long e) { - long r, rdis, rpdis; - - for (r = 1, rdis = 0, rpdis = 1; (i - r) >= s; r++) { + long r, rdis0, rpdis0, rdis1, rpdis1; + + /* + * Scans the lines before 'i' to find a run of lines that either + * have no match (dis[j] == 0) or have multiple matches (dis[j] > 1). + * Note that we always call this function with dis[i] > 1, so the + * current line (i) is already a multimatch line. + */ + for (r = 1, rdis0 = 0, rpdis0 = 1; (i - r) >= s; r++) { if (!dis[i - r]) - rdis++; + rdis0++; else if (dis[i - r] == 2) - rpdis++; + rpdis0++; else break; } - for (r = 1; (i + r) <= e; r++) { + /* + * If the run before the line 'i' found only multimatch lines, we + * return 0 and hence we don't make the current line (i) discarded. + * We want to discard multimatch lines only when they appear in the + * middle of runs with nomatch lines (dis[j] == 0). + */ + if (rdis0 == 0) + return 0; + for (r = 1, rdis1 = 0, rpdis1 = 1; (i + r) <= e; r++) { if (!dis[i + r]) - rdis++; + rdis1++; else if (dis[i + r] == 2) - rpdis++; + rpdis1++; else break; } - - return rpdis * XDL_KPDIS_RUN < (rpdis + rdis); + /* + * If the run after the line 'i' found only multimatch lines, we + * return 0 and hence we don't make the current line (i) discarded. + */ + if (rdis1 == 0) + return 0; + rdis1 += rdis0; + rpdis1 += rpdis0; + + return rpdis1 * XDL_KPDIS_RUN < (rpdis1 + rdis1); } @@ -334,34 +357,40 @@ static int xdl_clean_mmatch(char const *dis, long i, long s, long e) { * might be potentially discarded if they happear in a run of discardable. */ static int xdl_cleanup_records(xdfile_t *xdf1, xdfile_t *xdf2) { - long i, rhi, nreff; + long i, nm, rhi, nreff, mlim; unsigned long hav; xrecord_t **recs; xrecord_t *rec; char *dis, *dis1, *dis2; - if (!(dis = (char *) xdl_malloc((xdf1->nrec + xdf2->nrec + 2) * sizeof(char)))) { + if (!(dis = (char *) xdl_malloc(xdf1->nrec + xdf2->nrec + 2))) { return -1; } - memset(dis, 0, (xdf1->nrec + xdf2->nrec + 2) * sizeof(char)); + memset(dis, 0, xdf1->nrec + xdf2->nrec + 2); dis1 = dis; dis2 = dis1 + xdf1->nrec + 1; + if ((mlim = xdl_bogosqrt(xdf1->nrec)) > XDL_MAX_EQLIMIT) + mlim = XDL_MAX_EQLIMIT; for (i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; i <= xdf1->dend; i++, recs++) { hav = (*recs)->ha; rhi = (long) XDL_HASHLONG(hav, xdf2->hbits); - for (rec = xdf2->rhash[rhi]; rec; rec = rec->next) - if (rec->ha == hav && ++dis1[i] == 2) + for (nm = 0, rec = xdf2->rhash[rhi]; rec; rec = rec->next) + if (rec->ha == hav && ++nm == mlim) break; + dis1[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1; } + if ((mlim = xdl_bogosqrt(xdf2->nrec)) > XDL_MAX_EQLIMIT) + mlim = XDL_MAX_EQLIMIT; for (i = xdf2->dstart, recs = &xdf2->recs[xdf2->dstart]; i <= xdf2->dend; i++, recs++) { hav = (*recs)->ha; rhi = (long) XDL_HASHLONG(hav, xdf1->hbits); - for (rec = xdf1->rhash[rhi]; rec; rec = rec->next) - if (rec->ha == hav && ++dis2[i] == 2) + for (nm = 0, rec = xdf1->rhash[rhi]; rec; rec = rec->next) + if (rec->ha == hav && ++nm == mlim) break; + dis2[i] = (nm == 0) ? 0: (nm >= mlim) ? 2: 1; } for (nreff = 0, i = xdf1->dstart, recs = &xdf1->recs[xdf1->dstart]; diff --git a/xdiff/xutils.c b/xdiff/xutils.c index afaada1e..21ab8e7e 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -29,6 +29,19 @@ +long xdl_bogosqrt(long n) { + long i; + + /* + * Classical integer square root approximation using shifts. + */ + for (i = 1; n > 0; n >>= 2) + i <<= 1; + + return i; +} + + int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, xdemitcb_t *ecb) { mmbuffer_t mb[3]; @@ -244,7 +257,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, memcpy(buf, "@@ -", 4); nb += 4; - nb += xdl_num_out(buf + nb, c1 ? s1: 0); + nb += xdl_num_out(buf + nb, c1 ? s1: s1 - 1); if (c1 != 1) { memcpy(buf + nb, ",", 1); @@ -256,7 +269,7 @@ int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, memcpy(buf + nb, " +", 2); nb += 2; - nb += xdl_num_out(buf + nb, c2 ? s2: 0); + nb += xdl_num_out(buf + nb, c2 ? s2: s2 - 1); if (c2 != 1) { memcpy(buf + nb, ",", 1); diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 55b0d39f..ea38ee90 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -24,6 +24,7 @@ #define XUTILS_H +long xdl_bogosqrt(long n); int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize, xdemitcb_t *ecb); int xdl_cha_init(chastore_t *cha, long isize, long icount);