git rebase總結及git使用規範

1、git規範

  場景一:若是代碼commit到本地庫了,可是commit以前忘記pull了,遠程代碼也已更新,此時不能使用pull直接拉取遠程代碼(分支會產生merge的記錄):git

    解決方法:commit以後,使用git fetch,拉取遠程代碼到緩存區,而後使用git rebase origin/dev,此時會產生衝突,解決衝突後便可提交,這樣分支不會產生merge的記錄github

  場景二:commit提交以前先使用pull老是沒問題的,但若是pull不下來,是由於代碼和遠程代碼衝突了,此時有兩種解決辦法:緩存

    1.使用git stash 保存本地修改的代碼到緩存區,此時代碼會還原爲沒修改以前的,此時在使用git pull拉取代碼,而後使用git stash pop恢復緩存區的代碼,此時解決衝突便可提交安全

    2.先commit提交本地代碼到本地庫,這時候不要直接pull(分支會產生merge的記錄),先使用git fetch,拉取遠程代碼到緩存區,而後使用git rebase origin/dev,此時會產生衝突,解決衝突後便可提交,這樣分支不會產生merge的記錄markdown

  場景三:dev代碼修改後,test分支須要同步更新修改:運維

    解決方法:dev修改後push代碼,切換到test分支,pull保證與遠程代碼一致,此時不能merge dev,而是使用git rebase dev(或者git rebase origin/dev),此時會把dev的代碼都更新到本地test分支,而後在push到遠程test分支,這樣分支不會產生merge的記錄測試

  場景四:新增測試不穩定的版本,在dev上切一個臨時分支tmp:fetch

    解決方法:手動打包放在dev上測試,若是功能穩定沒問題,那麼合併代碼,步驟1:git rebase origin/tmp;合併完臨時分支,還要在合一次origin/dev,步驟二:git rebase origin/dev,此時才能夠pushspa

  場景五:取消merging狀態3d

    git reset --hard HEAD (or sha_1)

  場景五:多人同時開發一個分支:

    一、git pull

        若是pull不下來,說明本地代碼和遠程分支有衝突,代碼更新不了

    二、git commit -m "xxx"
        將本地代碼添加到本地緩衝區

      git commit -a -m "xxx"
    三、git stash
        若是本地有不須要提交的代碼,git stash把你的修改保存起來,恢復到和你沒修改以前一致
    四、git fetch
        更新遠程代碼到本地暫存區
    五、git rebase
        把本地暫存區的代碼更新到工做區
    六、有衝突的話把衝突解決
    七、git status
      git add . 將解決完衝突的文件添加提交
    八、git rebase --continue
    九、git push origin dev 提交遠程分支
    十、git stash pop 恢復不須要提交的文件

 

  場景六:回滾遠程倉庫版本

    1.git reset --hard xxx(git提交版本號)

    2.git push --force

 

 2、tag標籤

  到達必定階段後,在代碼封版時,須要將穩定的代碼發佈成一個版本,使用git 建立一個tag ,這樣一個不可修改的歷史代碼版本就像被咱們封存起來同樣,不管是運維發佈拉取,或者之後的代碼版本管理,都是十分方便的

建立tag標籤:
git tag -a 版本號 -m 'tag備註'
git tag -a v2.0.0 -m 'version2.0.0'

查看tag:
git tag

提交tag到遠程:
git push origin --tags

刪除tag:
git tag -d v2.0.0

刪除遠程tag:
git push origin :refs/tags/v2.0.0

 

