【git】遠程倉庫版本回退方法

1 簡介

最近在使用git時遇到了遠程分支須要版本回滾的狀況,因而作了一下研究,寫下這篇博客。前端

2 問題

若是提交了一個錯誤的版本,怎麼回退版本?git

若是提交了一個錯誤的版本到遠程分支,怎麼回退遠程分支版本?bash

若是提交了一個錯誤的版本到公共遠程分支,又該怎麼回退版本?分佈式

3 本地分支版本回退的方法

若是你在本地作了錯誤提交,那麼回退版本的方法很簡單 
先用下面命令找到要回退的版本的commit id:工具

git reflog

接着回退版本:ui

git reset --hard Obfafd

0bfafd就是你要回退的版本的commit id的前面幾位spa

4 本身的遠程分支版本回退的方法

若是你的錯誤提交已經推送到本身的遠程分支了,那麼就須要回滾遠程分支了。 
首先要回退本地分支:code

git reflog git reset --hard Obfafd

緊接着強制推送到遠程分支:server

git push -f

注意:本地分支回滾後,版本將落後遠程分支,必須使用強制推送覆蓋遠程分支,不然沒法推送到遠程分支ci

5 公共遠程分支版本回退的問題

看到這裏,相信你已經可以回滾遠程分支的版本了,那麼你也許會問了,回滾公共遠程分支和回滾本身的遠程分支有區別嗎? 
答案是,固然有區別啦。

一個顯而易見的問題:若是你回退公共遠程分支,把別人的提交給丟掉了怎麼辦?

下面來分析:

假如你的遠程master分支狀況是這樣的:

A1–A2–B1

其中A、B分別表明兩我的,A一、A二、B1表明各自的提交。而且全部人的本地分支都已經更新到最新版本,和遠程分支一致。

這個時候你發現A2此次提交有錯誤,你用reset回滾遠程分支master到A1,那麼理想狀態是你的隊友一拉代碼git pull,他們的master分支也回滾了,然而現實倒是,你的隊友會看到下面的提示:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working directory clean

也就是說,你的隊友的分支並無主動回退,而是比遠程分支超前了兩次提交,由於遠程分支回退了嘛。

(1) 這個時候,你大吼一聲:兄弟們,老子回退版本了。若是你的隊友都是神之隊友,好比: Tony(騰訊CTO),那麼Tony會冷靜的使用下面的命令來找出你回退版本後覆蓋掉的他的提交,也就是B1那次提交:

git reflog

而後冷靜的把本身的分支回退到那次提交,而且拉個分支:

git checkout tony_branch        //先回到本身的分支 git reflog //接着看看當前的commit id,例如:0bbbbb git reset --hard B1 //回到被覆蓋的那次提交B1 git checkout -b tony_backup //拉個分支,用於保存以前由於回退版本被覆蓋掉的提交B1 git checkout tony_branch //拉完分支,迅速回到本身分支 git reset --hard 0bbbbbb //立刻回到本身分支的最前端

經過上面一通敲,Tony暫時舒了一口氣,還好,B1那次提交找回來了,這時tony_backup分支最新的一次提交就是B1,接着Tony要把本身的本地master分支和遠程master分支保持一致:

git reset --hard origin/master

 

執行了上面這條命令後,Tony的master分支才真正的回滾了,也就是說你的回滾操做才能對Tony生效,這個時候Tony的本地maser是這樣的:

A1

接着Tony要再次合併那個被丟掉的B1提交:

git checkout master             //切換到master git merge tony_backup  //再合併一次帶有B1的分支到master

好了,Tony終於長舒一口氣,這個時候他的master分支是下面這樣的:

A1 – B1

終於把丟掉的B1給找回來了,接着他push一下,你一拉也能同步。

同理對於全部隊友也要這樣作,可是若是該隊友沒有提交被你丟掉,那麼他拉完代碼git pull以後,只須要強制用遠程master覆蓋掉本地master就能夠了

git reset --hard origin/master

(2) 然而很不幸的是,現實中,咱們常常遇到的都是豬同樣的隊友,他們一看到下面提示:

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits) nothing to commit, working directory clean

就習慣性的git push一下,或者他們直接用的SourceTree這樣的圖形界面工具,一看到界面上顯示的是推送的提示就直接點了推送按鈕,臥&槽,你辛辛苦苦回滾的版本就這樣輕鬆的被你豬同樣的隊友給還原了,因此,只要有一個隊友push以後,遠程master又變成了:

