1#!/bin/sh 2 3test_description='various tests of reflog walk (log -g) behavior' 4GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main 5export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME 6 7. ./test-lib.sh 8 9test_expect_success 'set up some reflog entries' ' 10 test_commit one && 11 test_commit two && 12 git checkout -b side HEAD^ && 13 test_commit three && 14 git merge --no-commit main && 15 echo evil-merge-content >>one.t && 16 test_tick && 17 git commit --no-edit -a 18' 19 20do_walk () { 21 git log -g --format="%gd %gs" "$@" 22} 23 24test_expect_success 'set up expected reflog' ' 25 cat >expect.all <<-EOF 26 HEAD@{0} commit (merge): Merge branch ${SQ}main${SQ} into side 27 HEAD@{1} commit: three 28 HEAD@{2} checkout: moving from main to side 29 HEAD@{3} commit: two 30 HEAD@{4} commit (initial): one 31 EOF 32' 33 34test_expect_success 'reflog walk shows expected logs' ' 35 do_walk >actual && 36 test_cmp expect.all actual 37' 38 39test_expect_success 'reflog can limit with --no-merges' ' 40 grep -v merge expect.all >expect && 41 do_walk --no-merges >actual && 42 test_cmp expect actual 43' 44 45test_expect_success 'reflog can limit with pathspecs' ' 46 grep two expect.all >expect && 47 do_walk -- two.t >actual && 48 test_cmp expect actual 49' 50 51test_expect_success 'pathspec limiting handles merges' ' 52 # we pick up: 53 # - the initial commit of one 54 # - the checkout back to commit one 55 # - the evil merge which touched one 56 sed -n "1p;3p;5p" expect.all >expect && 57 do_walk -- one.t >actual && 58 test_cmp expect actual 59' 60 61test_expect_success '--parents shows true parents' ' 62 # convert newlines to spaces 63 echo $(git rev-parse HEAD HEAD^1 HEAD^2) >expect && 64 git rev-list -g --parents -1 HEAD >actual && 65 test_cmp expect actual 66' 67 68test_expect_success 'walking multiple reflogs shows all' ' 69 # We expect to see all entries for all reflogs, but interleaved by 70 # date, with order on the command line breaking ties. We 71 # can use "sort" on the separate lists to generate this, 72 # but note two tricks: 73 # 74 # 1. We use "{" as the delimiter, which lets us skip to the reflog 75 # date specifier as our second field, and then our "-n" numeric 76 # sort ignores the bits after the timestamp. 77 # 78 # 2. POSIX leaves undefined whether this is a stable sort or not. So 79 # we use "-k 1" to ensure that we see HEAD before main before 80 # side when breaking ties. 81 { 82 do_walk --date=unix HEAD && 83 do_walk --date=unix side && 84 do_walk --date=unix main 85 } >expect.raw && 86 sort -t "{" -k 2nr -k 1 <expect.raw >expect && 87 do_walk --date=unix HEAD main side >actual && 88 test_cmp expect actual 89' 90 91test_expect_success 'date-limiting does not interfere with other logs' ' 92 do_walk HEAD@{1979-01-01} HEAD >actual && 93 test_cmp expect.all actual 94' 95 96test_expect_success 'min/max age uses entry date to limit' ' 97 # Flip between commits one and two so each ref update actually 98 # does something (and does not get optimized out). We know 99 # that the timestamps of those commits will be before our "min". 100 101 git update-ref -m before refs/heads/minmax one && 102 103 test_tick && 104 min=$test_tick && 105 git update-ref -m min refs/heads/minmax two && 106 107 test_tick && 108 max=$test_tick && 109 git update-ref -m max refs/heads/minmax one && 110 111 test_tick && 112 git update-ref -m after refs/heads/minmax two && 113 114 cat >expect <<-\EOF && 115 max 116 min 117 EOF 118 git log -g --since=$min --until=$max --format=%gs minmax >actual && 119 test_cmp expect actual 120' 121 122# Create a situation where the reflog and ref database disagree about the latest 123# state of HEAD. 124test_expect_success REFFILES 'walk prefers reflog to ref tip' ' 125 head=$(git rev-parse HEAD) && 126 one=$(git rev-parse one) && 127 ident="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE" && 128 echo "$head $one $ident broken reflog entry" >>.git/logs/HEAD && 129 130 echo $one >expect && 131 git log -g --format=%H -1 >actual && 132 test_cmp expect actual 133' 134 135test_expect_success 'rev-list -g complains when there are no reflogs' ' 136 test_must_fail git rev-list -g 137' 138 139test_done 140