reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2007 Junio C Hamano
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='Test prune and reflog expiration'
|
2020-11-18 23:44:21 +00:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-18 23:44:19 +00:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
tests: mark tests as passing with SANITIZE=leak
When the "ab/various-leak-fixes" topic was merged in [1] only t6021
would fail if the tests were run in the
"GIT_TEST_PASSING_SANITIZE_LEAK=check" mode, i.e. to check whether we
marked all leak-free tests with "TEST_PASSES_SANITIZE_LEAK=true".
Since then we've had various tests starting to pass under
SANITIZE=leak. Let's mark those as passing, this is when they started
to pass, narrowed down with "git bisect":
- t5317-pack-objects-filter-objects.sh: In
faebba436e6 (list-objects-filter: plug pattern_list leak, 2022-12-01).
- t3210-pack-refs.sh, t5613-info-alternate.sh,
t7403-submodule-sync.sh: In 189e97bc4ba (diff: remove parseopts member
from struct diff_options, 2022-12-01).
- t1408-packed-refs.sh: In ab91f6b7c42 (Merge branch
'rs/diff-parseopts', 2022-12-19).
- t0023-crlf-am.sh, t4152-am-subjects.sh, t4254-am-corrupt.sh,
t4256-am-format-flowed.sh, t4257-am-interactive.sh,
t5403-post-checkout-hook.sh: In a658e881c13 (am: don't pass strvec to
apply_parse_options(), 2022-12-13)
- t1301-shared-repo.sh, t1302-repo-version.sh: In b07a819c05f (reflog:
clear leftovers in reflog_expiry_cleanup(), 2022-12-13).
- t1304-default-acl.sh, t1410-reflog.sh,
t5330-no-lazy-fetch-with-commit-graph.sh, t5502-quickfetch.sh,
t5604-clone-reference.sh, t6014-rev-list-all.sh,
t7701-repack-unpack-unreachable.sh: In b0c61be3209 (Merge branch
'rs/reflog-expiry-cleanup', 2022-12-26)
- t3800-mktag.sh, t5302-pack-index.sh, t5306-pack-nobase.sh,
t5573-pull-verify-signatures.sh, t7612-merge-verify-signatures.sh: In
69bbbe484ba (hash-object: use fsck for object checks, 2023-01-18).
- t1451-fsck-buffer.sh: In 8e4309038f0 (fsck: do not assume
NUL-termination of buffers, 2023-01-19).
- t6501-freshen-objects.sh: In abf2bb895b4 (Merge branch
'jk/hash-object-fsck', 2023-01-30)
1. 9ea1378d046 (Merge branch 'ab/various-leak-fixes', 2022-12-14)
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-02-06 23:07:36 +00:00
|
|
|
TEST_PASSES_SANITIZE_LEAK=true
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
check_have () {
|
|
|
|
gaah= &&
|
|
|
|
for N in "$@"
|
|
|
|
do
|
|
|
|
eval "o=\$$N" && git cat-file -t $o || {
|
|
|
|
echo Gaah $N
|
|
|
|
gaah=$N
|
|
|
|
break
|
|
|
|
}
|
|
|
|
done &&
|
|
|
|
test -z "$gaah"
|
|
|
|
}
|
|
|
|
|
|
|
|
check_fsck () {
|
2018-11-10 05:16:15 +00:00
|
|
|
git fsck --full >fsck.output
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
case "$1" in
|
|
|
|
'')
|
2018-11-10 05:16:15 +00:00
|
|
|
test_must_be_empty fsck.output ;;
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
*)
|
2023-10-31 05:23:30 +00:00
|
|
|
test_grep "$1" fsck.output ;;
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
corrupt () {
|
2019-06-28 22:59:20 +00:00
|
|
|
mv .git/objects/$(test_oid_to_path $1) .git/$1
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
recover () {
|
2019-06-28 22:59:20 +00:00
|
|
|
aa=$(echo $1 | cut -c 1-2)
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
mkdir -p .git/objects/$aa
|
2019-06-28 22:59:20 +00:00
|
|
|
mv .git/$1 .git/objects/$(test_oid_to_path $1)
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
check_dont_have () {
|
|
|
|
gaah= &&
|
|
|
|
for N in "$@"
|
|
|
|
do
|
|
|
|
eval "o=\$$N"
|
|
|
|
git cat-file -t $o && {
|
|
|
|
echo Gaah $N
|
|
|
|
gaah=$N
|
|
|
|
break
|
|
|
|
}
|
|
|
|
done
|
|
|
|
test -z "$gaah"
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
mkdir -p A/B &&
|
|
|
|
echo rat >C &&
|
|
|
|
echo ox >A/D &&
|
|
|
|
echo tiger >A/B/E &&
|
|
|
|
git add . &&
|
|
|
|
|
|
|
|
test_tick && git commit -m rabbit &&
|
2015-12-22 15:05:48 +00:00
|
|
|
H=$(git rev-parse --verify HEAD) &&
|
|
|
|
A=$(git rev-parse --verify HEAD:A) &&
|
|
|
|
B=$(git rev-parse --verify HEAD:A/B) &&
|
|
|
|
C=$(git rev-parse --verify HEAD:C) &&
|
|
|
|
D=$(git rev-parse --verify HEAD:A/D) &&
|
|
|
|
E=$(git rev-parse --verify HEAD:A/B/E) &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
check_fsck &&
|
|
|
|
|
2009-02-28 20:12:57 +00:00
|
|
|
test_chmod +x C &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
git add C &&
|
|
|
|
test_tick && git commit -m dragon &&
|
2015-12-22 15:05:48 +00:00
|
|
|
L=$(git rev-parse --verify HEAD) &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
check_fsck &&
|
|
|
|
|
|
|
|
rm -f C A/B/E &&
|
|
|
|
echo snake >F &&
|
|
|
|
echo horse >A/G &&
|
|
|
|
git add F A/G &&
|
|
|
|
test_tick && git commit -a -m sheep &&
|
2015-12-22 15:05:48 +00:00
|
|
|
F=$(git rev-parse --verify HEAD:F) &&
|
|
|
|
G=$(git rev-parse --verify HEAD:A/G) &&
|
|
|
|
I=$(git rev-parse --verify HEAD:A) &&
|
|
|
|
J=$(git rev-parse --verify HEAD) &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
check_fsck &&
|
|
|
|
|
|
|
|
rm -f A/G &&
|
|
|
|
test_tick && git commit -a -m monkey &&
|
2015-12-22 15:05:48 +00:00
|
|
|
K=$(git rev-parse --verify HEAD) &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
check_fsck &&
|
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
2007-01-22 05:29:44 +00:00
|
|
|
git prune &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
|
|
|
check_fsck &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 4 output
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
'
|
|
|
|
|
2022-03-17 18:08:39 +00:00
|
|
|
test_expect_success 'correct usage on sub-command -h' '
|
|
|
|
test_expect_code 129 git reflog expire -h >err &&
|
|
|
|
grep "git reflog expire" err
|
|
|
|
'
|
|
|
|
|
2022-03-17 18:08:40 +00:00
|
|
|
test_expect_success 'correct usage on "git reflog show -h"' '
|
|
|
|
test_expect_code 129 git reflog show -h >err &&
|
|
|
|
grep -F "git reflog [show]" err
|
|
|
|
'
|
|
|
|
|
2022-03-17 18:08:39 +00:00
|
|
|
test_expect_success 'pass through -- to sub-command' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
test_commit -C repo message --a-file contents dash-tag &&
|
|
|
|
|
|
|
|
git -C repo reflog show -- --does-not-exist >out &&
|
|
|
|
test_must_be_empty out &&
|
|
|
|
git -C repo reflog show >expect &&
|
|
|
|
git -C repo reflog show -- --a-file >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
test_expect_success rewind '
|
|
|
|
test_tick && git reset --hard HEAD~2 &&
|
|
|
|
test -f C &&
|
|
|
|
test -f A/B/E &&
|
|
|
|
! test -f F &&
|
|
|
|
! test -f A/G &&
|
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
2007-01-22 05:29:44 +00:00
|
|
|
git prune &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 5 output
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'corrupt and check' '
|
|
|
|
|
|
|
|
corrupt $F &&
|
|
|
|
check_fsck "missing blob $F"
|
|
|
|
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'reflog expire --dry-run should not touch reflog' '
|
|
|
|
|
|
|
|
git reflog expire --dry-run \
|
|
|
|
--expire=$(($test_tick - 10000)) \
|
|
|
|
--expire-unreachable=$(($test_tick - 10000)) \
|
|
|
|
--stale-fix \
|
|
|
|
--all &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 5 output &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
|
|
|
|
check_fsck "missing blob $F"
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'reflog expire' '
|
|
|
|
|
|
|
|
git reflog expire --verbose \
|
|
|
|
--expire=$(($test_tick - 10000)) \
|
|
|
|
--expire-unreachable=$(($test_tick - 10000)) \
|
|
|
|
--stale-fix \
|
|
|
|
--all &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 2 output &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
|
|
|
|
check_fsck "dangling commit $K"
|
|
|
|
'
|
|
|
|
|
2021-02-10 16:11:38 +00:00
|
|
|
test_expect_success '--stale-fix handles missing objects generously' '
|
|
|
|
git -c core.logAllRefUpdates=false fast-import --date-format=now <<-EOS &&
|
|
|
|
commit refs/heads/stale-fix
|
|
|
|
mark :1
|
|
|
|
committer Author <a@uth.or> now
|
|
|
|
data <<EOF
|
|
|
|
start stale fix
|
|
|
|
EOF
|
|
|
|
M 100644 inline file
|
|
|
|
data <<EOF
|
|
|
|
contents
|
|
|
|
EOF
|
|
|
|
commit refs/heads/stale-fix
|
|
|
|
committer Author <a@uth.or> now
|
|
|
|
data <<EOF
|
|
|
|
stale fix branch tip
|
|
|
|
EOF
|
|
|
|
from :1
|
|
|
|
EOS
|
|
|
|
|
|
|
|
parent_oid=$(git rev-parse stale-fix^) &&
|
|
|
|
test_when_finished "recover $parent_oid" &&
|
|
|
|
corrupt $parent_oid &&
|
|
|
|
git reflog expire --stale-fix
|
|
|
|
'
|
|
|
|
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
test_expect_success 'prune and fsck' '
|
|
|
|
|
2007-01-22 05:29:44 +00:00
|
|
|
git prune &&
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
check_fsck &&
|
|
|
|
|
|
|
|
check_have A B C D E H L &&
|
|
|
|
check_dont_have F G I J K
|
|
|
|
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'recover and check' '
|
|
|
|
|
|
|
|
recover $F &&
|
|
|
|
check_fsck "dangling blob $F"
|
|
|
|
|
|
|
|
'
|
|
|
|
|
2008-08-11 06:21:25 +00:00
|
|
|
test_expect_success 'delete' '
|
2007-10-17 01:50:45 +00:00
|
|
|
echo 1 > C &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m rat C &&
|
|
|
|
|
|
|
|
echo 2 > C &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m ox C &&
|
|
|
|
|
|
|
|
echo 3 > C &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m tiger C &&
|
|
|
|
|
2010-10-31 01:46:54 +00:00
|
|
|
HEAD_entry_count=$(git reflog | wc -l) &&
|
2020-11-18 23:44:21 +00:00
|
|
|
main_entry_count=$(git reflog show main | wc -l) &&
|
2008-08-09 23:33:29 +00:00
|
|
|
|
|
|
|
test $HEAD_entry_count = 5 &&
|
2020-11-18 23:44:21 +00:00
|
|
|
test $main_entry_count = 5 &&
|
2008-08-09 23:33:29 +00:00
|
|
|
|
2007-10-17 01:50:45 +00:00
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog delete main@{1} &&
|
|
|
|
git reflog show main > output &&
|
|
|
|
test_line_count = $(($main_entry_count - 1)) output &&
|
2008-08-09 23:33:29 +00:00
|
|
|
test $HEAD_entry_count = $(git reflog | wc -l) &&
|
2007-10-17 01:50:45 +00:00
|
|
|
! grep ox < output &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
main_entry_count=$(wc -l < output) &&
|
2008-08-09 23:33:29 +00:00
|
|
|
|
|
|
|
git reflog delete HEAD@{1} &&
|
|
|
|
test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) &&
|
2020-11-18 23:44:21 +00:00
|
|
|
test $main_entry_count = $(git reflog show main | wc -l) &&
|
2008-08-09 23:33:29 +00:00
|
|
|
|
2010-10-31 01:46:54 +00:00
|
|
|
HEAD_entry_count=$(git reflog | wc -l) &&
|
2008-08-09 23:33:29 +00:00
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog delete main@{07.04.2005.15:15:00.-0700} &&
|
|
|
|
git reflog show main > output &&
|
|
|
|
test_line_count = $(($main_entry_count - 1)) output &&
|
2007-10-17 01:50:45 +00:00
|
|
|
! grep dragon < output
|
2008-02-23 06:54:37 +00:00
|
|
|
|
|
|
|
'
|
|
|
|
|
2010-02-27 03:50:03 +00:00
|
|
|
test_expect_success 'rewind2' '
|
|
|
|
|
|
|
|
test_tick && git reset --hard HEAD~2 &&
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 4 output
|
2010-02-27 03:50:03 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--expire=never' '
|
|
|
|
|
|
|
|
git reflog expire --verbose \
|
|
|
|
--expire=never \
|
|
|
|
--expire-unreachable=never \
|
|
|
|
--all &&
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 4 output
|
2010-02-27 03:50:03 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'gc.reflogexpire=never' '
|
2019-03-15 15:59:55 +00:00
|
|
|
test_config gc.reflogexpire never &&
|
|
|
|
test_config gc.reflogexpireunreachable never &&
|
2010-02-27 03:50:03 +00:00
|
|
|
|
2019-03-28 16:14:33 +00:00
|
|
|
git reflog expire --verbose --all >output &&
|
|
|
|
test_line_count = 9 output &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-27 22:57:08 +00:00
|
|
|
test_line_count = 4 output
|
2010-02-27 03:50:03 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'gc.reflogexpire=false' '
|
2019-03-15 15:59:55 +00:00
|
|
|
test_config gc.reflogexpire false &&
|
|
|
|
test_config gc.reflogexpireunreachable false &&
|
2010-02-27 03:50:03 +00:00
|
|
|
|
|
|
|
git reflog expire --verbose --all &&
|
2020-11-18 23:44:21 +00:00
|
|
|
git reflog refs/heads/main >output &&
|
2019-03-15 15:59:55 +00:00
|
|
|
test_line_count = 4 output
|
2010-02-27 03:50:03 +00:00
|
|
|
|
|
|
|
'
|
|
|
|
|
2019-03-15 15:59:56 +00:00
|
|
|
test_expect_success 'git reflog expire unknown reference' '
|
|
|
|
test_config gc.reflogexpire never &&
|
|
|
|
test_config gc.reflogexpireunreachable never &&
|
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
test_must_fail git reflog expire main@{123} 2>stderr &&
|
2023-10-31 05:23:30 +00:00
|
|
|
test_grep "points nowhere" stderr &&
|
2019-03-15 15:59:56 +00:00
|
|
|
test_must_fail git reflog expire does-not-exist 2>stderr &&
|
2023-10-31 05:23:30 +00:00
|
|
|
test_grep "points nowhere" stderr
|
2019-03-15 15:59:56 +00:00
|
|
|
'
|
|
|
|
|
2014-05-06 22:45:53 +00:00
|
|
|
test_expect_success 'checkout should not delete log for packed ref' '
|
2020-11-18 23:44:21 +00:00
|
|
|
test $(git reflog main | wc -l) = 4 &&
|
2014-05-06 22:45:53 +00:00
|
|
|
git branch foo &&
|
|
|
|
git pack-refs --all &&
|
|
|
|
git checkout foo &&
|
2020-11-18 23:44:21 +00:00
|
|
|
test $(git reflog main | wc -l) = 4
|
2014-05-06 22:45:53 +00:00
|
|
|
'
|
|
|
|
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
test_expect_success 'stale dirs do not cause d/f conflicts (reflogs on)' '
|
2014-11-09 01:59:18 +00:00
|
|
|
test_when_finished "git branch -d one || git branch -d one/two" &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git branch one/two main &&
|
|
|
|
echo "one/two@{0} branch: Created from main" >expect &&
|
2014-11-09 01:59:18 +00:00
|
|
|
git log -g --format="%gd %gs" one/two >actual &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
test_cmp expect actual &&
|
2014-11-09 01:59:18 +00:00
|
|
|
git branch -d one/two &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
|
2014-11-09 01:59:18 +00:00
|
|
|
# now logs/refs/heads/one is a stale directory, but
|
|
|
|
# we should move it out of the way to create "one" reflog
|
2020-11-18 23:44:21 +00:00
|
|
|
git branch one main &&
|
|
|
|
echo "one@{0} branch: Created from main" >expect &&
|
2014-11-09 01:59:18 +00:00
|
|
|
git log -g --format="%gd %gs" one >actual &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' '
|
2014-11-09 01:59:18 +00:00
|
|
|
test_when_finished "git branch -d one || git branch -d one/two" &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
|
2020-11-18 23:44:21 +00:00
|
|
|
git branch one/two main &&
|
|
|
|
echo "one/two@{0} branch: Created from main" >expect &&
|
2014-11-09 01:59:18 +00:00
|
|
|
git log -g --format="%gd %gs" one/two >actual &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
test_cmp expect actual &&
|
2014-11-09 01:59:18 +00:00
|
|
|
git branch -d one/two &&
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
|
2014-11-09 01:59:18 +00:00
|
|
|
# same as before, but we only create a reflog for "one" if
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
# it already exists, which it does not
|
2020-11-18 23:44:21 +00:00
|
|
|
git -c core.logallrefupdates=false branch one main &&
|
2014-11-09 01:59:18 +00:00
|
|
|
git log -g --format="%gd %gs" one >actual &&
|
tests: use 'test_must_be_empty' instead of 'test_cmp <empty> <out>'
Using 'test_must_be_empty' is shorter and more idiomatic than
>empty &&
test_cmp empty out
as it saves the creation of an empty file. Furthermore, sometimes the
expected empty file doesn't have such a descriptive name like 'empty',
and its creation is far away from the place where it's finally used
for comparison (e.g. in 't7600-merge.sh', where two expected empty
files are created in the 'setup' test, but are used only about 500
lines later).
These cases were found by instrumenting 'test_cmp' to error out the
test script when it's used to compare empty files, and then converted
manually.
Note that even after this patch there still remain a lot of cases
where we use 'test_cmp' to check empty files:
- Sometimes the expected output is not hard-coded in the test, but
'test_cmp' is used to ensure that two similar git commands produce
the same output, and that output happens to be empty, e.g. the
test 'submodule update --merge - ignores --merge for new
submodules' in 't7406-submodule-update.sh'.
- Repetitive common tasks, including preparing the expected results
and running 'test_cmp', are often extracted into a helper
function, and some of this helper's callsites expect no output.
- For the same reason as above, the whole 'test_expect_success'
block is within a helper function, e.g. in 't3070-wildmatch.sh'.
- Or 'test_cmp' is invoked in a loop, e.g. the test 'cvs update
(-p)' in 't9400-git-cvsserver-server.sh'.
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-19 21:57:25 +00:00
|
|
|
test_must_be_empty actual
|
ignore stale directories when checking reflog existence
When we update a ref, we have two rules for whether or not
we actually update the reflog:
1. If the reflog already exists, we will always append to
it.
2. If log_all_ref_updates is set, we will create a new
reflog file if necessary.
We do the existence check by trying to open the reflog file,
either with or without O_CREAT (depending on log_all_ref_updates).
If it fails, then we check errno to see what happened.
If we were not using O_CREAT and we got ENOENT, the file
doesn't exist, and we return success (there isn't a reflog
already, and we were not told to make a new one).
If we get EISDIR, then there is likely a stale directory
that needs to be removed (e.g., there used to be "foo/bar",
it was deleted, and the directory "foo" was left. Now we
want to create the ref "foo"). If O_CREAT is set, then we
catch this case, try to remove the directory, and retry our
open. So far so good.
But if we get EISDIR and O_CREAT is not set, then we treat
this as any other error, which is not right. Like ENOENT,
EISDIR is an indication that we do not have a reflog, and we
should silently return success (we were not told to create
it). Instead, the current code reports this as an error, and
we fail to update the ref at all.
Note that this is relatively unlikely to happen, as you
would have to have had reflogs turned on, and then later
turned them off (it could also happen due to a bug in fetch,
but that was fixed in the previous commit). However, it's
quite easy to fix: we just need to treat EISDIR like ENOENT
for the non-O_CREAT case, and silently return (note that
this early return means we can also simplify the O_CREAT
case).
Our new tests cover both cases (O_CREAT and non-O_CREAT).
The first one already worked, of course.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-04 13:24:53 +00:00
|
|
|
'
|
|
|
|
|
2016-01-05 21:12:10 +00:00
|
|
|
test_expect_success 'no segfaults for reflog containing non-commit sha1s' '
|
|
|
|
git update-ref --create-reflog -m "Creating ref" \
|
|
|
|
refs/tests/tree-in-reflog HEAD &&
|
|
|
|
git update-ref -m "Forcing tree" refs/tests/tree-in-reflog HEAD^{tree} &&
|
|
|
|
git update-ref -m "Restoring to commit" refs/tests/tree-in-reflog HEAD &&
|
|
|
|
git reflog refs/tests/tree-in-reflog
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_failure 'reflog with non-commit entries displays all entries' '
|
|
|
|
git reflog refs/tests/tree-in-reflog >actual &&
|
|
|
|
test_line_count = 3 actual
|
|
|
|
'
|
|
|
|
|
2016-06-03 20:42:35 +00:00
|
|
|
test_expect_success 'continue walking past root commits' '
|
|
|
|
git init orphanage &&
|
|
|
|
(
|
|
|
|
cd orphanage &&
|
|
|
|
cat >expect <<-\EOF &&
|
|
|
|
HEAD@{0} commit (initial): orphan2-1
|
|
|
|
HEAD@{1} commit: orphan1-2
|
|
|
|
HEAD@{2} commit (initial): orphan1-1
|
|
|
|
HEAD@{3} commit (initial): initial
|
|
|
|
EOF
|
|
|
|
test_commit initial &&
|
|
|
|
git checkout --orphan orphan1 &&
|
|
|
|
test_commit orphan1-1 &&
|
|
|
|
test_commit orphan1-2 &&
|
|
|
|
git checkout --orphan orphan2 &&
|
|
|
|
test_commit orphan2-1 &&
|
|
|
|
git log -g --format="%gd %gs" >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2018-10-21 08:08:59 +00:00
|
|
|
test_expect_success 'expire with multiple worktrees' '
|
|
|
|
git init main-wt &&
|
|
|
|
(
|
|
|
|
cd main-wt &&
|
|
|
|
test_tick &&
|
|
|
|
test_commit foo &&
|
|
|
|
git worktree add link-wt &&
|
|
|
|
test_tick &&
|
|
|
|
test_commit -C link-wt foobar &&
|
|
|
|
test_tick &&
|
|
|
|
git reflog expire --verbose --all --expire=$test_tick &&
|
2022-02-09 11:29:39 +00:00
|
|
|
test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD >actual &&
|
|
|
|
test_must_be_empty actual
|
2018-10-21 08:08:59 +00:00
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2023-10-28 11:58:41 +00:00
|
|
|
test_expect_success 'expire one of multiple worktrees' '
|
|
|
|
git init main-wt2 &&
|
|
|
|
(
|
|
|
|
cd main-wt2 &&
|
|
|
|
test_tick &&
|
|
|
|
test_commit foo &&
|
|
|
|
git worktree add link-wt &&
|
|
|
|
test_tick &&
|
|
|
|
test_commit -C link-wt foobar &&
|
|
|
|
test_tick &&
|
|
|
|
test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD \
|
|
|
|
>expect-link-wt &&
|
|
|
|
git reflog expire --verbose --all --expire=$test_tick \
|
|
|
|
--single-worktree &&
|
|
|
|
test-tool ref-store worktree:main for-each-reflog-ent HEAD \
|
|
|
|
>actual-main &&
|
|
|
|
test-tool ref-store worktree:link-wt for-each-reflog-ent HEAD \
|
|
|
|
>actual-link-wt &&
|
|
|
|
test_must_be_empty actual-main &&
|
|
|
|
test_cmp expect-link-wt actual-link-wt
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2023-11-29 07:24:53 +00:00
|
|
|
test_expect_success 'empty reflog' '
|
2022-03-10 22:56:11 +00:00
|
|
|
test_when_finished "rm -rf empty" &&
|
|
|
|
git init empty &&
|
|
|
|
test_commit -C empty A &&
|
2023-11-29 07:24:53 +00:00
|
|
|
test-tool ref-store main create-reflog refs/heads/foo &&
|
2022-03-10 22:56:11 +00:00
|
|
|
git -C empty reflog expire --all 2>err &&
|
|
|
|
test_must_be_empty err
|
|
|
|
'
|
|
|
|
|
2024-02-21 12:37:47 +00:00
|
|
|
test_expect_success 'list reflogs' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
git reflog list >actual &&
|
|
|
|
test_must_be_empty actual &&
|
|
|
|
|
|
|
|
test_commit A &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
refs/heads/main
|
|
|
|
EOF
|
|
|
|
git reflog list >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
git branch b &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
refs/heads/b
|
|
|
|
refs/heads/main
|
|
|
|
EOF
|
|
|
|
git reflog list >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'list reflogs with worktree' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
|
|
|
|
test_commit A &&
|
|
|
|
git worktree add wt &&
|
|
|
|
git -c core.logAllRefUpdates=always \
|
|
|
|
update-ref refs/worktree/main HEAD &&
|
|
|
|
git -c core.logAllRefUpdates=always \
|
|
|
|
update-ref refs/worktree/per-worktree HEAD &&
|
|
|
|
git -c core.logAllRefUpdates=always -C wt \
|
|
|
|
update-ref refs/worktree/per-worktree HEAD &&
|
|
|
|
git -c core.logAllRefUpdates=always -C wt \
|
|
|
|
update-ref refs/worktree/worktree HEAD &&
|
|
|
|
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
refs/heads/main
|
|
|
|
refs/heads/wt
|
|
|
|
refs/worktree/main
|
|
|
|
refs/worktree/per-worktree
|
|
|
|
EOF
|
|
|
|
git reflog list >actual &&
|
|
|
|
test_cmp expect actual &&
|
|
|
|
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
refs/heads/main
|
|
|
|
refs/heads/wt
|
|
|
|
refs/worktree/per-worktree
|
|
|
|
refs/worktree/worktree
|
|
|
|
EOF
|
|
|
|
git -C wt reflog list >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'reflog list returns error with additional args' '
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
error: list does not accept arguments: ${SQ}bogus${SQ}
|
|
|
|
EOF
|
|
|
|
test_must_fail git reflog list bogus 2>err &&
|
|
|
|
test_cmp expect err
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'reflog for symref with unborn target can be listed' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
test_commit A &&
|
|
|
|
git symbolic-ref HEAD refs/heads/unborn &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
refs/heads/main
|
|
|
|
EOF
|
|
|
|
git reflog list >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'reflog with invalid object ID can be listed' '
|
|
|
|
test_when_finished "rm -rf repo" &&
|
|
|
|
git init repo &&
|
|
|
|
(
|
|
|
|
cd repo &&
|
|
|
|
test_commit A &&
|
|
|
|
test-tool ref-store main update-ref msg refs/heads/missing \
|
|
|
|
$(test_oid deadbeef) "$ZERO_OID" REF_SKIP_OID_VERIFICATION &&
|
|
|
|
cat >expect <<-EOF &&
|
|
|
|
HEAD
|
|
|
|
refs/heads/main
|
|
|
|
refs/heads/missing
|
|
|
|
EOF
|
|
|
|
git reflog list >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
)
|
|
|
|
'
|
|
|
|
|
reflog expire --fix-stale
The logic in an earlier round to detect reflog entries that
point at a broken commit was not sufficient. Just like we do
not trust presense of a commit during pack transfer (we trust
only our refs), we should not trust a commit's presense, even if
the tree of that commit is complete.
A repository that had reflog enabled on some of the refs that
was rewound and then run git-repack or git-prune from older
versions of git can have reflog entries that point at a commit
that still exist but lack commits (or trees and blobs needed for
that commit) between it and some commit that is reachable from
one of the refs.
This revamps the logic -- the definition of "broken commit"
becomes: a commit that is not reachable from any of the refs and
there is a missing object among the commit, tree, or blob
objects reachable from it that is not reachable from any of the
refs. Entries in the reflog that refer to such a commit are
expired.
Since this computation involves traversing all the reachable
objects, i.e. it has the same cost as 'git prune', it is enabled
only when a new option --fix-stale. Fortunately, once this is
run, we should not have to ever worry about missing objects,
because the current prune and pack-objects know about reflogs
and protect objects referred by them.
Unfortunately, this will be absolutely necessary to help people
migrate to the newer prune and repack.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-01-06 10:16:19 +00:00
|
|
|
test_done
|