A1 – A2 – B1

這就是分佈式,每一個人都有副本。這個時候你連揍他的心都有了,怎麼辦呢?你不能期望每一個人隊友都是git高手,下面咱們用另一種方法來回退版本。

注意:博主是在虛擬機中實驗的,用於模擬兩我的的操做,若是你在一個機器上,用同一個帳號在不一樣的目錄下克隆兩份代碼來實驗的話,回退遠程分支後,另一我的是不會看到落後遠程分支兩次提交的,因此請務必使用虛擬機來模擬A、B兩我的的操做

6 公共遠程分支版本回退的方法

使用git reset回退公共遠程分支的版本後,須要其餘全部人手動用遠程master分支覆蓋本地master分支,顯然,這不是優雅的回退方法,下面咱們使用另個一個命令來回退版本:

git revert HEAD                     //撤銷最近一次提交 git revert HEAD~1 //撤銷上上次的提交,注意:數字從0開始 git revert 0ffaacc //撤銷0ffaacc此次提交

git revert 命令意思是撤銷某次提交。它會產生一個新的提交,雖然代碼回退了,可是版本依然是向前的,因此,當你用revert回退以後,全部人pull以後,他們的代碼也自動的回退了。 
可是,要注意如下幾點:

  1. revert 是撤銷一次提交,因此後面的commit id是你須要回滾到的版本的前一次提交
  2. 使用revert HEAD是撤銷最近的一次提交,若是你最近一次提交是用revert命令產生的,那麼你再執行一次,就至關於撤銷了上次的撤銷操做,換句話說,你連續執行兩次revert HEAD命令,就跟沒執行是同樣的
  3. 使用revert HEAD~1 表示撤銷最近2次提交,這個數字是從0開始的,若是你以前撤銷過產生了commi id,那麼也會計算在內的。
  4. 若是使用 revert 撤銷的不是最近一次提交,那麼必定會有代碼衝突,須要你合併代碼,合併代碼只須要把當前的代碼所有去掉,保留以前版本的代碼就能夠了.

git revert 命令的好處就是不會丟掉別人的提交,即便你撤銷後覆蓋了別人的提交,他更新代碼後,能夠在本地用 reset 向前回滾,找到本身的代碼,而後拉一下分支,再回來合併上去就能夠找回被你覆蓋的提交了。

7 revert 合併代碼,解決衝突

使用revert命令,若是不是撤銷的最近一次提交,那麼必定會有衝突,以下所示:

<<<<<<< HEAD
所有清空
第一次提交 ======= 所有清空 >>>>>>> parent of c24cde7... 所有清空

解決衝突很簡單,由於咱們只想回到某次提交,所以須要把當前最新的代碼去掉便可,也就是HEAD標記的代碼:

<<<<<<< HEAD
所有清空
第一次提交 =======

把上面部分代碼去掉就能夠了,而後再提交一次代碼就能夠解決衝突了。

8 繼續擴展,簡單粗暴的回滾方法

看到這裏也許你已經以爲學會了遠程倉庫版本回滾方法了,可是實踐中老是會遇到不少不按套路來的問題,考慮下面一種狀況:

若是大家開發中,突然發現前面很遠的地方有一次錯誤的合併代碼,把原本下一次才能發的功能的代碼合併到了這一次來了,這個時候全體成員都以爲直接回滾比較快,由於他們都有備份,覆蓋了無所謂,這個時候用reset的話對隊友的要求比較高,用revert的話呢要大面積的解決衝突,也很麻煩呀,怎麼辦呢?

這個時候,可使用簡單粗暴的辦法,直接從那個錯誤的提交的前一次拉取一份代碼放到其餘目錄,而後將master代碼所有刪除,把那份新代碼方進去,而後提交,果真簡單粗暴啊,雖然這種方法不入流,可是,實踐中發現很好使啊,因此,實踐是檢驗真理的惟一標準。遇到問題仍是要靈活應對。 
若是你遇到問題,歡迎給我留言,我CSDN博客———「梧桐那時雨」。

9 總結

遠程分支回滾的三種方法:

    1. 本身的分支回滾直接用reset
    2. 公共分支回滾用revert
    3. 錯的太遠了直接將代碼所有刪掉,用正確代碼替代
相關文章
相關標籤/搜索