3、rebase總結

  1. 若是新參與一個項目,首先須要本地clone遠程倉庫。以後會有一個master(若不特殊說明,均指代本地master)和遠端的master(如下稱爲remote/master)是關聯的,即remote/master是本地master的up-stream。


    從遠程倉庫進行克隆
  2. 作開發時,要新建一個分支,如dev1,做爲你的開發分支。開發完新特性後,將工做區(work tree)的修改提交至暫存區(index),而後commit,此時會在dev1分支上生成一個新的commit單號。


    提交你的修改
  3. 切換回master分支,而後使用pull或者fetch+merge命令與remote/master同步一下(此時可能會有來自其餘開發者的提交),再合併(merge)dev1分支的,若是有衝突,則解決衝突。最後推送代碼到遠端倉庫。


    更新本地主分支

    合併dev1分支,推送
    合併dev1分支,推送

    這是我剛開始實習時,經常使用的一個開發,推送代碼的流程。長此以往,我發現了幾個問題:

  • 在master分支上解決衝突,可能會有些風險。好比一不注意,衝突沒有正確解決,致使本地修改與別人的修改混在一塊兒,原本穩定的與遠程保持同步的master分支被你改混亂了,且沒有其餘的備份了。

  • 在master分支上merge開發分支,若是master分支上有dev1沒有的commit單號,則會產生一個攜帶merge信息的提交單。這個commit你也要推送到遠端。企業開發通常會有一個評審分支,主管會對commit單號進行review,而後submit合併進remote/master分支中。merge信息的提交單也會讓reviewer作一次review,然而沒什麼必要的。

  • 一我的提交時,會有一個merge commit,那麼10我的提交,就會有10個merge commit,此時分支樹看起來會很混亂。零零散散的merge commit信息穿插在你的特性commit之間。

所以,我考慮使用另一種本地分支管理策略,來改善這樣的問題。

 

使用rebase命令。

先簡要說下rebase命令的做用。

好比在dev1分支上,你提交了2個單,c1和c2。而後你在dev1分支上將master分支rebase到當前分支git rebase master。此時,若是master分支已經與remote/master作了同步,更新了2個來自其餘人的提交,c3和c4。

 
場景描述

rebase會作以下操做:

 

  1. 把dev1分支上的c1和c2「拆」下來,並臨時保存成c1'和c2'。git裏將其稱爲patch
  2. 將master分支上更新的提交c3和c4合併進dev1分支上。


    rebase操做,拆分提交
    rebase操做,拆分提交
  3. 將c1'和c2',再按順序接在c3和c4的提交後面,若是沒有衝突,則rebase成功。此時c1'和c2'雖然和c1和c2的修改徹底同樣,但卻已經不是原來的提交了,commit id已經變化了。
     
    鏈接patch

    此時dev1分支包含master分支的全部commit,而且超前了兩個commit。若是你如今切換至master分支,並執行git merge dev1操做,因爲沒有不一樣於dev1的提交,merge操做就不會產生merge commit了。此時推送代碼,也只會有兩個commit。同時,master分支樹筆直前進,分支很清晰地展現一個個提交。而且,上述的更新和提交代碼的過程,是在dev1分支上修改衝突的,相對來講會比在master分支上修改更安全,若是不當心改混了,也能經過切換回master分支來找到穩定代碼。
     
    在master分支上合併dev1分支

    基於上述內容,可使用以下流程來提交代碼:

 

  1. 在dev1分支上進行開發,而後commit提交,在dev1分支上生成一個提交單。
  2. 切換到master分支,與remote/master分支同步。
  3. 切換回dev1分支,將master分支rebase到dev1分支上,若是有衝突,修改衝突。rebase操做的衝突修改與merge不同,修改完衝突後,保存進index,而後直接git rebase --continue便可,不一樣再多作一次提交。
  4. 切換回master分支,合併dev1分支,此時合併會很是順暢。而後push。

rebase的風險

以前提到,rebase會將當前分支的新提交拆下來,保存成patch,而後合併進其餘分支新的commit,最後將patch接進當前分支。這是rebase對多條分支的操做。對於單條分支,rebase還可以合併多個commit單號,將多個提交合併成一個提交。

git rebase -i [commit id]命令可以合併(整改)commit id以前的全部commit單。加上-i選項可以提供一個交互界面,分階段修改commit信息並rebase。

但這裏就會出現一個問題:若是你合併多個單號時,一不當心合併多了,將別人的提交也合併了,此時你本地的commit history和遠程倉庫的commit history不同了,不管你如何push,都沒法推送你的代碼了。若是你並不記得rebase以前的HEAD指向的commit的commit ID的話,git reflog都救不了你。

tips: 你能夠push時帶上-f參數,強制覆蓋遠程commit history,你這樣作估計會被打,由於覆蓋以後,團隊的其餘人的本地commit history就與遠程的不同了,都沒法推送了。

所以,請保證僅僅對本身私有的提交單進行rebase操做,對於已經合併進遠程倉庫的歷史提交單,不要使用rebase操做合併commit單。

相關文章
相關標籤/搜索