使用 git status 或 git pull 指令,都會顯示錯誤訊:
fatal: bad tree object
或:
fatal: unable to read tree
挑戰使用 git reset –hard 也會失敗。
執行指令:
git fsck --full
顯示詳細的出錯地方:
bad sha1 file: .git/objects/08/a17cc480454ddce bad sha1 file: .git/objects/0a/b5448f76a304ed7 bad sha1 file: .git/objects/40/1bad05ff57143cab268bae88d1408e bad sha1 file: .git/objects/4b/b87f2fe96729b5c bad sha1 file: .git/objects/65/7eae0c1999fa121 bad sha1 file: .git/objects/7c/e8c257894339fb2fc77cee76054aa9 bad sha1 file: .git/objects/87/b6219cffc518346 bad sha1 file: .git/objects/89/77f89bcaf2ee459 bad sha1 file: .git/objects/9e/1e9d0d34dc61fff bad sha1 file: .git/objects/ac/18db921111520ae bad sha1 file: .git/objects/b4/4ea3302f22e6950 bad sha1 file: .git/objects/c4/b5fb24a6d920497 bad sha1 file: .git/objects/c4/86a17f9b04637f6 bad sha1 file: .git/objects/cb/8591c50df269669 bad sha1 file: .git/objects/ce/cda4953fdc90eaed632d8bf2f4ee81 bad sha1 file: .git/objects/e9/9bfc0a56df14a3cf257f42896cf0e3 bad sha1 file: .git/objects/f0/63ec472d66cd077 Checking object directories: 100% (256/256), done. Checking objects: 100% (303/303), done. error: refs/remotes/origin/master: invalid reflog entry 8977f89bcaf2ee459a348649984f0df89ef15699 error: refs/remotes/origin/master: invalid reflog entry 8977f89bcaf2ee459a348649984f0df89ef15699 error: refs/heads/master: invalid reflog entry 8977f89bcaf2ee459a348649984f0df89ef15699 error: refs/heads/master: invalid reflog entry 8977f89bcaf2ee459a348649984f0df89ef15699 error: HEAD: invalid reflog entry 8977f89bcaf2ee459a348649984f0df89ef15699 error: HEAD: invalid reflog entry 8977f89bcaf2ee459a348649984f0df89ef15699 error: 87b6219cffc518346172f422d1bfa4e8b78ed6fe: invalid sha1 pointer in cache-tree broken link from tree 26640b344192f293fac8ebb8d8f3fdccfd189d42 to tree 401bad05ff57143cab268bae88d1408e8e76cb3c broken link from tree 26640b344192f293fac8ebb8d8f3fdccfd189d42 to tree cecda4953fdc90eaed632d8bf2f4ee81508933e8 broken link from tree 47ba09a9cfaacc42524cf27ad8d9e7908aa0c5d7 to tree 08a17cc480454ddce30f0081a2d4badbffd55b9f broken link from commit 46bd75ce77f3b65e1c31206600caad57f306ca0a to tree 9e1e9d0d34dc61ffff3fefb38d7e94781cbffb08 broken link from commit dac0579e0b3bc6ca5a990d659a7cb9ce7655a932 to tree 87b6219cffc518346172f422d1bfa4e8b78ed6fe broken link from commit dac0579e0b3bc6ca5a990d659a7cb9ce7655a932 to commit 8977f89bcaf2ee459a348649984f0df89ef15699 dangling blob 422c38560f4b6f012215f16691347498e4681e0d missing blob 4bb87f2fe96729b5cc5d4f2caf5c963b8934f02e missing blob 7ce8c257894339fb2fc77cee76054aa96803679b dangling tree d13ce7747f9b24259ef8773913bd0f76a87fd2aa missing tree 08a17cc480454ddce30f0081a2d4badbffd55b9f missing blob cb8591c50df2696693808909971890b744b25380 missing tree cecda4953fdc90eaed632d8bf2f4ee81508933e8 dangling tree 6ca29d55c0b990e57487ebb0a066c3ac6a992922 missing tree 87b6219cffc518346172f422d1bfa4e8b78ed6fe missing tree 9e1e9d0d34dc61ffff3fefb38d7e94781cbffb08 dangling blob bf4a20c6380beeb9adf1cf58d424b467580ab004 missing blob c486a17f9b04637f64a9113c4f1ac41de54fb3f6 missing tree 401bad05ff57143cab268bae88d1408e8e76cb3c dangling tree 46137c7cfcfef7b70f6a01ff17c6271aaad1bc1e missing commit 8977f89bcaf2ee459a348649984f0df89ef15699 dangling blob a8978263ebd73655bd9197d40935d007b9c6cd9c missing blob e99bfc0a56df14a3cf257f42896cf0e389686951
建議解法
直接使用 git clone 把遠端 repo 再下載回來,會簡單很多。
複雜解法
mv -v .git .git_old git init git remote add origin "${url}" git fetch # Note that some repositories use 'master' in place of 'main'. git reset origin/master
這一個複雜解法的好處是,可以保留有被異動的檔案們,執行完上面指令,再下 git status 就可以看到被異動的檔案們。
複雜解法的第一次 git push 會失敗,不過系統會提示我們服用下面的指令就OK 了:
git push --set-upstream origin master
資料來源
How can I fix a corrupted Git repository?
https://stackoverflow.com/questions/18678853/how-can-i-fix-a-corrupted-git-repository
As an alternative to Todd’s last option (Full Restores and Re-Initialization), if only the local repository is corrupted, and you know the URL to the remote, you can use this to reset your .git
to match the remote (replacing ${url}
with the remote URL):
mv -v .git .git_old && # Remove old Git files
git init && # Initialise new repository
git remote add origin "${url}" && # Link to old repository
git fetch && # Get old history
# Note that some repositories use 'master' in place of 'main'. Change the following line if your remote uses 'master'.
git reset origin/main --mixed # Force update to old history.
This leaves your working tree intact, and only affects Git’s bookkeeping.
I also recently made a Bash script for this very purpose (Appendix A), which wraps a bit of safety around this operation.
Note:
- If your repository has submodules, this process will mess them up somehow, and the only solution I’ve found so far is deleting them and then using
git submodule update --init
(or recloning the repository, but that seems too drastic). - This tries to determine the correct choice between ‘main’ and ‘master’ depending on local configuration settings, however there may be some issues if used on a repository that uses ‘master’, on a machine that has ‘main’ as the default branch.
- This uses
wget
to check that the url is reachable before doing anything. This is not necessarily the best operation to determine that a site is reachable, and if you haven’t got wget available, this can likely be replaced withping -c 1 "${url_base}"
(linux),ping -n 1 "${url_base}"
(windows), orcurl -Is "${url_base}"