From: Junio C Hamano Date: Sun, 11 Mar 2007 07:26:33 +0000 (-0800) Subject: Merge branch 'js/diff-ni' X-Git-Tag: v1.5.1-rc1~62 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/cf6981d4932007555689052cbc255b911674b01c?ds=inline;hp=-c Merge branch 'js/diff-ni' * js/diff-ni: Get rid of the dependency to GNU diff in the tests diff --no-index: support /dev/null as filename diff-ni: fix the diff with standard input diff: support reading a file from stdin via "-" --- cf6981d4932007555689052cbc255b911674b01c diff --combined diff-lib.c index 778cf58244,5e6bca5906..6abb981534 --- a/diff-lib.c +++ b/diff-lib.c @@@ -30,22 -30,28 +30,28 @@@ static int read_directory(const char *p return 0; } + static int get_mode(const char *path, int *mode) + { + struct stat st; + + if (!path || !strcmp(path, "/dev/null")) + *mode = 0; + else if (!strcmp(path, "-")) + *mode = ntohl(create_ce_mode(0666)); + else if (stat(path, &st)) + return error("Could not access '%s'", path); + else + *mode = st.st_mode; + return 0; + } + static int queue_diff(struct diff_options *o, const char *name1, const char *name2) { - struct stat st; int mode1 = 0, mode2 = 0; - if (name1) { - if (stat(name1, &st)) - return error("Could not access '%s'", name1); - mode1 = st.st_mode; - } - if (name2) { - if (stat(name2, &st)) - return error("Could not access '%s'", name2); - mode2 = st.st_mode; - } + if (get_mode(name1, &mode1) || get_mode(name2, &mode2)) + return -1; if (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2)) return error("file/directory conflict: %s, %s", name1, name2); @@@ -224,7 -230,7 +230,7 @@@ int setup_diff_no_index(struct rev_inf { int i; for (i = 1; i < argc; i++) - if (argv[i][0] != '-') + if (argv[i][0] != '-' || argv[i][1] == '\0') break; else if (!strcmp(argv[i], "--")) { i++; @@@ -254,9 -260,15 +260,15 @@@ revs->diffopt.paths = xcalloc(2, sizeof(char*)); for (i = 0; i < 2; i++) { - const char *p; - p = prefix_filename(prefix, len, argv[argc - 2 + i]); - revs->diffopt.paths[i] = xstrdup(p); + const char *p = argv[argc - 2 + i]; + /* + * stdin should be spelled as '-'; if you have + * path that is '-', spell it as ./-. + */ + p = (strcmp(p, "-") + ? xstrdup(prefix_filename(prefix, len, p)) + : p); + revs->diffopt.paths[i] = p; } } else @@@ -412,9 -424,6 +424,9 @@@ int run_diff_files(struct rev_info *rev S_ISREG(newmode) && S_ISREG(oldmode) && ((newmode ^ oldmode) == 0111)) newmode = oldmode; + else if (!has_symlinks && + S_ISREG(newmode) && S_ISLNK(oldmode)) + newmode = oldmode; diff_change(&revs->diffopt, oldmode, newmode, ce->sha1, (changed ? null_sha1 : ce->sha1), ce->name, NULL); diff --combined diff.c index 8f7a7d1108,9e276e5848..954ca83e0b --- a/diff.c +++ b/diff.c @@@ -1364,6 -1364,32 +1364,32 @@@ static struct sha1_size_cache *locate_s return e; } + static int populate_from_stdin(struct diff_filespec *s) + { + #define INCREMENT 1024 + char *buf; + unsigned long size; + int got; + + size = 0; + buf = NULL; + while (1) { + buf = xrealloc(buf, size + INCREMENT); + got = xread(0, buf + size, INCREMENT); + if (!got) + break; /* EOF */ + if (got < 0) + return error("error while reading from stdin %s", + strerror(errno)); + size += got; + } + s->should_munmap = 0; + s->data = buf; + s->size = size; + s->should_free = 1; + return 0; + } + /* * While doing rename detection and pickaxe operation, we may need to * grab the data for the blob (or file) for our own in-core comparison. @@@ -1389,6 -1415,9 +1415,9 @@@ int diff_populate_filespec(struct diff_ char *buf; unsigned long size; + if (!strcmp(s->path, "-")) + return populate_from_stdin(s); + if (lstat(s->path, &st) < 0) { if (errno == ENOENT) { err_empty: @@@ -1399,7 -1428,7 +1428,7 @@@ return err; } } - s->size = st.st_size; + s->size = xsize_t(st.st_size); if (!s->size) goto empty; if (size_only) @@@ -1515,13 -1544,12 +1544,13 @@@ static void prepare_temp_file(const cha if (S_ISLNK(st.st_mode)) { int ret; char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */ + size_t sz = xsize_t(st.st_size); if (sizeof(buf) <= st.st_size) die("symlink too long: %s", name); - ret = readlink(name, buf, st.st_size); + ret = readlink(name, buf, sz); if (ret < 0) die("readlink(%s)", name); - prep_temp_blob(temp, buf, st.st_size, + prep_temp_blob(temp, buf, sz, (one->sha1_valid ? one->sha1 : null_sha1), (one->sha1_valid ? @@@ -1690,6 -1718,10 +1719,10 @@@ static void diff_fill_sha1_info(struct if (DIFF_FILE_VALID(one)) { if (!one->sha1_valid) { struct stat st; + if (!strcmp(one->path, "-")) { + hashcpy(one->sha1, null_sha1); + return; + } if (lstat(one->path, &st) < 0) die("stat %s", one->path); if (index_path(one->sha1, one->path, &st, 0)) @@@ -2139,7 -2171,7 +2172,7 @@@ static int parse_num(const char **cp_p /* user says num divided by scale and we say internally that * is MAX_SCORE * num / scale. */ - return (num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale); + return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale)); } int diff_scoreopt_parse(const char *opt) diff --combined t/t1300-repo-config.sh index ee386cfbf3,84a59397b2..78c2e0864f --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@@ -368,12 -368,12 +368,12 @@@ cat > expect << EO weird EOF - test_expect_success "rename succeeded" "diff -u expect .git/config" + test_expect_success "rename succeeded" "git diff expect .git/config" test_expect_failure "rename non-existing section" \ 'git-config --rename-section branch."world domination" branch.drei' - test_expect_success "rename succeeded" "diff -u expect .git/config" + test_expect_success "rename succeeded" "git diff expect .git/config" test_expect_success "rename another section" \ 'git-config --rename-section branch."1 234 blabl/a" branch.drei' @@@ -389,24 -389,8 +389,24 @@@ cat > expect << EO weird EOF - test_expect_success "rename succeeded" "diff -u expect .git/config" + test_expect_success "rename succeeded" "git diff expect .git/config" +cat >> .git/config << EOF + [branch "zwei"] a = 1 [branch "vier"] +EOF + +test_expect_success "remove section" "git config --remove-section branch.zwei" + +cat > expect << EOF +# Hallo + #Bello +[branch "drei"] +weird +EOF + +test_expect_success "section was removed properly" \ - "diff -u expect .git/config" ++ "git diff -u expect .git/config" + test_expect_success numbers ' git-config kilo.gram 1k && diff --combined t/t5400-send-pack.sh index b1c97b0dfb,fc4a126407..477b267599 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@@ -108,9 -108,9 +108,9 @@@ test_expect_success cd victim && git-config receive.denyNonFastforwards true && cd .. && - git-update-ref refs/heads/master master^ && - git-send-pack --force ./victim/.git/ master && + git-update-ref refs/heads/master master^ || return 1 + git-send-pack --force ./victim/.git/ master && return 1 - ! diff .git/refs/heads/master victim/.git/refs/heads/master + ! git diff .git/refs/heads/master victim/.git/refs/heads/master ' test_done diff --combined t/t5401-update-hooks.sh index 0c0034e34c,460c9fd7fe..cf6306ce9f --- a/t/t5401-update-hooks.sh +++ b/t/t5401-update-hooks.sh @@@ -11,124 -11,71 +11,124 @@@ test_expect_success setup git-update-index --add a && tree0=$(git-write-tree) && commit0=$(echo setup | git-commit-tree $tree0) && - git-update-ref HEAD $commit0 && - git-clone ./. victim && echo We hope it works. >a && git-update-index a && tree1=$(git-write-tree) && commit1=$(echo modify | git-commit-tree $tree1 -p $commit0) && - git-update-ref HEAD $commit1 + git-update-ref refs/heads/master $commit0 && + git-update-ref refs/heads/tofail $commit1 && + git-clone ./. victim && + GIT_DIR=victim/.git git-update-ref refs/heads/tofail $commit1 && + git-update-ref refs/heads/master $commit1 && + git-update-ref refs/heads/tofail $commit0 ' +cat >victim/.git/hooks/pre-receive <<'EOF' +#!/bin/sh +echo "$@" >>$GIT_DIR/pre-receive.args +read x; printf "$x" >$GIT_DIR/pre-receive.stdin +echo STDOUT pre-receive +echo STDERR pre-receive >&2 +EOF +chmod u+x victim/.git/hooks/pre-receive + cat >victim/.git/hooks/update <<'EOF' #!/bin/sh -echo "$@" >$GIT_DIR/update.args +echo "$@" >>$GIT_DIR/update.args read x; printf "$x" >$GIT_DIR/update.stdin -echo STDOUT update -echo STDERR update >&2 +echo STDOUT update $1 +echo STDERR update $1 >&2 +test "$1" = refs/heads/master || exit EOF chmod u+x victim/.git/hooks/update +cat >victim/.git/hooks/post-receive <<'EOF' +#!/bin/sh +echo "$@" >>$GIT_DIR/post-receive.args +read x; printf "$x" >$GIT_DIR/post-receive.stdin +echo STDOUT post-receive +echo STDERR post-receive >&2 +EOF +chmod u+x victim/.git/hooks/post-receive + cat >victim/.git/hooks/post-update <<'EOF' #!/bin/sh -echo "$@" >$GIT_DIR/post-update.args +echo "$@" >>$GIT_DIR/post-update.args read x; printf "$x" >$GIT_DIR/post-update.stdin echo STDOUT post-update echo STDERR post-update >&2 EOF chmod u+x victim/.git/hooks/post-update -test_expect_success push ' - git-send-pack ./victim/.git/ master >send.out 2>send.err +test_expect_failure push ' + git-send-pack --force ./victim/.git master tofail >send.out 2>send.err +' + +test_expect_success 'updated as expected' ' + test $(GIT_DIR=victim/.git git-rev-parse master) = $commit1 && + test $(GIT_DIR=victim/.git git-rev-parse tofail) = $commit1 ' test_expect_success 'hooks ran' ' + test -f victim/.git/pre-receive.args && + test -f victim/.git/pre-receive.stdin && test -f victim/.git/update.args && test -f victim/.git/update.stdin && + test -f victim/.git/post-receive.args && + test -f victim/.git/post-receive.stdin && test -f victim/.git/post-update.args && test -f victim/.git/post-update.stdin ' +test_expect_success 'pre-receive hook arguments' ' + echo \ + refs/heads/master $commit0 $commit1 \ + refs/heads/tofail $commit1 $commit0 \ - | diff - victim/.git/pre-receive.args ++ | git diff - victim/.git/pre-receive.args +' + test_expect_success 'update hook arguments' ' + (echo refs/heads/master $commit0 $commit1; + echo refs/heads/tofail $commit1 $commit0 - ) | diff - victim/.git/update.args ++ ) | git diff - victim/.git/update.args +' + +test_expect_success 'post-receive hook arguments' ' echo refs/heads/master $commit0 $commit1 | - diff - victim/.git/post-receive.args - git diff - victim/.git/update.args ++ git diff - victim/.git/post-receive.args ' test_expect_success 'post-update hook arguments' ' echo refs/heads/master | - diff -u - victim/.git/post-update.args + git diff - victim/.git/post-update.args ' -test_expect_failure 'update hook stdin is /dev/null' ' - test -s victim/.git/update.stdin -' - -test_expect_failure 'post-update hook stdin is /dev/null' ' - test -s victim/.git/post-update.stdin +test_expect_success 'all hook stdin is /dev/null' ' + ! test -s victim/.git/pre-receive.stdin && + ! test -s victim/.git/update.stdin && + ! test -s victim/.git/post-receive.stdin && + ! test -s victim/.git/post-update.stdin ' test_expect_failure 'send-pack produced no output' ' test -s send.out ' +cat <expect +STDOUT pre-receive +STDERR pre-receive +STDOUT update refs/heads/master +STDERR update refs/heads/master +STDOUT update refs/heads/tofail +STDERR update refs/heads/tofail +STDOUT post-receive +STDERR post-receive +STDOUT post-update +STDERR post-update +EOF test_expect_success 'send-pack stderr contains hook messages' ' - grep "STDOUT update" send.err && - grep "STDERR update" send.err && - grep "STDOUT post-update" send.err && - grep "STDERR post-update" send.err + egrep ^STD send.err >actual && - diff - actual file original && + git add file && + git commit -a -m One && + git tag tag-one && + git tag tag-one-tree HEAD^{tree} && + git branch one && + + echo two >> file && + git commit -a -m Two && + git tag -a -m "Tag Two" tag-two && + git branch two && + + echo three >> file && + git commit -a -m Three && + git tag -a -m "Tag Three" tag-three && + git tag -a -m "Tag Three file" tag-three-file HEAD^{tree}:file && + git branch three && + + echo master >> file && + git commit -a -m Master && + git tag -a -m "Tag Master" tag-master && + + git checkout three && + + git clone . cloned && + cd cloned && + git config remote.origin.url ../.git/ && + + git config remote.config-explicit.url ../.git/ && + git config remote.config-explicit.fetch refs/heads/master:remotes/rem/master && + git config --add remote.config-explicit.fetch refs/heads/one:remotes/rem/one && + git config --add remote.config-explicit.fetch two:remotes/rem/two && + git config --add remote.config-explicit.fetch refs/heads/three:remotes/rem/three && + remotes="config-explicit" && + + git config remote.config-glob.url ../.git/ && + git config remote.config-glob.fetch refs/heads/*:refs/remotes/rem/* && + remotes="$remotes config-glob" && + + mkdir -p .git/remotes && + { + echo "URL: ../.git/" + echo "Pull: refs/heads/master:remotes/rem/master" + echo "Pull: refs/heads/one:remotes/rem/one" + echo "Pull: two:remotes/rem/two" + echo "Pull: refs/heads/three:remotes/rem/three" + } >.git/remotes/remote-explicit && + remotes="$remotes remote-explicit" && + + { + echo "URL: ../.git/" + echo "Pull: refs/heads/*:refs/remotes/rem/*" + } >.git/remotes/remote-glob && + remotes="$remotes remote-glob" && + + mkdir -p .git/branches && + echo "../.git" > .git/branches/branches-default && + remotes="$remotes branches-default" && + + echo "../.git#one" > .git/branches/branches-one && + remotes="$remotes branches-one" && + + for remote in $remotes ; do + git config branch.br-$remote.remote $remote && + git config branch.br-$remote-merge.remote $remote && + git config branch.br-$remote-merge.merge refs/heads/three && + git config branch.br-$remote-octopus.remote $remote && + git config branch.br-$remote-octopus.merge refs/heads/one && + git config --add branch.br-$remote-octopus.merge two && + git config --add branch.br-$remote-octopus.merge remotes/rem/three + done +' + +# Merge logic depends on branch properties and Pull: or .fetch lines +for remote in $remotes ; do + for branch in "" "-merge" "-octopus" ; do +cat < tests + +# Merge logic does not depend on branch properties, +# but does depend on Pull: or fetch lines. +# Use two branches completely unrelated from the arguments, +# the clone default and one without branch properties +for branch in master br-unconfig ; do + echo $branch + for remote in $remotes ; do + echo $branch $remote + done +done >> tests + +# Merge logic does not depend on branch properties +# neither in the Pull: or .fetch config +for branch in master br-unconfig ; do + cat <> tests + +while read cmd +do + case "$cmd" in + '' | '#'*) continue ;; + esac + test=`echo "$cmd" | sed -e 's|[/ ][/ ]*|_|g'` + cnt=`expr $test_count + 1` + pfx=`printf "%04d" $cnt` + expect="../../t5515/fetch.$test" + actual="$pfx-fetch.$test" + + test_expect_success "$cmd" ' + { + echo "# $cmd" + set x $cmd; shift + git symbolic-ref HEAD refs/heads/$1 ; shift + rm -f .git/FETCH_HEAD + rm -f .git/refs/heads/* + rm -f .git/refs/remotes/rem/* + rm -f .git/refs/tags/* + git fetch "$@" >/dev/null + cat .git/FETCH_HEAD + } >"$actual" && + if test -f "$expect" + then - diff -u "$expect" "$actual" && ++ git diff -u "$expect" "$actual" && + rm -f "$actual" + else + # this is to help developing new tests. + cp "$actual" "$expect" + false + fi + ' +done < tests + +test_done diff --combined t/t9300-fast-import.sh index 2e1a09ff2d,2337d83d35..03f2f8f347 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@@ -74,7 -74,7 +74,7 @@@ EO test_expect_success \ 'A: verify commit' \ 'git-cat-file commit master | sed 1d >actual && - diff -u expect actual' + git diff expect actual' cat >expect <actual && - diff -u expect actual' + git diff expect actual' echo "$file2_data" >expect test_expect_success \ 'A: verify file2' \ - 'git-cat-file blob master:file2 >actual && diff -u expect actual' + 'git-cat-file blob master:file2 >actual && git diff expect actual' echo "$file3_data" >expect test_expect_success \ 'A: verify file3' \ - 'git-cat-file blob master:file3 >actual && diff -u expect actual' + 'git-cat-file blob master:file3 >actual && git diff expect actual' printf "$file4_data" >expect test_expect_success \ 'A: verify file4' \ - 'git-cat-file blob master:file4 >actual && diff -u expect actual' + 'git-cat-file blob master:file4 >actual && git diff expect actual' cat >expect <actual && - diff -u expect actual' + git diff expect actual' cat >expect <expec test_expect_success \ 'D: verify file5' \ 'git-cat-file blob branch:newdir/interesting >actual && - diff -u expect actual' + git diff expect actual' echo "$file6_data" >expect test_expect_success \ 'D: verify file6' \ 'git-cat-file blob branch:newdir/exec.sh >actual && - diff -u expect actual' + git diff expect actual' ### ### series E @@@ -282,7 -274,7 +282,7 @@@ EO test_expect_success \ 'E: verify commit' \ 'git-cat-file commit branch | sed 1,2d >actual && - diff -u expect actual' + git diff expect actual' ### ### series F @@@ -335,7 -327,7 +335,7 @@@ EO test_expect_success \ 'F: verify other commit' \ 'git-cat-file commit other >actual && - diff -u expect actual' + git diff expect actual' ### ### series G @@@ -413,7 -405,7 +413,7 @@@ echo "$file5_data" >expec test_expect_success \ 'H: verify file' \ 'git-cat-file blob H:h/e/l/lo >actual && - diff -u expect actual' + git diff expect actual' ### ### series I @@@ -439,7 -431,7 +439,7 @@@ EO test_expect_success \ 'I: verify edge list' \ 'sed -e s/pack-.*pack/pack-.pack/ edges.list >actual && - diff -u expect actual' + git diff expect actual' ### ### series J