learn_git詳細(xì)學(xué)習(xí)記錄

參考網(wǎng)站:learn_git

1.直接進(jìn)入沙盒

在 URL 后頭加上 ?NODEMO 就可以了

2. 本地操作相關(guān)篇節(jié)

2.1 基礎(chǔ)篇

  1. Git Commeit

    • 提交記錄: 保存的是你的目錄下所有文件的快照,就是ctrl+c,但是更優(yōu)雅、輕便
    • 可以做到的結(jié)果:可以快速地在這些提交記錄之間切換
    • hide goal命令關(guān)閉窗口
  2. Git Branch

    • 分支:早建分支!多用分支!

    • 與上面的提交記錄結(jié)合起來

      • 一種結(jié)合方法:新創(chuàng)建的分支 newImage 指向的是提交記錄
        • 切換新分支:git checkout newImage;git commit并且修改保存到新分支中
        • 簡潔的切換方法(創(chuàng)建新分支并切換新分支):git checkout -b <your-branch-name>
    • 創(chuàng)建分支示意圖

    切換分支
    提交記錄
  3. Git Merge

    • 用處:兩個(gè)分支都是獨(dú)立但是沒有整體,如果需要整體的提交記錄這時(shí)候就可以采用合并分支這一個(gè)命令

      • git merge bugFix
    • 合并分支的幾個(gè)步驟:先切換到a節(jié)點(diǎn),接著合并到b節(jié)點(diǎn)

      • 合并的規(guī)則就是:正常情況是jiu

        git branch bugFix
        git commit
        git checkout master
        git merge bugFix
        隨時(shí)用objective打開對(duì)話框
        
      • 合并分支示意圖:

合并分支之前
合并分支之后
  1. Git Rebase(另外一種合并方案)
    • 本質(zhì):實(shí)際上就是取出一系列的提交記錄,“復(fù)制”它們,然后在另外一個(gè)地方逐個(gè)的放下去(有當(dāng)前節(jié)點(diǎn)和其他節(jié)點(diǎn),rebase就是復(fù)制當(dāng)前節(jié)點(diǎn)到其指定的其他節(jié)點(diǎn)后面——也就是繼承自其他節(jié)點(diǎn))

    • 代碼實(shí)現(xiàn):

      git checkout -b bugFix  新建并切換回bugFix
      git commit              提交一次
      git checkout master     切換回master
      git commit              再提交一次
      git checkout bugFix     切換回bugFix
      git rebase master       把master合并到當(dāng)前分支
      
  • 合并示意圖:

    rebase之前
    rebase之后
  1. 樹上進(jìn)行移動(dòng)
    1. HEAD

      • 分離的 HEAD 就是讓其指向了某個(gè)具體的提交記錄而不是分支名

      • 一個(gè)對(duì)當(dāng)前檢出記錄的符號(hào)引用 —— 也就是指向你正在其基礎(chǔ)上進(jìn)行工作的提交記錄。

      • 總是指向當(dāng)前分支上最近一次提交記錄,修改提交樹也是針對(duì)head開始的;

      • 對(duì)提交做的一些更改,可以通過其看到。

      • 可以通過 cat .git/HEAD 查看head指向;

      • 指向的是一個(gè)引用,還可以用 git symbolic-ref HEAD 查看它的指向

        git checkout C1;
        git checkout master;
        git commit;
        git checkout C2;
        
      • HEAD示意圖:

      未檢出HEAD
      檢出HEAD
    2. 分離的 HEAD

      • ==讓其指向了某個(gè)具體的提交記錄而不是分支名==
      • 待解決的問題:
        • 想完成此關(guān),從 bugFix 分支中分離出 HEAD 并讓其指向一個(gè)提交記錄。
        • 通過哈希值指定提交記錄。每個(gè)提交記錄的哈希值顯示在代表提交記錄的圓圈中。
      • 示意圖與1部分示意圖一致。
  2. 相對(duì)引用:
    • 通過指定提交記錄哈希值的方式在 Git 中移動(dòng)不太方便,在git中只需要提供能夠唯一標(biāo)識(shí)提交記錄的前幾個(gè)字符即可。

    • 2個(gè)非常有用的操作:

      • a.使用 ^ 向上移動(dòng) 1 個(gè)提交記錄

      • b.使用 ~<num> 向上移動(dòng)多個(gè)提交記錄,如 ~3

      • 代碼構(gòu)成:

        git checkout C3;
        git checkout HEAD^;
        git checkout HEAD^;
        git checkout HEAD^;
        
    • 示意圖:

      相對(duì)引用之前
      進(jìn)行相對(duì)引用之后
    • 強(qiáng)制修改分支位置

  • 直接使用 -f 選項(xiàng)讓分支指向另一個(gè)提交:git branch -f master HEAD~3

    - 示意圖(`git branch -f master C6`):
    
      ![修改之前](https://upload-images.jianshu.io/upload_images/16953224-cca269a818f79bb6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
      ![修改之后](https://upload-images.jianshu.io/upload_images/16953224-0c6a291e009f802d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
  1. 撤銷變更:

    • 組成部分:底層部分(暫存區(qū)的獨(dú)立文件或者片段)和上層部分(變更到底是通過哪種方式被撤銷的)

      • 我們關(guān)注的是后者:上層部分
    • 兩種撤銷更改指令:

      • git reset(本地),(git reset HEAD^1----->數(shù)字1就是指定回退到的位置)示意圖如下:

        git reset之前
        git reset之后
      • git revert(遠(yuǎn)程)(git revert HEAD,注意當(dāng)前節(jié)點(diǎn)應(yīng)該是在所要操作的節(jié)點(diǎn)上):用一個(gè)新提交來消除一個(gè)歷史提交所做的任何修改,示意圖如下:

        git revert之前
        git revert之后
    • 完成的任務(wù):

      • 分別撤銷 local 分支和 pushed 分支上的最近一次提交。共需要撤銷兩個(gè)提交(每個(gè)分支一個(gè))。
      • 記住 pushed 是遠(yuǎn)程分支,local 是本地分支 —— 這么說你應(yīng)該知道用分別哪種方法了吧?

2.2 處理復(fù)雜問題

2.2.1 修改提交樹

  1. 自由修改提交樹git cherry-pick
    • 清楚知道所需要提交的記錄

    • 提交記錄插入分支的指向,指定記錄插入當(dāng)前分支

    • 示意圖如下(git cherry-pick C2 C4):

      修改之前
      修改之后
  2. 交互式的rebase
    • 從一系列的提交記錄中找到想要的記錄,可以調(diào)整順序、刪除、合并操作

    • rebase --interactive(-i)

    • 示意圖(git rebase -i HEAD~4):

      調(diào)整之前
      調(diào)整之后

2.3 雜項(xiàng)

  1. 本地自由棧式提交
    • 針對(duì)各個(gè)不同分支有一些調(diào)試或者打印的提交記錄:復(fù)制解決問題的那幾個(gè)提交就是(只提交一個(gè)分支)

    • 提交的技巧

      • 先用 git rebase -i 將提交重新排序,然后把我們想要修改的提交記錄挪到最前
      • 然后用 commit --amend 來進(jìn)行一些小修改
        • 會(huì)合并當(dāng)前提交和上一次的提交,如果當(dāng)前提交有注釋,則以當(dāng)前的注釋為合并后的提交的注釋,若當(dāng)前提交沒有注釋,則以上一次提交的注釋作為合并后的提交的注釋
      • 接著再用 git rebase -i 來將他們調(diào)回原來的順序
      • 最后我們把 master 移到修改的最前端(用你自己喜歡的方法),就大功告成啦!
    • 關(guān)卡代碼實(shí)現(xiàn):

      git rebase -i C3~2
      git commit --amend        針對(duì)當(dāng)前分支修改提交內(nèi)容
      git rebase caption master
      
  • 示意圖:

    未修改
    修改之后
  1. 與1實(shí)現(xiàn)同樣的功能:將提交樹上任何地方的提交記錄取過來追加到 HEAD 上

    • 實(shí)現(xiàn)代碼:git cherry-pick C2

    • 示意圖:

      未修改
      修改之后
  2. 永遠(yuǎn)地指向某一個(gè)提交記錄分支或者提供類似功能(標(biāo)簽)

    • 標(biāo)簽,對(duì)應(yīng)關(guān)系:標(biāo)簽→錨點(diǎn)

      • git tag 標(biāo)簽 實(shí)際節(jié)點(diǎn)
        • 主要區(qū)別就是:不會(huì)隨著分支的移動(dòng)而移動(dòng);
    • 示意圖(git tag v1 c1):

      沒打標(biāo)簽
      打上標(biāo)簽
    • describe,用于描述最近的錨點(diǎn)

      • git describe <ref>

        • git bisect(一個(gè)查找產(chǎn)生 Bug 的提交記錄的指令)一起結(jié)合使用
        • 輸出結(jié)果:<tag>_<numCommits>_g<hash>,tag是指的離ref最近的tag標(biāo)簽
      • 示意圖:

        describe
  3. 高級(jí)操作

    • 多次rebase

      • 把多個(gè)分支rebase到master,按照規(guī)定的順序;

      • 主要關(guān)注的是一種特殊情況,如下所示:

        rebase的特殊注意情況
    • 選擇父提交節(jié)點(diǎn)

      • 操作符 ^ 與 ~ 符一樣,后面也可以跟一個(gè)數(shù)字。他們意義不同:

        • ^指定合并提交記錄的某個(gè)父提交(針對(duì)有多個(gè)父節(jié)點(diǎn)的時(shí)候),~就是返回多少代。git branch bugWork master^^2^
      • 示意圖:

        未選擇
        選擇后
    • 糾纏不清的分支:多個(gè)分支都需要做不同的操作或者提交

      • 三個(gè)分支:one 需要重新排序并刪除 C5,two 僅需要重排排序,而 three 只需要提交一次

      • 關(guān)卡代碼實(shí)現(xiàn):

        git checkout one
        git cherry-pick c4 c3 c2
        git checkout two
        git cherry-pick c5 c4
        git branch -f three c2
        
      • 示意圖:

        處理之前
        處理之后

3. 遠(yuǎn)程操作相關(guān)篇章

3.1 push && pull----git遠(yuǎn)程倉庫

  1. clone一個(gè)遠(yuǎn)程倉庫
  • git clone

    • 本地多的遠(yuǎn)程分支:o/master(遠(yuǎn)程分支有一些特殊的屬性)

      • 遠(yuǎn)程分支反映了遠(yuǎn)程倉庫(在你上次和它通信時(shí))的狀態(tài)
      • 遠(yuǎn)程分支有一個(gè)特別的屬性:檢出時(shí)自動(dòng)進(jìn)入分離 HEAD 狀態(tài)。所以做法是:(更新了遠(yuǎn)程分支之后)再用遠(yuǎn)程分享你的工作成果。
      • o代表遠(yuǎn)程倉庫默認(rèn)為origin
        • 遠(yuǎn)程倉庫的命名規(guī)則:<remote name>/<branch name>
    • 示意圖:

      git clone
      git commit之后進(jìn)入分離狀態(tài)
  • git fetch: 向遠(yuǎn)程倉庫傳輸數(shù)據(jù)以及從遠(yuǎn)程倉庫獲取數(shù)據(jù)。

    • git fetch 通常通過互聯(lián)網(wǎng)(使用 http:// 或 git:// 協(xié)議) 與遠(yuǎn)程倉庫通信。

    • 本質(zhì):將本地倉庫中的遠(yuǎn)程分支更新成了遠(yuǎn)程倉庫相應(yīng)分支最新的狀態(tài)

    • 會(huì)更新本地沒有的記錄而不會(huì)更新更新本地倉庫狀態(tài)(這點(diǎn)尤其需要注意),以及將指針指向o/master

    • 關(guān)卡代碼實(shí)現(xiàn)

      git fetch origin bugFix
      git checkout master
      git fetch origin master
      git checkout bugFix
      
    • 示意圖:

      git fetch
      關(guān)卡初始圖
      關(guān)卡過關(guān)圖
  • git pull:將變化的內(nèi)容更新到本地

    • 等同于兩個(gè)命令:

      • git fetch;git merge o/master
      • git pull --rebase 就是 fetchrebase 的簡寫!
    • 示意圖:

      git pull之前
      git pull之后
  • 模擬團(tuán)隊(duì)協(xié)作:

    • 模擬提交:git fakeTeamwork foo 3
  • git push:與git pull相對(duì),將本地上傳到遠(yuǎn)程數(shù)據(jù)庫

    • ==推送之前需要先clone==

    • git push 負(fù)責(zé)將你的變更上傳到指定的遠(yuǎn)程倉庫;同時(shí)本地master與o/master也被更新;

    • git push 不帶任何參數(shù)時(shí)的行為與 Git 的一個(gè)名為 push.default 的配置有關(guān),使用的時(shí)候最好進(jìn)行檢查。

    • 示意圖:

      git push之前
      git push之后
  • 偏離的提交記錄

    • 具體原因造成:成員更改了API,你是基于原本的API進(jìn)行開發(fā)

    • 通過rebase進(jìn)行解決

      • git fetch;git rebase o/master;git push;
      • 簡化代碼:git pull --rebase;git push;
    • 也可以使用merge,只要告訴git當(dāng)前提交已經(jīng)包含了遠(yuǎn)程分支的所有狀況

      • git fetch;git merge o/master;git push;
      • 簡化代碼:git pull;git push;
    • 示意圖(通過rebase處理,本地根據(jù)遠(yuǎn)程分支o/master操作了一步,但是遠(yuǎn)程是在o/master之后還有c2):

      偏離前
      對(duì)偏離進(jìn)行合并處理后
  • 遠(yuǎn)程服務(wù)器拒絕!(Remote Rejected)(鎖定的Master(Locked Master))

    • 必須使用pull request來更新這個(gè)分支(在團(tuán)隊(duì)中合作可能會(huì)進(jìn)行相關(guān)master鎖定)

    • 相應(yīng)流程:

      1. 新建一個(gè)分支;
      2. reset你的master分支和遠(yuǎn)程服務(wù)器保持一致;
        1. 重置操作:git reset --hard o/master;(這種是硬重置,一般默認(rèn)是--mixed)
      3. 推送(push)這個(gè)分支并申請(qǐng)pull request;
    • 流程代碼:

      git reset --hard o/master;
      git checkout -b feature C2;
      git push origin feature;
      
    • 示意圖:

      未處理
      協(xié)同時(shí)鎖定的master處理后

3.2 關(guān)于 origin 和它的周邊 —— Git 遠(yuǎn)程倉庫高級(jí)操作

  1. 推送主分支

    • 完成兩個(gè)操作:

      1. 將特性分支集成到 master 上;
      2. 推送并更新遠(yuǎn)程分支;
    • 實(shí)現(xiàn)過程

       git fetch
       git rebase o/master side1
       git rebase side1 side2
       git rebase side2 side3
       git rebase side3 master    要注意最后push之前要把當(dāng)前分支合并到想要遠(yuǎn)程的分支(比如master)
       快速前進(jìn)。。。
       git push
      
    • 示意圖:

      未推送前
      推送之后
  2. 合并遠(yuǎn)程倉庫

    • rebase與merge之間的區(qū)別:

      • 優(yōu)點(diǎn):Rebase 使你的提交樹變得很干凈, 所有的提交都在一條線上
      • 缺點(diǎn):Rebase 使你的提交樹變得很干凈, 所有的提交都在一條線上
      • 喜歡保留提交歷史,更偏愛 merge;喜歡干凈的提交樹,偏愛 rebase;因此使用什么根據(jù)自己習(xí)慣就行。
    • 實(shí)現(xiàn)過程:
      git checkout master; git pull; git merge side1; git merge side2; git merge side3; git push;

    • 過程圖:


      合并之前的原圖

      合并之后的結(jié)果圖
  3. 遠(yuǎn)程追蹤

    • 本地分支與遠(yuǎn)程分支之間的關(guān)聯(lián)(通過push以及pull):

      1. pull:提交記錄會(huì)被先下載到 o/master 上,之后再合并到本地的 master 分支
      2. push:把工作從 master 推到遠(yuǎn)程倉庫中的 master 分支(同時(shí)會(huì)更新遠(yuǎn)程分支 o/master)
      3. 分支的remote tracking(遠(yuǎn)程跟蹤)屬性決定,并且git clone的時(shí)候就已經(jīng)進(jìn)行設(shè)定了,注意提示語句:local branch "master" set to track remote branch "o/master"
        1. 自己指定鎖定屬性:分支會(huì)像 master 分支一樣得到隱含的 push 目的地以及 merge 的目標(biāo)。
          • 可以在分支 totallyNotMaster 上執(zhí)行 git push,將工作推送到遠(yuǎn)程倉庫的 master 分支上
          • git checkout -b totallyNotMaster o/master(第一種方法)檢出一個(gè)分支跟蹤o/masters(totallyNotMaster分支是通過創(chuàng)建出來的)
          • git branch -u o/master foo(當(dāng)前就在 foo 分支上, 還可以省略 foo,foo分支是本來存在的)
    • 示意圖:

      遠(yuǎn)程跟蹤
  4. git push的參數(shù)1

    • 基本格式語法:git push <remote> <place>

      • 具體實(shí)例:git push origin master——切到本地倉庫中的“master”分支,獲取所有的提交,再到遠(yuǎn)程倉庫“origin”中找到“master”分支,將遠(yuǎn)程倉庫中沒有的提交記錄都添加上去,搞定之后告訴我。
        • 過指定參數(shù)告訴了 Git 所有它需要的信息, 所以它就忽略了我們所檢出的分支的屬性
        • 有一種情況就是:將某一記錄節(jié)點(diǎn)檢出之后,直接git push就會(huì)失敗,這時(shí)候就需要需要指定本地分支以及遠(yuǎn)程分支
    • 關(guān)卡問題:本關(guān)我們要更新遠(yuǎn)程倉庫中的 foomaster, 但是 git checkout 被禁用了!

      • git push origin master
    • 示意圖:

      git push<遠(yuǎn)程><位置>
  5. git push的參數(shù)2

    • ==來源與去向名稱不一致==,比如:想把本地的 foo 分支推送到遠(yuǎn)程倉庫中的 bar 分支

      • 解決方案:同時(shí)為源、目的地指定地址:git push origin <source>:<destination>
        • 注意:source可以是git能夠識(shí)別的任意地址
        • git push origin master:newBranch(<u>目的分支不存在的話,git就會(huì)新創(chuàng)建一個(gè)</u>)
    • 示意圖:

      push之前
      push之后
  6. git fetch的參數(shù)

    • git fetch 的參數(shù)和 git push 極其相似,只是方向反了,一個(gè)是上傳一個(gè)是下載提交記錄;

      1. git fetch origin foo--->到遠(yuǎn)程foo上下載所有不存在的節(jié)點(diǎn)記錄,但是需要注意的是:提交的記錄只是放在了o/foo上面,并沒有提交到foo上面,這就是fetch特殊的地方;

      2. git fetch origin foo~1:bar------>結(jié)果就是將foo~的記錄提交到bar上,如果分支bar不存在就新建一個(gè)。

      3. git fetch:就是把遠(yuǎn)程的所有都更新到本地中

    • 代碼實(shí)現(xiàn)過程:

      git fetch origin master~:foo
      git fetch origin foo:master
      git checkout foo
      git merge master
      
    • 示意圖:

      git fetch origin foo
      指定位置的fetch之前

      指定位置的fetch之后
  7. 沒有source的source

    • 奇怪的用法:

      • 可以在 git push 或 git fetch 時(shí)不指定任何 source,也就是source留空
        • git push origin :side---->如果空的上傳遠(yuǎn)程倉庫,就是把0賦值給某一個(gè)分支,就是刪除side分支
        • git fetch origin :bugFix----->表示可能從遠(yuǎn)程下載分支,自然就是創(chuàng)建一個(gè)新分支bugFix
    • 示意圖:

      1. push空source

        push空之前

        push空之后
      2. fetch空source

        fetch空之前

        fetch空之后
  8. git pull的參數(shù)

    • 實(shí)質(zhì)意義就是:用同樣的參數(shù)執(zhí)行 git fetch,然后再 merge 你所抓取到的提交記錄;

    • 幾個(gè)等價(jià)的代碼:

      等價(jià)1:
          git pull origin foo;
          git fetch origin foo;git merge o/foo;
      等價(jià)2:
         git pull origin bar~;bugFix;
         git fetch origin bar~:bugFix;git mergbe bugFix;
      
    • 同理git pull也可以用source:destination;

    • 示意圖:

      1. git pull origin master

        git pull origin master之前

        git pull origin master之后
      2. git pull origin master:foo

        git pull origin master:foo之前

        git pull origin master:foo之后
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容