From: Junio C Hamano Date: Mon, 26 Jun 2006 21:36:02 +0000 (-0700) Subject: Merge branch 'jc/diff' X-Git-Tag: v1.4.1-rc2~19 X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=commitdiff_plain;h=6a0dbb8a5c41770c2280de15c3202970c6515ccc;hp=801235c5e6bff0ec1c4e41c9d46535ead3b693c1;p=git.git Merge branch 'jc/diff' * jc/diff: diff --color: use $GIT_DIR/config --- diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 7b810dfda..62a8e7f22 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -16,7 +16,7 @@ SYNOPSIS [-n] [-l | --files-with-matches] [-L | --files-without-match] [-c | --count] [-A ] [-B ] [-C ] - [-f ] [-e ] + [-f ] [-e] [...] [--] [...] @@ -71,6 +71,11 @@ OPTIONS -f :: Read patterns from , one per line. +-e:: + The next parameter is the pattern. This option has to be + used for patterns starting with - and should be used in + scripts passing user input to grep. + `...`:: Search blobs in the trees for specified patterns. diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index c339c4525..9d7bcaa38 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -108,7 +108,6 @@ OPTIONS --skip:: Restart the rebasing process by skipping the current patch. - This does not work with the --merge option. --merge:: Use merging strategies to rebase. When the recursive (default) merge diff --git a/connect.c b/connect.c index db7342e4d..66e78a290 100644 --- a/connect.c +++ b/connect.c @@ -8,6 +8,7 @@ #include #include #include +#include static char *server_capabilities = NULL; diff --git a/diff.c b/diff.c index e73c0c300..fbb6c26cd 100644 --- a/diff.c +++ b/diff.c @@ -743,7 +743,7 @@ static void builtin_diff(const char *name_a, memset(&ecbdata, 0, sizeof(ecbdata)); ecbdata.label_path = lbl; ecbdata.color_diff = o->color_diff; - xpp.flags = XDF_NEED_MINIMAL; + xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; xecfg.flags = XDL_EMIT_FUNCNAMES; if (!diffopts) @@ -768,6 +768,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, struct diff_filespec *one, struct diff_filespec *two, struct diffstat_t *diffstat, + struct diff_options *o, int complete_rewrite) { mmfile_t mf1, mf2; @@ -797,7 +798,7 @@ static void builtin_diffstat(const char *name_a, const char *name_b, xdemitconf_t xecfg; xdemitcb_t ecb; - xpp.flags = XDF_NEED_MINIMAL; + xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = 0; xecfg.flags = 0; ecb.outf = xdiff_outf; @@ -1382,7 +1383,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o, if (DIFF_PAIR_UNMERGED(p)) { /* unmerged */ - builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, 0); + builtin_diffstat(p->one->path, NULL, NULL, NULL, diffstat, o, 0); return; } @@ -1394,7 +1395,7 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o, if (p->status == DIFF_STATUS_MODIFIED && p->score) complete_rewrite = 1; - builtin_diffstat(name, other, p->one, p->two, diffstat, complete_rewrite); + builtin_diffstat(name, other, p->one, p->two, diffstat, o, complete_rewrite); } static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) @@ -1600,6 +1601,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) } else if (!strcmp(arg, "--color")) options->color_diff = 1; + else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space")) + options->xdl_opts |= XDF_IGNORE_WHITESPACE; + else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change")) + options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE; else return 0; return 1; diff --git a/diff.h b/diff.h index de9de574e..b61fdc8f1 100644 --- a/diff.h +++ b/diff.h @@ -46,6 +46,7 @@ struct diff_options { int setup; int abbrev; const char *stat_sep; + long xdl_opts; int nr_paths; const char **paths; diff --git a/git-cvsimport.perl b/git-cvsimport.perl old mode 100644 new mode 100755 index f3daa6c05..50f5d9642 --- a/git-cvsimport.perl +++ b/git-cvsimport.perl @@ -17,7 +17,7 @@ use strict; use warnings; use Getopt::Std; use File::Spec; -use File::Temp qw(tempfile); +use File::Temp qw(tempfile tmpnam); use File::Path qw(mkpath); use File::Basename qw(basename dirname); use Time::Local; @@ -467,13 +467,12 @@ my $orig_git_index; $orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE}; my %index; # holds filenames of one index per branch -{ # init with an index for origin - my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx', - DIR => File::Spec->tmpdir()); - close ($fh); - $index{$opt_o} = $fn; -} +$index{$opt_o} = tmpnam(); + $ENV{GIT_INDEX_FILE} = $index{$opt_o}; +system("git-read-tree", $opt_o); +die "read-tree failed: $?\n" if $?; + unless(-d $git_dir) { system("git-init-db"); die "Cannot init the GIT db at $git_tree: $?\n" if $?; @@ -502,10 +501,7 @@ unless(-d $git_dir) { # populate index unless ($index{$last_branch}) { - my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx', - DIR => File::Spec->tmpdir()); - close ($fh); - $index{$last_branch} = $fn; + $index{$last_branch} = tmpnam(); } $ENV{GIT_INDEX_FILE} = $index{$last_branch}; system('git-read-tree', $last_branch); @@ -818,16 +814,26 @@ while() { if(($ancestor || $branch) ne $last_branch) { print "Switching from $last_branch to $branch\n" if $opt_v; unless ($index{$branch}) { - my ($fh, $fn) = tempfile('gitXXXXXX', SUFFIX => '.idx', - DIR => File::Spec->tmpdir()); - close ($fh); - $index{$branch} = $fn; + $index{$branch} = tmpnam(); $ENV{GIT_INDEX_FILE} = $index{$branch}; system("git-read-tree", $branch); die "read-tree failed: $?\n" if $?; - } else { + } + # just in case + $ENV{GIT_INDEX_FILE} = $index{$branch}; + if ($ancestor) { + print "have ancestor $ancestor" if $opt_v; + system("git-read-tree", $ancestor); + die "read-tree failed: $?\n" if $?; + } + } else { + # just in case + unless ($index{$branch}) { + $index{$branch} = tmpnam(); $ENV{GIT_INDEX_FILE} = $index{$branch}; - } + system("git-read-tree", $branch); + die "read-tree failed: $?\n" if $?; + } } $last_branch = $branch if $branch ne $last_branch; $state = 9; diff --git a/git-rebase.sh b/git-rebase.sh index 91594775e..9ad1c44d4 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -59,15 +59,16 @@ continue_merge () { if test -n "`git-diff-index HEAD`" then + printf "Committed: %0${prec}d" $msgnum git-commit -C "`cat $dotest/current`" else - echo "Previous merge succeeded automatically" + printf "Already applied: %0${prec}d" $msgnum fi + echo ' '`git-rev-list --pretty=oneline -1 HEAD | \ + sed 's/^[a-f0-9]\+ //'` prev_head=`git-rev-parse HEAD^0` - # save the resulting commit so we can read-tree on it later - echo "$prev_head" > "$dotest/cmt.$msgnum.result" echo "$prev_head" > "$dotest/prev_head" # onto the next patch: @@ -82,7 +83,7 @@ call_merge () { rv=$? case "$rv" in 0) - git-commit -C "$cmt" || die "commit failed: $MRESOLVEMSG" + return ;; 1) test -d "$GIT_DIR/rr-cache" && git-rerere @@ -100,23 +101,6 @@ call_merge () { } finish_rb_merge () { - set -e - - msgnum=1 - echo "Finalizing rebased commits..." - git-reset --hard "`cat $dotest/onto`" - end="`cat $dotest/end`" - while test "$msgnum" -le "$end" - do - git-read-tree `cat "$dotest/cmt.$msgnum.result"` - git-checkout-index -q -f -u -a - git-commit -C "`cat $dotest/cmt.$msgnum`" - - printf "Committed %0${prec}d" $msgnum - echo ' '`git-rev-list --pretty=oneline -1 HEAD | \ - sed 's/^[a-f0-9]\+ //'` - msgnum=$(($msgnum + 1)) - done rm -r "$dotest" echo "All done." } @@ -153,7 +137,18 @@ do --skip) if test -d "$dotest" then - die "--skip is not supported when using --merge" + prev_head="`cat $dotest/prev_head`" + end="`cat $dotest/end`" + msgnum="`cat $dotest/msgnum`" + msgnum=$(($msgnum + 1)) + onto="`cat $dotest/onto`" + while test "$msgnum" -le "$end" + do + call_merge "$msgnum" + continue_merge + done + finish_rb_merge + exit fi git am -3 --skip --resolvemsg="$RESOLVEMSG" exit diff --git a/merge-index.c b/merge-index.c index 190e12fb7..0498a6f45 100644 --- a/merge-index.c +++ b/merge-index.c @@ -1,5 +1,6 @@ #include #include +#include #include "cache.h" diff --git a/pkt-line.h b/pkt-line.h index 9abef24de..9df653f6f 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -1,6 +1,8 @@ #ifndef PKTLINE_H #define PKTLINE_H +#include "git-compat-util.h" + /* * Silly packetized line writing interface */ diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh index 32dc9c5e7..360a67060 100755 --- a/t/t3401-rebase-partial.sh +++ b/t/t3401-rebase-partial.sh @@ -37,7 +37,9 @@ test_expect_success \ test_expect_success \ 'pick top patch from topic branch into master' \ 'git-cherry-pick my-topic-branch^0 && - git-checkout -f my-topic-branch + git-checkout -f my-topic-branch && + git-branch master-merge master && + git-branch my-topic-branch-merge my-topic-branch ' test_debug \ @@ -50,4 +52,13 @@ test_expect_success \ 'rebase topic branch against new master and check git-am did not get halted' \ 'git-rebase master && test ! -d .dotest' +if test -z "$no_python" +then + test_expect_success \ + 'rebase --merge topic branch that was partially merged upstream' \ + 'git-checkout -f my-topic-branch-merge && + git-rebase --merge master-merge && + test ! -d .git/.dotest-merge' +fi + test_done diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh new file mode 100755 index 000000000..8ab63c527 --- /dev/null +++ b/t/t3403-rebase-skip.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# +# Copyright (c) 2006 Eric Wong +# + +test_description='git rebase --merge --skip tests' + +. ./test-lib.sh + +# we assume the default git-am -3 --skip strategy is tested independently +# and always works :) + +if test "$no_python"; then + echo "Skipping: no python => no recursive merge" + test_done + exit 0 +fi + +test_expect_success setup ' + echo hello > hello && + git add hello && + git commit -m "hello" && + git branch skip-reference && + + echo world >> hello && + git commit -a -m "hello world" && + echo goodbye >> hello && + git commit -a -m "goodbye" && + + git checkout -f skip-reference && + echo moo > hello && + git commit -a -m "we should skip this" && + echo moo > cow && + git add cow && + git commit -m "this should not be skipped" && + git branch pre-rebase skip-reference && + git branch skip-merge skip-reference + ' + +test_expect_failure 'rebase with git am -3 (default)' 'git rebase master' + +test_expect_success 'rebase --skip with am -3' ' + git reset --hard HEAD && + git rebase --skip + ' +test_expect_success 'checkout skip-merge' 'git checkout -f skip-merge' + +test_expect_failure 'rebase with --merge' 'git rebase --merge master' + +test_expect_success 'rebase --skip with --merge' ' + git reset --hard HEAD && + git rebase --skip + ' + +test_expect_success 'merge and reference trees equal' \ + 'test -z "`git-diff-tree skip-merge skip-reference`"' + +test_debug 'gitk --all & sleep 1' + +test_done + diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 2540e8a2c..2ce10b4c0 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -29,6 +29,9 @@ extern "C" { #define XDF_NEED_MINIMAL (1 << 1) +#define XDF_IGNORE_WHITESPACE (1 << 2) +#define XDF_IGNORE_WHITESPACE_CHANGE (1 << 3) +#define XDF_WHITESPACE_FLAGS (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE) #define XDL_PATCH_NORMAL '-' #define XDL_PATCH_REVERSE '+' diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index b95ade2c1..ed7ad2041 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -45,7 +45,7 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1, long *kvdf, long *kvdb, int need_min, xdpsplit_t *spl, xdalgoenv_t *xenv); static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, long chg2); -static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo); +static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags); @@ -397,7 +397,7 @@ static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, } -static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) { +static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { long ix, ixo, ixs, ixref, grpsiz, nrec = xdf->nrec; char *rchg = xdf->rchg, *rchgo = xdfo->rchg; xrecord_t **recs = xdf->recs; @@ -440,7 +440,7 @@ static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) { * the group. */ while (ixs > 0 && recs[ixs - 1]->ha == recs[ix - 1]->ha && - XDL_RECMATCH(recs[ixs - 1], recs[ix - 1])) { + xdl_recmatch(recs[ixs - 1]->ptr, recs[ixs - 1]->size, recs[ix - 1]->ptr, recs[ix - 1]->size, flags)) { rchg[--ixs] = 1; rchg[--ix] = 0; @@ -468,7 +468,7 @@ static int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo) { * the group. */ while (ix < nrec && recs[ixs]->ha == recs[ix]->ha && - XDL_RECMATCH(recs[ixs], recs[ix])) { + xdl_recmatch(recs[ixs]->ptr, recs[ixs]->size, recs[ix]->ptr, recs[ix]->size, flags)) { rchg[ixs++] = 0; rchg[ix++] = 1; @@ -546,8 +546,8 @@ int xdl_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, return -1; } - if (xdl_change_compact(&xe.xdf1, &xe.xdf2) < 0 || - xdl_change_compact(&xe.xdf2, &xe.xdf1) < 0 || + if (xdl_change_compact(&xe.xdf1, &xe.xdf2, xpp->flags) < 0 || + xdl_change_compact(&xe.xdf2, &xe.xdf1, xpp->flags) < 0 || xdl_build_script(&xe, &xscr) < 0) { xdl_free_env(&xe); diff --git a/xdiff/xdiffi.h b/xdiff/xdiffi.h index dd8f3c986..d3b72716b 100644 --- a/xdiff/xdiffi.h +++ b/xdiff/xdiffi.h @@ -55,6 +55,5 @@ void xdl_free_script(xdchange_t *xscr); int xdl_emit_diff(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdemitconf_t const *xecfg); - #endif /* #if !defined(XDIFFI_H) */ diff --git a/xdiff/xmacros.h b/xdiff/xmacros.h index 78f02603b..4c2fde80c 100644 --- a/xdiff/xmacros.h +++ b/xdiff/xmacros.h @@ -33,7 +33,6 @@ #define XDL_ISDIGIT(c) ((c) >= '0' && (c) <= '9') #define XDL_HASHLONG(v, b) (((unsigned long)(v) * GR_PRIME) >> ((CHAR_BIT * sizeof(unsigned long)) - (b))) #define XDL_PTRFREE(p) do { if (p) { xdl_free(p); (p) = NULL; } } while (0) -#define XDL_RECMATCH(r1, r2) ((r1)->size == (r2)->size && memcmp((r1)->ptr, (r2)->ptr, (r1)->size) == 0) #define XDL_LE32_PUT(p, v) \ do { \ unsigned char *__p = (unsigned char *) (p); \ diff --git a/xdiff/xprepare.c b/xdiff/xprepare.c index add5a75c7..1be7b3195 100644 --- a/xdiff/xprepare.c +++ b/xdiff/xprepare.c @@ -43,12 +43,13 @@ typedef struct s_xdlclassifier { xdlclass_t **rchash; chastore_t ncha; long count; + long flags; } xdlclassifier_t; -static int xdl_init_classifier(xdlclassifier_t *cf, long size); +static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags); static void xdl_free_classifier(xdlclassifier_t *cf); static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned int hbits, xrecord_t *rec); @@ -63,9 +64,11 @@ static int xdl_optimize_ctxs(xdfile_t *xdf1, xdfile_t *xdf2); -static int xdl_init_classifier(xdlclassifier_t *cf, long size) { +static int xdl_init_classifier(xdlclassifier_t *cf, long size, long flags) { long i; + cf->flags = flags; + cf->hbits = xdl_hashbits((unsigned int) size); cf->hsize = 1 << cf->hbits; @@ -103,8 +106,9 @@ static int xdl_classify_record(xdlclassifier_t *cf, xrecord_t **rhash, unsigned line = rec->ptr; hi = (long) XDL_HASHLONG(rec->ha, cf->hbits); for (rcrec = cf->rchash[hi]; rcrec; rcrec = rcrec->next) - if (rcrec->ha == rec->ha && rcrec->size == rec->size && - !memcmp(line, rcrec->line, rec->size)) + if (rcrec->ha == rec->ha && + xdl_recmatch(rcrec->line, rcrec->size, + rec->ptr, rec->size, cf->flags)) break; if (!rcrec) { @@ -173,7 +177,7 @@ static int xdl_prepare_ctx(mmfile_t *mf, long narec, xpparam_t const *xpp, top = blk + bsize; } prev = cur; - hav = xdl_hash_record(&cur, top); + hav = xdl_hash_record(&cur, top, xpp->flags); if (nrec >= narec) { narec *= 2; if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *)))) { @@ -268,7 +272,7 @@ int xdl_prepare_env(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, enl1 = xdl_guess_lines(mf1) + 1; enl2 = xdl_guess_lines(mf2) + 1; - if (xdl_init_classifier(&cf, enl1 + enl2 + 1) < 0) { + if (xdl_init_classifier(&cf, enl1 + enl2 + 1, xpp->flags) < 0) { return -1; } diff --git a/xdiff/xutils.c b/xdiff/xutils.c index f91b40347..f7bdd395a 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -186,12 +186,61 @@ long xdl_guess_lines(mmfile_t *mf) { return nl + 1; } +int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) +{ + int i1, i2; + + if (flags & XDF_IGNORE_WHITESPACE) { + for (i1 = i2 = 0; i1 < s1 && i2 < s2; i1++, i2++) { + if (isspace(l1[i1])) + while (isspace(l1[i1]) && i1 < s1) + i1++; + else if (isspace(l2[i2])) + while (isspace(l2[i2]) && i2 < s2) + i2++; + else if (l1[i1] != l2[i2]) + return l2[i2] - l1[i1]; + } + if (i1 >= s1) + return 1; + else if (i2 >= s2) + return -1; + } else if (flags & XDF_IGNORE_WHITESPACE_CHANGE) { + for (i1 = i2 = 0; i1 < s1 && i2 < s2; i1++, i2++) { + if (isspace(l1[i1])) { + if (!isspace(l2[i2])) + return -1; + while (isspace(l1[i1]) && i1 < s1) + i1++; + while (isspace(l2[i2]) && i2 < s2) + i2++; + } else if (l1[i1] != l2[i2]) + return l2[i2] - l1[i1]; + } + if (i1 >= s1) + return 1; + else if (i2 >= s2) + return -1; + } else + return s1 == s2 && !memcmp(l1, l2, s1); + + return 0; +} -unsigned long xdl_hash_record(char const **data, char const *top) { +unsigned long xdl_hash_record(char const **data, char const *top, long flags) { unsigned long ha = 5381; char const *ptr = *data; for (; ptr < top && *ptr != '\n'; ptr++) { + if (isspace(*ptr) && (flags & XDF_WHITESPACE_FLAGS)) { + while (ptr < top && isspace(*ptr) && ptr[1] != '\n') + ptr++; + if (flags & XDF_IGNORE_WHITESPACE_CHANGE) { + ha += (ha << 5); + ha ^= (unsigned long) ' '; + } + continue; + } ha += (ha << 5); ha ^= (unsigned long) *ptr; } diff --git a/xdiff/xutils.h b/xdiff/xutils.h index 08691a244..70d8b9838 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -34,7 +34,8 @@ void *xdl_cha_alloc(chastore_t *cha); void *xdl_cha_first(chastore_t *cha); void *xdl_cha_next(chastore_t *cha); long xdl_guess_lines(mmfile_t *mf); -unsigned long xdl_hash_record(char const **data, char const *top); +int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags); +unsigned long xdl_hash_record(char const **data, char const *top, long flags); unsigned int xdl_hashbits(unsigned int size); int xdl_num_out(char *out, long val); long xdl_atol(char const *str, char const **next);