天天看點

Git 系列(四):在 Git 中進行版本回退

在這篇文章中,你将學到如何檢視項目中的曆史版本,如何進行版本回退,以及如何建立 git 分支以便你可以大膽嘗試而不會出現問題。

在你的 git 項目的曆史中,你的位置就像是搖滾專輯中的一個片段,由一個被稱為 head 的 标記來确定(如錄音帶錄音機或錄音播放器的播放頭)。要在你的 git 時間線上前後移動 head ,需要使用 git checkout 指令。

git checkout 指令的使用方式有兩種。最常見的用途是從一個以前的送出中恢複檔案,你也可以整個倒回錄音帶,切換到另一個分支。

恢複一個檔案

當你意識到一個本來很好檔案被你完全改亂了。我們都這麼幹過:我們把檔案放到一個地方,添加并送出,然後我們發現它還需要做點最後的調整,最後這個檔案被搞得面目全非了。

要把它恢複到最後的完好狀态,使用 git checkout 從最後的送出(即 head)中恢複:

$ git checkout head filename 

如果你碰巧送出了一個錯誤的版本,你需要找回更早的版本,使用 git log 檢視你更早的送出,然後從合适的送出中找回它:

$ git log --oneline 

79a4e5f bad take 

f449007 the second commit 

55df4c2 my great project, first commit. 

$ git checkout 55df4c2 filename 

現在,以前的檔案恢複到了你目前的位置。(任何時候你都可以用 git status 指令檢視你的目前狀态)因為這個檔案改變了,你需要添加這個檔案,再進行送出:

$ git add filename 

$ git commit -m 'restoring filename from first commit.' 

使用 git log 驗證你所送出的:

d512580 restoring filename from first commit 

從本質上講,你已經倒好了錄音帶并修複了壞的地方,是以你需要重新錄制正确的。

回退時間線

恢複檔案的另一種方式是回退整個 git 項目。這裡使用了分支的思想,這是另一種替代方法。

如果你要回到曆史送出,你要将 git head 回退到以前的版本才行。這個例子将回到最初的送出處:

$ git checkout 55df4c2  

當你以這種方式倒回錄音帶,如果你按下錄音鍵再次開始,就會丢失以前的工作。git 預設假定你不想這樣做,是以将 head 從項目中分離出來,可以讓你如所需的那樣工作,而不會因為偶爾的記錄而影響之後的工作。

如果你想看看以前的版本,想要重新做或者嘗試不同的方法,那麼安全一點的方式就是建立一個新的分支。可以将這個過程想象為嘗試同一首歌曲的不同版本,或者建立一個混音的。原始的依然存在,關閉那個分支做你想做的版本吧。

就像記錄到一個空白錄音帶一樣,把你的 git head 指到一個新的分支處:

$ git checkout -b remix 

switched to a new branch 'remix'  

現在你已經切換到了另一個分支,在你面前的是一個替代的幹淨工作區,準備開始工作吧。

也可以不用改變時間線來做同樣的事情。也許你很想這麼做,但切換到一個臨時的工作區隻是為了嘗試一些瘋狂的想法。這在工作中完全是可以接受的,請看:

$ git status 

on branch master 

nothing to commit, working directory clean 

$ git checkout -b crazy_idea 

switched to a new branch 'crazy_idea'  

現在你有一個幹淨的工作空間,在這裡你可以完成一些奇怪的想法。一旦你完成了,可以保留你的改變,或者丢棄他們,并切換回你的主分支。

若要放棄你的想法,切換到你的主分支,假裝新分支不存在:

$ git checkout master 

想要繼續使用你的瘋狂的想法,需要把它們拉回到主分支,切換到主分支然後合并新分支到主分支:

$ git merge crazy_idea  

git 的分支功能很強大,開發人員在克隆倉庫後馬上建立一個新分支是很常見的做法;這樣,他們所有的工作都在自己的分支上,可以送出并合并到主分支。git 是很靈活的,是以沒有“正确”或“錯誤”的方式(甚至一個主分支也可以與其所屬的遠端倉庫分離),但分支易于分離任務和送出貢獻。不要太激動,你可以如你所願的有很多的 git 分支。完全自由。

遠端協作

到目前為止你已經在自己舒适而私密的家中維護着一個 git 倉庫,但如何與其他人協同工作呢?

有好幾種不同的方式來設定 git 以便讓多人可以同時在一個項目上工作,是以首先我們要克隆倉庫,你可能已經從某人的 git 伺服器或 github 首頁,或在區域網路中的共享存儲上克隆了一個倉庫。

工作在私人倉庫下和共享倉庫下唯一不同的是你需要把你的改變 push 到别人的倉庫。我們把工作的倉庫稱之為本地(local)倉庫,其他倉庫稱為遠端(remote)倉庫。

當你以讀寫的方式克隆一個倉庫時,克隆的倉庫會繼承自被稱為 origin 的遠端庫。你可以看看你的克隆倉庫的遠端倉庫:

$ git remote --verbose 

origin  [email protected]:~/myproject.git (fetch) 

origin  [email protected]:~/myproject.git (push) 

有一個 origin 遠端庫非常有用,因為它有異地備份的功能,并允許其他人在該項目上工作。

如果克隆沒有繼承 origin 遠端庫,或者如果你選擇以後再添加,可以使用 git remote 指令:

$ git remote add [email protected]:~/myproject.git 

如果你修改了檔案,想把它們發到有讀寫權限的 origin 遠端庫,使用 git push。第一次推送改變,必須也發送分支資訊。不直接在主分支上工作是一個很好的做法,除非你被要求這樣做:

$ git checkout -b seth-dev 

$ git add exciting-new-file.txt 

$ git commit -m 'first push to remote' 

$ git push -u origin head 

它會推送你目前的位置(head)及其存在的分支到遠端。當推送過一次後,以後每次推送可以不使用 -u 選項:

$ git add another-file.txt 

$ git commit -m 'another push to remote' 

$ git push origin head 

合并分支

當你工作在一個 git 倉庫時,你可以合并任意測試分支到主分支。當團隊協作時,你可能想在将它們合并到主分支之前檢查他們的改變:

$ git checkout contributor 

$ git pull 

$ less blah.txt  ### 檢查改變的檔案 

$ git merge contributor 

如果你正在使用 github 或 gitlab 以及類似的東西,這個過程是不同的。但克隆項目并把它作為你自己的倉庫都是相似的。你可以在本地工作,将改變送出到你的 github 或 gitlab 帳戶,而不用其它人的許可,因為這些庫是你自己的。

如果你想要讓你克隆的倉庫接受你的改變,需要建立了一個拉取請求(pull request),它使用 web 服務的後端發送更新檔到真正的擁有者,并允許他們審查和拉取你的改變。

克隆一個項目通常是在 web 服務端完成的,它和使用 git 指令來管理項目是類似的,甚至推送的過程也是。然後它傳回到 web 服務打開一個拉取請求,工作就完成了。

下一部分我們将整合一些有用的插件到 git 中來幫你輕松的完成日常工作。

作者:seth kenlon

來源:51cto