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 13:16:19 +03:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2007 Junio C Hamano
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='Test prune and reflog expiration'
|
2020-11-19 02:44:21 +03: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-19 02:44:19 +03:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
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 13:16:19 +03: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 08:16:15 +03: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 13:16:19 +03:00
|
|
|
case "$1" in
|
|
|
|
'')
|
2018-11-10 08:16:15 +03: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 13:16:19 +03:00
|
|
|
*)
|
2018-11-10 08:16:15 +03:00
|
|
|
test_i18ngrep "$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 13:16:19 +03:00
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
corrupt () {
|
2019-06-29 01:59:20 +03: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 13:16:19 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
recover () {
|
2019-06-29 01:59:20 +03: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 13:16:19 +03:00
|
|
|
mkdir -p .git/objects/$aa
|
2019-06-29 01:59:20 +03: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 13:16:19 +03: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 18:05:48 +03: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 13:16:19 +03:00
|
|
|
check_fsck &&
|
|
|
|
|
2009-02-28 23:12:57 +03: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 13:16:19 +03:00
|
|
|
git add C &&
|
|
|
|
test_tick && git commit -m dragon &&
|
2015-12-22 18:05:48 +03: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 13:16:19 +03: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 18:05:48 +03: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 13:16:19 +03:00
|
|
|
check_fsck &&
|
|
|
|
|
|
|
|
rm -f A/G &&
|
|
|
|
test_tick && git commit -a -m monkey &&
|
2015-12-22 18:05:48 +03: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 13:16:19 +03:00
|
|
|
check_fsck &&
|
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
2007-01-22 08:29:44 +03: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 13:16:19 +03:00
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
|
|
|
check_fsck &&
|
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03: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 13:16:19 +03: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 08:29:44 +03: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 13:16:19 +03:00
|
|
|
|
|
|
|
check_have A B C D E F G H I J K L &&
|
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03: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 13:16:19 +03: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-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03: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 13:16:19 +03: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-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03: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 13:16:19 +03:00
|
|
|
|
|
|
|
check_fsck "dangling commit $K"
|
|
|
|
'
|
|
|
|
|
2021-02-10 19:11:38 +03: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 13:16:19 +03:00
|
|
|
test_expect_success 'prune and fsck' '
|
|
|
|
|
2007-01-22 08:29:44 +03: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 13:16:19 +03: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 10:21:25 +04:00
|
|
|
test_expect_success 'delete' '
|
2007-10-17 05:50:45 +04: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 04:46:54 +03:00
|
|
|
HEAD_entry_count=$(git reflog | wc -l) &&
|
2020-11-19 02:44:21 +03:00
|
|
|
main_entry_count=$(git reflog show main | wc -l) &&
|
2008-08-10 03:33:29 +04:00
|
|
|
|
|
|
|
test $HEAD_entry_count = 5 &&
|
2020-11-19 02:44:21 +03:00
|
|
|
test $main_entry_count = 5 &&
|
2008-08-10 03:33:29 +04:00
|
|
|
|
2007-10-17 05:50:45 +04:00
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog delete main@{1} &&
|
|
|
|
git reflog show main > output &&
|
|
|
|
test_line_count = $(($main_entry_count - 1)) output &&
|
2008-08-10 03:33:29 +04:00
|
|
|
test $HEAD_entry_count = $(git reflog | wc -l) &&
|
2007-10-17 05:50:45 +04:00
|
|
|
! grep ox < output &&
|
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
main_entry_count=$(wc -l < output) &&
|
2008-08-10 03:33:29 +04:00
|
|
|
|
|
|
|
git reflog delete HEAD@{1} &&
|
|
|
|
test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) &&
|
2020-11-19 02:44:21 +03:00
|
|
|
test $main_entry_count = $(git reflog show main | wc -l) &&
|
2008-08-10 03:33:29 +04:00
|
|
|
|
2010-10-31 04:46:54 +03:00
|
|
|
HEAD_entry_count=$(git reflog | wc -l) &&
|
2008-08-10 03:33:29 +04:00
|
|
|
|
2020-11-19 02:44:21 +03: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 05:50:45 +04:00
|
|
|
! grep dragon < output
|
2008-02-23 09:54:37 +03:00
|
|
|
|
|
|
|
'
|
|
|
|
|
2010-02-27 06:50:03 +03:00
|
|
|
test_expect_success 'rewind2' '
|
|
|
|
|
|
|
|
test_tick && git reset --hard HEAD~2 &&
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03:00
|
|
|
test_line_count = 4 output
|
2010-02-27 06:50:03 +03:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--expire=never' '
|
|
|
|
|
|
|
|
git reflog expire --verbose \
|
|
|
|
--expire=never \
|
|
|
|
--expire-unreachable=never \
|
|
|
|
--all &&
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03:00
|
|
|
test_line_count = 4 output
|
2010-02-27 06:50:03 +03:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'gc.reflogexpire=never' '
|
2019-03-15 18:59:55 +03:00
|
|
|
test_config gc.reflogexpire never &&
|
|
|
|
test_config gc.reflogexpireunreachable never &&
|
2010-02-27 06:50:03 +03:00
|
|
|
|
2019-03-28 19:14:33 +03:00
|
|
|
git reflog expire --verbose --all >output &&
|
|
|
|
test_line_count = 9 output &&
|
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2015-07-28 01:57:08 +03:00
|
|
|
test_line_count = 4 output
|
2010-02-27 06:50:03 +03:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'gc.reflogexpire=false' '
|
2019-03-15 18:59:55 +03:00
|
|
|
test_config gc.reflogexpire false &&
|
|
|
|
test_config gc.reflogexpireunreachable false &&
|
2010-02-27 06:50:03 +03:00
|
|
|
|
|
|
|
git reflog expire --verbose --all &&
|
2020-11-19 02:44:21 +03:00
|
|
|
git reflog refs/heads/main >output &&
|
2019-03-15 18:59:55 +03:00
|
|
|
test_line_count = 4 output
|
2010-02-27 06:50:03 +03:00
|
|
|
|
|
|
|
'
|
|
|
|
|
2019-03-15 18:59:56 +03:00
|
|
|
test_expect_success 'git reflog expire unknown reference' '
|
|
|
|
test_config gc.reflogexpire never &&
|
|
|
|
test_config gc.reflogexpireunreachable never &&
|
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
test_must_fail git reflog expire main@{123} 2>stderr &&
|
2019-03-15 18:59:56 +03:00
|
|
|
test_i18ngrep "points nowhere" stderr &&
|
|
|
|
test_must_fail git reflog expire does-not-exist 2>stderr &&
|
|
|
|
test_i18ngrep "points nowhere" stderr
|
|
|
|
'
|
|
|
|
|
2014-05-07 02:45:53 +04:00
|
|
|
test_expect_success 'checkout should not delete log for packed ref' '
|
2020-11-19 02:44:21 +03:00
|
|
|
test $(git reflog main | wc -l) = 4 &&
|
2014-05-07 02:45:53 +04:00
|
|
|
git branch foo &&
|
|
|
|
git pack-refs --all &&
|
|
|
|
git checkout foo &&
|
2020-11-19 02:44:21 +03:00
|
|
|
test $(git reflog main | wc -l) = 4
|
2014-05-07 02:45:53 +04: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 16:24:53 +03:00
|
|
|
test_expect_success 'stale dirs do not cause d/f conflicts (reflogs on)' '
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
git branch one/two main &&
|
|
|
|
echo "one/two@{0} branch: Created from main" >expect &&
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
test_cmp expect actual &&
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
|
2014-11-09 04:59:18 +03: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-19 02:44:21 +03:00
|
|
|
git branch one main &&
|
|
|
|
echo "one@{0} branch: Created from main" >expect &&
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'stale dirs do not cause d/f conflicts (reflogs off)' '
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
|
2020-11-19 02:44:21 +03:00
|
|
|
git branch one/two main &&
|
|
|
|
echo "one/two@{0} branch: Created from main" >expect &&
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
test_cmp expect actual &&
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
|
2014-11-09 04:59:18 +03: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 16:24:53 +03:00
|
|
|
# it already exists, which it does not
|
2020-11-19 02:44:21 +03:00
|
|
|
git -c core.logallrefupdates=false branch one main &&
|
2014-11-09 04:59:18 +03: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-20 00:57:25 +03: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 16:24:53 +03:00
|
|
|
'
|
|
|
|
|
for_each_reflog_ent_reverse: fix newlines on block boundaries
When we read a reflog file in reverse, we read whole chunks
of BUFSIZ bytes, then loop over the buffer, parsing any
lines we find. We find the beginning of each line by looking
for the newline from the previous line. If we don't find
one, we know that we are either at the beginning of
the file, or that we have to read another block.
In the latter case, we stuff away what we have into a
strbuf, read another block, and continue our parse. But we
missed one case here. If we did find a newline, and it is at
the beginning of the block, we must also stuff that newline
into the strbuf, as it belongs to the block we are about to
read.
The minimal fix here would be to add this special case to
the conditional that checks whether we found a newline.
But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and
then at the end of each loop, stuff away any leftovers if
necessary. That lets us fold this special-case in with the
more common "we ended in the middle of a line" case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-05 04:28:54 +03:00
|
|
|
# Triggering the bug detected by this test requires a newline to fall
|
|
|
|
# exactly BUFSIZ-1 bytes from the end of the file. We don't know
|
|
|
|
# what that value is, since it's platform dependent. However, if
|
|
|
|
# we choose some value N, we also catch any D which divides N evenly
|
|
|
|
# (since we will read backwards in chunks of D). So we choose 8K,
|
|
|
|
# which catches glibc (with an 8K BUFSIZ) and *BSD (1K).
|
|
|
|
#
|
|
|
|
# Each line is 114 characters, so we need 75 to still have a few before the
|
|
|
|
# last 8K. The 89-character padding on the final entry lines up our
|
|
|
|
# newline exactly.
|
2019-06-29 01:59:20 +03:00
|
|
|
test_expect_success SHA1 'parsing reverse reflogs at BUFSIZ boundaries' '
|
for_each_reflog_ent_reverse: fix newlines on block boundaries
When we read a reflog file in reverse, we read whole chunks
of BUFSIZ bytes, then loop over the buffer, parsing any
lines we find. We find the beginning of each line by looking
for the newline from the previous line. If we don't find
one, we know that we are either at the beginning of
the file, or that we have to read another block.
In the latter case, we stuff away what we have into a
strbuf, read another block, and continue our parse. But we
missed one case here. If we did find a newline, and it is at
the beginning of the block, we must also stuff that newline
into the strbuf, as it belongs to the block we are about to
read.
The minimal fix here would be to add this special case to
the conditional that checks whether we found a newline.
But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and
then at the end of each loop, stuff away any leftovers if
necessary. That lets us fold this special-case in with the
more common "we ended in the middle of a line" case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-05 04:28:54 +03:00
|
|
|
git checkout -b reflogskip &&
|
2019-06-29 01:59:20 +03:00
|
|
|
zf=$(test_oid zero_2) &&
|
for_each_reflog_ent_reverse: fix newlines on block boundaries
When we read a reflog file in reverse, we read whole chunks
of BUFSIZ bytes, then loop over the buffer, parsing any
lines we find. We find the beginning of each line by looking
for the newline from the previous line. If we don't find
one, we know that we are either at the beginning of
the file, or that we have to read another block.
In the latter case, we stuff away what we have into a
strbuf, read another block, and continue our parse. But we
missed one case here. If we did find a newline, and it is at
the beginning of the block, we must also stuff that newline
into the strbuf, as it belongs to the block we are about to
read.
The minimal fix here would be to add this special case to
the conditional that checks whether we found a newline.
But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and
then at the end of each loop, stuff away any leftovers if
necessary. That lets us fold this special-case in with the
more common "we ended in the middle of a line" case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-05 04:28:54 +03:00
|
|
|
ident="abc <xyz> 0000000001 +0000" &&
|
|
|
|
for i in $(test_seq 1 75); do
|
2019-06-29 01:59:20 +03:00
|
|
|
printf "$zf%02d $zf%02d %s\t" $i $(($i+1)) "$ident" &&
|
for_each_reflog_ent_reverse: fix newlines on block boundaries
When we read a reflog file in reverse, we read whole chunks
of BUFSIZ bytes, then loop over the buffer, parsing any
lines we find. We find the beginning of each line by looking
for the newline from the previous line. If we don't find
one, we know that we are either at the beginning of
the file, or that we have to read another block.
In the latter case, we stuff away what we have into a
strbuf, read another block, and continue our parse. But we
missed one case here. If we did find a newline, and it is at
the beginning of the block, we must also stuff that newline
into the strbuf, as it belongs to the block we are about to
read.
The minimal fix here would be to add this special case to
the conditional that checks whether we found a newline.
But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and
then at the end of each loop, stuff away any leftovers if
necessary. That lets us fold this special-case in with the
more common "we ended in the middle of a line" case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-05 04:28:54 +03:00
|
|
|
if test $i = 75; then
|
|
|
|
for j in $(test_seq 1 89); do
|
|
|
|
printf X
|
|
|
|
done
|
|
|
|
else
|
|
|
|
printf X
|
|
|
|
fi &&
|
|
|
|
printf "\n"
|
|
|
|
done >.git/logs/refs/heads/reflogskip &&
|
|
|
|
git rev-parse reflogskip@{73} >actual &&
|
2019-06-29 01:59:20 +03:00
|
|
|
echo ${zf}03 >expect &&
|
for_each_reflog_ent_reverse: fix newlines on block boundaries
When we read a reflog file in reverse, we read whole chunks
of BUFSIZ bytes, then loop over the buffer, parsing any
lines we find. We find the beginning of each line by looking
for the newline from the previous line. If we don't find
one, we know that we are either at the beginning of
the file, or that we have to read another block.
In the latter case, we stuff away what we have into a
strbuf, read another block, and continue our parse. But we
missed one case here. If we did find a newline, and it is at
the beginning of the block, we must also stuff that newline
into the strbuf, as it belongs to the block we are about to
read.
The minimal fix here would be to add this special case to
the conditional that checks whether we found a newline.
But we can make the flow a little clearer by rearranging a
bit: we first handle lines that we are going to show, and
then at the end of each loop, stuff away any leftovers if
necessary. That lets us fold this special-case in with the
more common "we ended in the middle of a line" case.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-12-05 04:28:54 +03:00
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2016-01-06 00:12:10 +03: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
|
|
|
|
'
|
|
|
|
|
2021-08-02 19:53:33 +03:00
|
|
|
# This test takes a lock on an individual ref; this is not supported in
|
|
|
|
# reftable.
|
|
|
|
test_expect_success REFFILES 'reflog expire operates on symref not referrent' '
|
2018-06-22 12:23:59 +03:00
|
|
|
git branch --create-reflog the_symref &&
|
|
|
|
git branch --create-reflog referrent &&
|
2016-04-07 22:03:11 +03:00
|
|
|
git update-ref referrent HEAD &&
|
|
|
|
git symbolic-ref refs/heads/the_symref refs/heads/referrent &&
|
|
|
|
test_when_finished "rm -f .git/refs/heads/referrent.lock" &&
|
|
|
|
touch .git/refs/heads/referrent.lock &&
|
|
|
|
git reflog expire --expire=all the_symref
|
|
|
|
'
|
|
|
|
|
2016-06-03 23:42:35 +03: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 11:08:59 +03: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 &&
|
|
|
|
test_must_be_empty .git/worktrees/link-wt/logs/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 13:16:19 +03:00
|
|
|
test_done
|