Вернуться в историю к неповрежденной версии?

У меня поврежденный незакрепленный объект.

Я пробовал оформить заказ, вернуть, перебазировать и, возможно, еще несколько вещей, чтобы перейти к исходной фиксации. В каждом случае я запускал git fsck и по-прежнему имел ту же проблему:

> git fsck 
error: corrupt loose object '25a196217ebb6e341909205575f491022eafc4d9'
fatal: loose object 25a196217ebb6e341909205575f491022eafc4d9 (stored in .git/objects/25/a196217ebb6e341909205575f491022eafc4d9) is corrupt

есть ли способ избавиться от поврежденных объектов, не удаляя просто .git? У меня нет другой резервной копии, поэтому я не могу заменить поврежденный объект.

Это более узкий вопрос, возникший из-за этой ошибки git: коррумпирован свободный объект после перемещения каталога

обновление (1):

> git gc
Counting objects: 747, done.
Delta compression using up to 8 threads.
error: corrupt loose object '25a196217ebb6e341909205575f491022eafc4d9'
fatal: loose object 25a196217ebb6e341909205575f491022eafc4d9 (stored in .git/objects/25/a196217ebb6e341909205575f491022eafc4d9) is corrupt
error: failed to run repack

update (2): это не сработало. Удалить файл из репозитория git (история)

обновление (3): клонирование не сработало:

> git clone ../dynamicsCode_good/ .
Cloning into ....
done.
error: corrupt loose object '25a196217ebb6e341909205575f491022eafc4d9'
fatal: loose object 25a196217ebb6e341909205575f491022eafc4d9 (stored in .git/objects/25/a196217ebb6e341909205575f491022eafc4d9) is corrupt

файл. каталог пуст

update (4): удаление поврежденного объекта.

> git --version
git version 1.7.5.4


> rm -f .git/objects/25/a196217ebb6e341909205575f491022eafc4d9
13:42:57 ~/Dropbox/work/dev/dynamicsCode_torek 
> git fsck --full
missing blob 25a196217ebb6e341909205575f491022eafc4d9
dangling tree 64a970c878fef7deeeb4ce2ffc5e6234a72894ad
dangling tree 528e6c121fb8e56097462b2ebb9ec4de66388ce2

первый (начальный) комментарий. в этом комментарии даже нет поврежденного файла.

> git log |tail -5
commit 150ceebafb9c20769386cc7ffba07f6e6565fae6
Author: Kirill ...gmail.com>
Date:   Tue Sep 27 22:51:15 2011 -0400

    state takes input as input
checkout:

> git checkout -b 150ceebafb9c20769386cc7ffba07f6e6565fae6
Switched to a new branch '150ceebafb9c20769386cc7ffba07f6e6565fae6'

> git gc
Counting objects: 783, done.
error: unable to find 25a196217ebb6e341909205575f491022eafc4d9
Compressing objects: 100% (776/776), done.
fatal: unable to read 25a196217ebb6e341909205575f491022eafc4d9
error: failed to run repack
> git fsck --full
broken link from    tree 4668817140320ad2e04aa946d95dec2c3885d97b
              to    blob 25a196217ebb6e341909205575f491022eafc4d9
missing blob 25a196217ebb6e341909205575f491022eafc4d9
dangling tree 64a970c878fef7deeeb4ce2ffc5e6234a72894ad
dangling tree 528e6c121fb8e56097462b2ebb9ec4de66388ce2

Я также попробовал распаковать единственный объект в каталоге .git/objects/pack/. не помогло.

Я также клонировал это состояние в новый каталог:

> git gc
Counting objects: 662, done.
error: unable to find 25a196217ebb6e341909205575f491022eafc4d9
Compressing objects: 100% (656/656), done.
fatal: unable to read 25a196217ebb6e341909205575f491022eafc4d9
error: failed to run repack
14:40:34 ~/Dropbox/work/dev/dynamicsCode_torek_commit_clone 
> git fsck 
broken link from    tree b5ab6b287804d5069a3c8648ace38d9d9feac1a5
              to    blob 25a196217ebb6e341909205575f491022eafc4d9
dangling commit dad8edc620248d3911b7b1c0a99608a64e0288a3
missing blob 25a196217ebb6e341909205575f491022eafc4d9
dangling tree 64a970c878fef7deeeb4ce2ffc5e6234a72894ad
dangling commit ae2b2a9edb744d9e91aa78891c849d5a0040ea94
dangling commit 32ed79bd4ac70b118d046cb6093a4710562e95ba
dangling commit 7e45ef0c6ffc46401b1f82bcbf0f7e843abf9e31
dangling tree 528e6c121fb8e56097462b2ebb9ec4de66388ce2
14:40:40 ~/Dropbox/work/dev/dynamicsCode_torek_commit_clone 
> git branch 
* 150ceebafb9c20769386cc7ffba07f6e6565fae6

тоже не помогло.

Поврежденный файл tags из ctags. Мне это не нужно. странно, что я не могу восстановить git без этого файла. Самое главное, что из всех моих исследований я не вижу ни того, как это можно сделать, ни почему это невозможно.

update (5): оформление заказа без ветвления

> git checkout 150ceebafb9c20769386cc7ffba07f6e6565fae6
Note: checking out '150ceebafb9c20769386cc7ffba07f6e6565fae6'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 150ceeb... state takes input as input
16:41:40 ~/Dropbox/work/dev/dynamicsCode_torek_commit 
> git fsck --full
broken link from    tree 4668817140320ad2e04aa946d95dec2c3885d97b
              to    blob 25a196217ebb6e341909205575f491022eafc4d9
