git: Это свисающие коммиты?
В конце дан извлеченный скриншот из дерева ветвей SourceTree (в середине скриншота есть пробел)
В этом, #1
указывает на линию, которая раньше была ветвью 1.7.6.14.X
а также #2
указывает на текущее состояние той же ветви.
Коммит, на который ссылается #3
и предыдущие 8 коммитов на этой линии были ранее присоединены к ветке 1.7.6.14.X
, Затем другой разработчик предположительно проверил ту же ветку и сделал исправление, на которое указывает #4
, это #4
commit удалил прежние 9 коммитов из ветки 1.7.6.14.X
и оставил их висящими.
В результате филиал 1.7.6.14.X
теперь начинается с исходной точки ветвления, а не просто продолжается от коммита #3
,
Бег git fsck
с --unreachable
, --dangling
и т.д. не дает ошибок. Я старался --lost-found
также.
Тем не мение, git fsck <hash of commit #3>
создает пять висячих коммитов и целую кучу висячих тегов:
Checking object directories: 100% (256/256), done.
Checking objects: 100% (3148/3148), done.
dangling commit ec213...
dangling commit ab82a...
dangling commit 7d262...
dangling commit a6f06...
dangling commit 6674a...
У меня есть два вопроса:
Что могло быть причиной этой ситуации (например, филиал
#1
отстраняться)?Как я могу определить, есть ли похожие проблемы в других репозиториях? (без необходимости знать хеши отдельных коммитов, таких как
#3
)
Обновление:
Мы нашли ответ на вопрос (1). Ситуация была вызвана принудительным толчком к центральному репо, разработчиком, у которого был более ранний снимок ветви.
2 ответа
- как вы сказали; это вызвано использованием
git push --force
- Поскольку все ваши коммиты достижимы с помощью тега; мерзавец никогда не скажет, что они болтаются, так как они нет. Они никогда не будут потеряны или очищены, так как тег ссылается на них.
Что касается того, как найти эти (из-за отсутствия лучшего слова) висячие коммиты; Я не нашел ничего просто мерзавца, но придумал небольшой скрипт, который позволяет их обнаруживать. Может быть способ сделать это более производительным, но он делает свое дело:
for sha in $(git log --all --pretty=format:"%H")
do
if [ -z "$(git branch --contains $sha)" ]
then
echo "commit not on a branch: $sha"
fi
done
обратите внимание, я знаю, что тест -z ""
не очень чистый, но возвращаемое значение git branch
всегда 0...
Вот пост Линуса Торвальдса:
Что могло послужить причиной этой ситуации (то есть отделение № 1 отсоединилось)?
Висячие данные - это данные, которые хранятся в репозитории git, но недоступны.
Это означает, что у вас есть (добавленный или зафиксированный) контент, который недоступен в вашем хранилище (никакой коммит или ветвь не имеют или не указывают на этот контент)
Таким образом, ответ - да, все коммиты на ветви #1 не доступны ни из каких коммитов, кроме ветви #1.
Как я могу определить, есть ли похожие проблемы в других репозиториях?
(без необходимости знать хэши отдельных коммитов, таких как #3)
git fsck --full
Эта команда проверит весь висящий контент в вашем хранилище
В вашем хранилище может быть 2 вида висящего контента:
Свисающая капля
Изменения, внесенные в промежуточную область / индекс (после того, как вы git add
git вычислил SHA-1 и начал отслеживать содержимое), но так и не получил подтверждение.
Оборванный коммит
Фиксация (и), которая не связана ни с одной веткой или тегом ни напрямую, ни с кем-либо из его потомков.