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);
{
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++;
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
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);
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.
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:
return err;
}
}
- s->size = st.st_size;
+ s->size = xsize_t(st.st_size);
if (!s->size)
goto empty;
if (size_only)
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 ?
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))
/* 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)
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'
weird
EOF
- test_expect_success "rename succeeded" "diff -u expect .git/config"
+ test_expect_success "rename succeeded" "git diff expect .git/config"
- "diff -u 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" \
++ "git diff -u expect .git/config"
+
test_expect_success numbers '
git-config kilo.gram 1k &&
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
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
'
- | diff - victim/.git/pre-receive.args
+test_expect_success 'pre-receive hook arguments' '
+ echo \
+ refs/heads/master $commit0 $commit1 \
+ refs/heads/tofail $commit1 $commit0 \
++ | git diff - victim/.git/pre-receive.args
+'
+
test_expect_success 'update hook arguments' '
- ) | diff - victim/.git/update.args
+ (echo refs/heads/master $commit0 $commit1;
+ echo refs/heads/tofail $commit1 $commit0
++ ) | 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 <<EOF >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 <expect
++ git diff - actual <expect
'
test_done
--- /dev/null
- diff -u "$expect" "$actual" &&
+#!/bin/sh
+#
+# Copyright (c) 2007 Santi Béjar, based on t4013 by Junio C Hamano
+#
+#
+
+test_description='Merge logic in fetch'
+
+. ./test-lib.sh
+
+LF='
+'
+
+test_expect_success setup '
+ GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" &&
+ GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" &&
+ export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
+
+ echo >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 <<EOF
+br-$remote$branch
+br-$remote$branch $remote
+EOF
+ done
+done > 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 <<EOF
+$branch ../.git
+$branch ../.git one
+$branch ../.git one two
+$branch --tags ../.git
+$branch ../.git tag tag-one tag tag-three
+$branch ../.git tag tag-one-tree tag tag-three-file
+$branch ../.git one tag tag-one tag tag-three-file
+EOF
+done >> 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
++ 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
test_expect_success \
'A: verify commit' \
'git-cat-file commit master | sed 1d >actual &&
- diff -u expect actual'
+ git diff expect actual'
cat >expect <<EOF
100644 blob file2
test_expect_success \
'A: verify tree' \
'git-cat-file -p master^{tree} | sed "s/ [0-9a-f]* / /" >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 <<EOF
:2 `git-rev-parse --verify master:file2`
EOF
test_expect_success \
'A: verify marks output' \
- 'diff -u expect marks.out'
+ 'git diff expect marks.out'
- diff -u expect marks.new'
+test_expect_success \
+ 'A: verify marks import' \
+ 'git-fast-import \
+ --import-marks=marks.out \
+ --export-marks=marks.new \
+ </dev/null &&
++ git diff -u expect marks.new'
+
###
### series B
###
test_expect_success \
'C: verify commit' \
'git-cat-file commit branch | sed 1d >actual &&
- diff -u expect actual'
+ git diff expect actual'
cat >expect <<EOF
:000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A file2/newf
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
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
test_expect_success \
'F: verify other commit' \
'git-cat-file commit other >actual &&
- diff -u expect actual'
+ git diff expect actual'
###
### series G
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
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