在git diff時突然出現broken ling miss blob的情況,不明就理,網上goolge也下參考鏈接How to fix a broken repository
我的問題是文中說的A情況 have a “broken link” message
就是類似如下情況,參考文中它是直接移除文件來模擬這個情況:
$ mv .git/objects/4b/9458b3786228369c63936db65827de3cc06200 ../
$ git fsck –full
broken link from tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
to blob 4b9458b3786228369c63936db65827de3cc06200
missing blob 4b9458b3786228369c63936db65827de3cc06200
也就是說這個問題其實是你的.git/objects/xx/xxxxx丟失引起的.要想恢復主要就是重建這個丟失的文件.
git相關知識的理解
- 1.2 那麼這個文件在哪裏?
- 這個丟失的blob file(比如上面的4b9458b3786228369c63936db65827de3cc06200)文件,就保存在.git/objects/4b/…. 前兩個字母是文件夾,後面的字母就是文件名了
- 1.2 這個文件到底是什麼,怎麼產生的?
-
就我這個git門外漢來說,它就是一個HASH值,git 好像是在每一個commit版本中對修改過的文件都自動生成一個對應的hash值來標識這個文件有更改,不同commit間只要對比這個值就可以知道文件是否有修改了.
(簡單理解就是不同的hash值表示文件內容有差異,如果hash值一樣,說明文件是相同的.所以如果你要生成對應的hash值,你就要確保不同版本的文件內容是相同的,這在後面恢復時會用的)
它也可以你自己手動生成,命令如下,這個在我們恢復時需要用到.git hash-object -w file
回到我們的問題,如何解決 miss blob file
知道了這個問題的原因就是丟失了一個關於hash的blob文件,那我們只要把它找回來就行了.怎麼找回來?從任何你能得到該文件的地方COPY過來都行(可以從備份的git respo中,也可以從遠程git respo中),只要文件名與miss blob的名字一致的就是了.如果都沒有,那隻能自己生成一個了.
-
2.1 如何查看是哪個文件的hash值?
-
使用
git ls-tree commit
查詢,比如查詢當前版本的所有文件的blob文件可以如下:anzyelay@ubuntu:PZJBY11$ git ls-tree HEAD 100644 blob 16b4ee58786b1c31dc05f495d4ebe7fe2a215a88 .gitignore 100644 blob 0fb0518faec22fdb5d1868265b5871e059a1ffc9 CUart.cpp 100644 blob ce33a837e98893be1251c532692bf13e604c5c77 CUart.h ... 100644 blob bd82f5bd464deacbba8fdc9b80ebdf0b550bca20 src.qrc anzyelay@ubuntu:PZJBY11$
上面通過
git fsck
可以知道是哪個版本的blob丟失,在尋找對應文件,直接引用參考文檔裏的內容了.$ git fsck –full
broken link from tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
to blob 4b9458b3786228369c63936db65827de3cc06200
missing blob 4b9458b3786228369c63936db65827de3cc06200$ git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
100644 blob 8d14531846b95bfa3564b58ccfb7913a034323b8 .gitignore
100644 blob ebf9bf84da0aab5ed944264a5db2a65fe3a3e883 .mailmap
100644 blob 4b9458b3786228369c63936db65827de3cc06200 my-error-file
100644 blob ee909f2cc49e54f0799a4739d24c4cb9151ae453 CREDITS
040000 tree 0f5f709c17ad89e72bdbbef6ea221c69807009f6 Documentation
100644 blob 1570d248ad9237e4fa6e4d079336b9da62d9ba32 Kbuild
100644 blob 1c7c229a092665b11cd46a25dbd40feeb31661d9 MAINTAINERS由上找到了blob對應的文件是my-error-file
-
2.2 知道了文件,那就要還原當時的文件內容,這樣才能生成對應的hash值
-
如果你的丟失的blob的hash值對應的文件正好是你當前的文件,那恭喜你,直接
anzyelay@ubuntu:PZJBY11$ git hash-object -w my-error-file 9808b564a15c38833f2b13aee1ff36e302e22e34
看看生成的9808b564a15c38833f2b13aee1ff36e302e22e34這個數字是不是你要找的,如果不是,那你就是想辦法還原my-error-file到對應的版本,在生成了.
悲劇的是我的就不是,只能找是哪個版本了,使用如下命令:git log --raw --all --full-history -- my-error-file commit abc Author: Date: ... :100644 100644 4b9458b... newsha... M my-error-file commit xyz Author: Date: ... :100644 100644 oldsha... 4b9458b... M my-error-file
這個命令可以查看不同commit下,對應文件的hash值變化過程,發現my-error-file的4b9458b是在 commit xyz時生成的,在commit abc後更改了內容所以hash值也變了.那就努力的還原到commit xyz版本時 my-error-file的內容吧,如果還原OK了,就在
git hash-object -w my-error-file
下,如果出來的結果是丟失的blob的值,那就恭喜你成功了,這時在git fsck下看看.