1. 程式人生 > >記錄一次因伺服器關機造成的Git服務異常

記錄一次因伺服器關機造成的Git服務異常

 

環境:Ubuntu 16.04 、Git 2.7.4

事情原因:之前公司使用的是SVN版本控制器,後來,因為分支的需求,所以搭建了Git;

今天早上因為Git伺服器上tomcat服務出現異常,需要手動重啟伺服器;所以,同事手動重啟了伺服器;但是恰巧剛好另一個同事,正在push一個本地分支到Git伺服器上;所以造成該同事本地倉庫出現錯亂;(當時 我並不知道這件事。是後面其它同事提交Git時發現push失敗,出現異常);

假如,當前push錯誤的分支為C

其它分支有A、B

當使用git pull A 或者 git push A 或者 git pull B/git push B 到Git伺服器;都不會報錯

但是,push / pull C分支,或者是使用git fetch時,就出現異常

異常錯誤:

$ git fetch
[email protected]'s password:
error: object file ./objects/70/44716e362b4dfe9133728147c3cc27e8d15dd1 is empty
error: object file ./objects/70/44716e362b4dfe9133728147c3cc27e8d15dd1 is empty
fatal: loose object 7044716e362b4dfe9133728147c3cc27e8d15dd1 (stored in ./objects/70/44716e362b4dfe9133728147c3cc27e8d15dd1) is corrupt
fatal: The remote end hung up unexpectedly

注意:fatal: loose object... 這裡的意思就是說7044...這個版本號在447...當中不存在,447...的記錄為空;我猜想447當中記錄的是該分支(C分支)的上一個版本號;

驗證:

登入到Git伺服器後臺,進入專案的倉庫中(比如example.git);進入該目錄下的refs/heads/ 

目錄下有一個當前分支的檔案(C);使用cat 檢視一下,終端輸出的內容就是447...;

到這裡,問題已經很清晰了。就是因為在push時,伺服器斷電,造成版本丟失,所以分支C不能使用;而使用fetch命名是拉取遠端上所有的分支,該分支包含出錯的C分支,所以fetch失敗;而其它分支不受印象;

解決方法:

1.刪除遠端分支

1)刪除 Git伺服器上專案倉庫下/objects/70/44716e362b4dfe9133728147c3cc27e8d15dd1檔案,

2)刪除專案倉庫下/refs/heads/分支名稱 檔案

3)直接在本地倉庫使用git 命令刪除遠端分支(我這裡刪除遠端分支出錯了,如果出錯參考1)

這兩種方法都可以;但是操作之前一定要備份伺服器上專案倉庫:cp -a excample.git example.git-bak

2.重建本地專案(倉庫):如果出現loose object 一定要重建,不能使用以前的本地倉庫(push C分支的同事的電腦上要重建專案倉庫)

3.push  / pull  / fetch  使用各種Git命令對本地倉庫和遠端倉庫檢測;問題解決

注意:重點是刪除遠端分支,重建本地分支,如果不重建專案的話,還是在原來的本地倉庫新增遠端分支(沒有修改過),建立沒有問題,但是如果再修改內容後再push的話,push也能成功,fetch也能成功(C分支的同事的機器上), 但是在其它同事電腦上還是不能fetch;會報另外一個錯誤

19:35:31 Fetch failed
         remote: error: object file ./objects/0e/3255209641d780b165aa1628dde1200851e9de is empty        
         remote: error: object file ./objects/0e/3255209641d780b165aa1628dde1200851e9de is empty        
         error: git upload-pack: git-pack-objects died with error.
         fatal: git upload-pack: aborting due to possible repository corruption on the remote side.
         fatal: protocol error: bad pack header

如果出現這種錯誤,說明你的本地倉庫已經出現非常致命的問題了,不是簡單修修改改就能行,我嘗試過,去刪除,修改一些檔案,結果問題越來越多;才發覺已經走歪了,所以趕緊走回來;果斷備份本地專案,再次刪除遠端分支(因為剛剛在原來的倉庫新建立的遠端分支),重建本地專案倉庫,新增新分支,push到遠端倉庫;以及修改內容,push到遠端分支後,其他同事fetch;沒有問題,至此問題已經解決

再次重申一下,問題主要是因為本地倉庫版本號丟失以及版本號錯亂了;所以,導致分支不能使用;刪除分支,重建本地專案倉庫;

至於備份本地倉庫,因為改遠端分支上已經有很多可用的程式碼,重建本地專案倉庫後,新增新的分支後,切換到該分支後,直接將備份的專案的程式碼覆蓋,然後提交/push即可(不可能再去重新敲一次程式碼:所以備份是一個好習慣)