missing blob 25a196217ebb6e341909205575f491022eafc4d9
dangling tree 64a970c878fef7deeeb4ce2ffc5e6234a72894ad
dangling tree 528e6c121fb8e56097462b2ebb9ec4de66388ce2

person kirill_igum    schedule 07.04.2012    source источник
comment
Вы можете попробовать клонировать этот репозиторий. Клонирование должно переносить только необходимые объекты в новое репо, поэтому, пока этот свободный объект действительно не нужен для вашего клона, у вас может быть репозиторий без повреждений в вашем клоне.   -  person Mark Rushakoff    schedule 07.04.2012
comment
Если вы хотите удалить поврежденный объект, вы можете просто удалить его. Например. rm .git/objects/25/a196217ebb6e341909205575f491022eafc4d9 из корня репо. Но я не уверен, что произойдет, если на него будет ссылаться другой объект.   -  person svick    schedule 07.04.2012
comment
Клонирование @MarkRushakoff не сработало. см. обновление (3)   -  person kirill_igum    schedule 07.04.2012


Ответы (1)


Если вы удалите поврежденный объект вручную, git, как правило, позволит вам получить все остальное. Я намеренно испортил git blob (просто поставил несколько плохих байтов впереди) и получил следующее:

$ git fsck
fatal: object bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad is corrupted
$ git gc
Counting objects: 23, done.
error: unable to unpack bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad header
error: inflateEnd: failed
Delta compression using up to 2 threads.
Compressing objects: 100% (12/12), done.
fatal: object bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad is corrupted
error: failed to run repack
$ git fsck --full
fatal: object bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad is corrupted
$ rm -f .git/objects/bd/1b260b0ef92d1a219e1183953fa1ac7cdb4cad
$ git fsck --full
broken link from    tree a3070cb66fd169e1443867a8bb137a44103c9f24
              to    blob bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad
missing blob bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad
$ git cat-file -p 2418b6ba8fd0289933c9351260a272b8e410867f
tree a3070cb66fd169e1443867a8bb137a44103c9f24
parent 8d945134b0cead535d66af29c8eb4228b5dc3763
author [redacted] 1333789753 -0600
committer [redacted] 1333789753 -0600

test corrupted object
$ git checkout 2418b6ba8fd0289933c9351260a272b8e410867f
error: git checkout-index: unable to read sha1 file of morefile (bd1b260b0ef92d1a219e1183953fa1ac7cdb4cad)
D   morefile
Note: checking out '2418b6ba8fd0289933c9351260a272b8e410867f'.

You are in 'detached HEAD' state. ...

Обратите внимание, где-то по пути он перенаправил ветку master на предыдущую «хорошую» фиксацию (а не на предыдущую, и я понятия не имею, почему), так что вам может потребоваться восстановить историю фиксации и т. Д. Но все был там, за исключением отсутствующего файла "morefile", blob которого я испортил. (Я восстановил его из резервной копии, которую сделал заранее, и даже смог вернуть файл с помощью git checkout -- morefile. Вы можете mv где-нибудь найти поврежденный blob-объект и посмотреть, сможете ли вы восстановить из него некоторые данные.)

Я бы, конечно, сначала сделал резервную копию сломанного репозитория git, на всякий случай. :-)

person torek    schedule 07.04.2012
comment
наш git fsck немного отличается. Я сделал то же самое, что и ты. И, попробовал клонировать. не сработало. см. обновление (4). В любом случае, я ценю ваш подробный ответ. - person kirill_igum; 07.04.2012
comment
Кстати, магическое число выше (2418b ...) появилось при прокрутке назад, чтобы увидеть, что это было до того, как я разбил один объект-каплю. Когда вы говорите, что не работает, вы имеете в виду, что git checkout ‹какой-то коммит, который должен быть в порядке› не дает вам заполненное рабочее дерево? Я тестировал это на своем ноутбуке с установленной версией 1.7.0.3. - person torek; 08.04.2012
comment
1) да, я подумал. Я использовал свой первоначальный комментарий (см. git log |tail -n5 в update (4)). в комментарии даже нет поврежденного файла; так что это хороший комментарий. 2) я не уверен, заполняет он дерево или нет, но fit fsck по-прежнему выдает ошибку, см. Update (5). - person kirill_igum; 08.04.2012
comment
Неработающая ссылка в порядке; цель здесь - иметь возможность проверить все (или, по крайней мере, достаточно) хороших коммитов, чтобы получить что-то полезное. Если у вас есть хорошее дерево работы, вы можете скопировать (или git archive или что-то еще) его в новое место и создать полностью новое репозиторий git, за вычетом плохих файлов, которые сохранят столько истории, сколько вы захотите восстановить. Или вы можете использовать filter-branch для усечения истории из (дубликата) исходного репо. В любом случае вы получите новые идентификаторы фиксации. - person torek; 08.04.2012
comment
Ах, теперь это имеет смысл. Я могу получить доступ к предыдущим сборкам. так что я думаю, мне нужно просто скопировать дерево. Вы знаете, как это сделать? те, что я видел, полагались на .git/objects/pack, но в моем случае он пуст. следует ли мне написать сценарий, который проверяет каждую фиксацию, копирует файлы в новый каталог, а затем фиксирует его в новом .git? - person kirill_igum; 08.04.2012
comment
На самом деле я не пытался восстановить сломанный репозиторий git, как этот, поэтому не знаю, есть ли лучший способ. Похоже, что последовательность git archive ops или git checkouts с установленными переменными окружения GIT_DIR и GIT_WORK_TREE была бы хорошим способом скопировать дерево в другое место. Или возьмите копию фактического сценария ветвления фильтра (это /usr/libexec/git-core/git-filter-branch или аналогичный) и поработайте по ней. :-) - person torek; 08.04.2012