 7cf686b9a8
			
		
	
	7cf686b9a8
	
	
	
		
			
			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
 |