| 1 | #!/bin/sh |
| 2 | |
| 3 | test_description='various tests of reflog walk (log -g) behavior' |
| 4 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
| 5 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
| 6 | |
| 7 | . ./test-lib.sh |
| 8 | |
| 9 | test_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 | |
| 20 | do_walk () { |
| 21 | git log -g --format="%gd %gs" "$@" |
| 22 | } |
| 23 | |
| 24 | test_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 | |
| 34 | test_expect_success 'reflog walk shows expected logs' ' |
| 35 | do_walk >actual && |
| 36 | test_cmp expect.all actual |
| 37 | ' |
| 38 | |
| 39 | test_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 | |
| 45 | test_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 | |
| 51 | test_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 | |
| 61 | test_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 | |
| 68 | test_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 | |
| 91 | test_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 | |
| 96 | test_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. |
| 124 | test_expect_success 'walk prefers reflog to ref tip' ' |
| 125 | test_commit A && |
| 126 | test_commit B && |
| 127 | git reflog delete HEAD@{0} && |
| 128 | head=$(git rev-parse HEAD) && |
| 129 | git rev-parse A >expect && |
| 130 | git log -g --format=%H -1 >actual && |
| 131 | test_cmp expect actual |
| 132 | ' |
| 133 | |
| 134 | test_expect_success 'rev-list -g complains when there are no reflogs' ' |
| 135 | test_must_fail git rev-list -g |
| 136 | ' |
| 137 | |
| 138 | test_done |