Since its inception, the general strategy of the reflog-walk
code has been to start with the tip commit for the ref, and
as we traverse replace each commit's parent pointers with
fake parents pointing to the previous reflog entry.
This lets us traverse the reflog as if it were a real
history, but it has some user-visible oddities. Namely:
1. The fake parents are used for commit selection and
display. So for example, "--merges" or "--no-merges"
are not useful, because the history appears as a linear
string of commits. Likewise, pathspec limiting is based
on the diff between adjacent entries, not the changes
actually introduced by a commit.
These are often the same (e.g., because the entry was
just running "git commit" and the adjacent entry _is_
the true parent), but it may not be in several common
cases. For instance, using "git reset" to jump around
history, or "git checkout" to move HEAD.
2. We reverse-map each commit back to its reflog. So when
it comes time to show commit X, we say "a-ha, we added
X because it was at the tip of the 'foo' reflog, so
let's show the foo reflog". But this leads to nonsense
results when you ask to traverse multiple reflogs: if
two reflogs have the same tip commit, we only map back
to one of them. Instead, we should show both.
3. If the tip of the reflog and the ref tip disagree on
the current value, we show the ref tip but give no
indication of the value in the reflog. This situation
isn't supposed to happen (since any ref update should
touch the reflog). But if it does, given that the
requested operation is to show the reflog, it makes
sense to prefer that.
This commit adds a new script with several expect_failure
tests to demonstrate the problems. This could be part of
the existing t1411, but it's a bit easier to start from a
fresh state, where we know exactly what will be in the log.
Since the new multiple-reflog tests are checking the actual
output, we can drop the "make sure we don't segfault" tests
from t1411, which are a strict subset of what we're doing
here.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
175 lines
4.4 KiB
Bash
Executable File
175 lines
4.4 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
test_description='Test reflog display routines'
|
|
. ./test-lib.sh
|
|
|
|
test_expect_success 'setup' '
|
|
echo content >file &&
|
|
git add file &&
|
|
test_tick &&
|
|
git commit -m one
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
|
|
Reflog message: commit (initial): one
|
|
EOF
|
|
test_expect_success 'log -g shows reflog headers' '
|
|
git log -g -1 >tmp &&
|
|
grep ^Reflog <tmp >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
e46513e HEAD@{0}: commit (initial): one
|
|
EOF
|
|
test_expect_success 'oneline reflog format' '
|
|
git log -g -1 --oneline >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'reflog default format' '
|
|
git reflog -1 >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
commit e46513e
|
|
Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
|
|
Reflog message: commit (initial): one
|
|
Author: A U Thor <author@example.com>
|
|
|
|
one
|
|
EOF
|
|
test_expect_success 'override reflog default format' '
|
|
git reflog --format=short -1 >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
Reflog: HEAD@{Thu Apr 7 15:13:13 2005 -0700} (C O Mitter <committer@example.com>)
|
|
Reflog message: commit (initial): one
|
|
EOF
|
|
test_expect_success 'using @{now} syntax shows reflog date (multiline)' '
|
|
git log -g -1 HEAD@{now} >tmp &&
|
|
grep ^Reflog <tmp >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
|
|
EOF
|
|
test_expect_success 'using @{now} syntax shows reflog date (oneline)' '
|
|
git log -g -1 --oneline HEAD@{now} >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
HEAD@{Thu Apr 7 15:13:13 2005 -0700}
|
|
EOF
|
|
test_expect_success 'using @{now} syntax shows reflog date (format=%gd)' '
|
|
git log -g -1 --format=%gd HEAD@{now} >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
Reflog: HEAD@{Thu Apr 7 15:13:13 2005 -0700} (C O Mitter <committer@example.com>)
|
|
Reflog message: commit (initial): one
|
|
EOF
|
|
test_expect_success 'using --date= shows reflog date (multiline)' '
|
|
git log -g -1 --date=default >tmp &&
|
|
grep ^Reflog <tmp >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
|
|
EOF
|
|
test_expect_success 'using --date= shows reflog date (oneline)' '
|
|
git log -g -1 --oneline --date=default >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
HEAD@{1112911993 -0700}
|
|
EOF
|
|
test_expect_success 'using --date= shows reflog date (format=%gd)' '
|
|
git log -g -1 --format=%gd --date=raw >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
|
|
Reflog message: commit (initial): one
|
|
EOF
|
|
test_expect_success 'log.date does not invoke "--date" magic (multiline)' '
|
|
test_config log.date raw &&
|
|
git log -g -1 >tmp &&
|
|
grep ^Reflog <tmp >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
e46513e HEAD@{0}: commit (initial): one
|
|
EOF
|
|
test_expect_success 'log.date does not invoke "--date" magic (oneline)' '
|
|
test_config log.date raw &&
|
|
git log -g -1 --oneline >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
HEAD@{0}
|
|
EOF
|
|
test_expect_success 'log.date does not invoke "--date" magic (format=%gd)' '
|
|
test_config log.date raw &&
|
|
git log -g -1 --format=%gd >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
cat >expect <<'EOF'
|
|
HEAD@{0}
|
|
EOF
|
|
test_expect_success '--date magic does not override explicit @{0} syntax' '
|
|
git log -g -1 --format=%gd --date=raw HEAD@{0} >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
: >expect
|
|
test_expect_success 'empty reflog file' '
|
|
git branch empty &&
|
|
git reflog expire --expire=all refs/heads/empty &&
|
|
|
|
git log -g empty >actual &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
# This guards against the alternative of showing the diffs vs. the
|
|
# reflog ancestor. The reflog used is designed to list the commits
|
|
# more than once, so as to exercise the corresponding logic.
|
|
test_expect_success 'git log -g -p shows diffs vs. parents' '
|
|
test_commit two &&
|
|
git branch flipflop &&
|
|
git update-ref refs/heads/flipflop -m flip1 HEAD^ &&
|
|
git update-ref refs/heads/flipflop -m flop1 HEAD &&
|
|
git update-ref refs/heads/flipflop -m flip2 HEAD^ &&
|
|
git log -g -p flipflop >reflog &&
|
|
grep -v ^Reflog reflog >actual &&
|
|
git log -1 -p HEAD^ >log.one &&
|
|
git log -1 -p HEAD >log.two &&
|
|
(
|
|
cat log.one; echo
|
|
cat log.two; echo
|
|
cat log.one; echo
|
|
cat log.two
|
|
) >expect &&
|
|
test_cmp expect actual
|
|
'
|
|
|
|
test_expect_success 'reflog exists works' '
|
|
git reflog exists refs/heads/master &&
|
|
! git reflog exists refs/heads/nonexistent
|
|
'
|
|
|
|
test_done
|