天天看點

圖解常用的 Git 指令含義

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

本文會介紹一些常用 Git 指令的圖解說明。

合并(git merge)

當項目中多條功能分支是,有時就需要使用 git merge 指令,指定将某個分支的送出合并到目前分支。Git 中有兩個合并政策:fast-forward 和 no-fast-forward。

fast-forward(--ff)

如果目前分支,在合并分支前,沒有做過額外送出。那麼合并分支的過程不會産生的新的送出記錄,而是直接将分支上的送出添加進來。這稱為 fast-forward 合并。

圖解常用的 Git 指令含義

現在 dev 分支上的修改已全部合并到主分支 master 上。那 no-fast-forward 又是什麼呢?

no-fast-forward(--no-ff)

上面的場景很少遇到,基本是:在目前分支分離出子分支後,做了一些修改;而分離出的子分支也做了修改。這個時候再使用 git merge,就會觸發 no-fast-forward 政策了。

在 no-fast-forward 政策下,Git 會在目前分支(active branch)額外建立一個新的 合并送出(merging commit)。這條送出記錄既指向目前分支,又指向合并分支。

圖解常用的 Git 指令含義

合并後,在目前主分支 master 上包含 dev 分支上的所有修改。

合并沖突

如果兩個分支的修改存在沖突:比如說同時修改了某個檔案的同一行;或者一個分支删除了檔案,另一個分支則修改了檔案——對于這種情況,Git 是無法自行決定合并政策的。這個時候,Git 就會把合并操作交給我們。

舉個例子,兩個分支對同一個 README.md 檔案做了修改。

圖解常用的 Git 指令含義

如果此時将 dev 合并到 master,那麼就存在合并沖突了:标題是使用 Hello! 還是 Hey! 呢?

當在主分支上執行 git merge 後,Git 會提示存在合并沖突,并把沖突的地方标記出來。我們手工處理完畢後,儲存修改、添加檔案、然後送出修改就可以了。

圖解常用的 Git 指令含義

變基(git rebase)

除了 git merge,還能使用 git rebase 來合并分支。git rebase 指令會 複制 目前分支的所有最新送出,然後将這些送出添加到指定分支送出記錄之上。

圖解常用的 Git 指令含義

如圖,dev 分支是從主分支上分離出去的(在 i8fe5 處),之後主分支與 dev 分支上都有相應的修改。執行 git rebase master 指令後,dev 分支将自己的最新送出記錄複制出來(送出 hash 也發生了改變),拼在了主分支最後一次送出之上。這種合并分支的方式,會另 Git 送出曆史看起來很清爽。

變基在開發功能(feature branch)分支時很有用——在開發功能時,主分支上可能也做了一些更新,我們可以将主分支上的最新更新通過變基合并到功能分支上來,這在未來在主分支上合并功能分支避免了沖突的發生。

互動式變基

git rebase 時,我們還能對目前分支上的送出記錄做修改!采用 互動式變基(Interactive Rebase) 形式。

變基時提供了 6 種操作模式:

  • reword:修改送出資訊
  • edit:修改此送出
  • squash:将目前送出合并到之前的送出中
  • fixup:将目前送出合并到之前的送出中,不保留送出日志消息
  • exec:在每一個需要變基的送出上執行一條指令
  • drop:删除送出

以 drop 為例:

圖解常用的 Git 指令含義

以 squash 為例:

圖解常用的 Git 指令含義

e45cb(+styles.css) 合并到 ec5be(+index.js) 送出後,兩個送出重新 hash 出了 c4ec9(+styles.css、+index.js)這個送出記錄。

重置(git reset)

如果因為某些原因(比如新送出導緻了 BUG,或隻是一個 WIP 送出),需要撤回送出,那麼可以使用 git reset 指令。

git reset 可以控制目前分支回撤到某次送出時的狀态。

軟重置

執行軟重置時,撤回到特定送出之後,已有的修改會保留。

以下圖為例:9e78i 送出添加了 style.css 檔案,035cc 送出添加了 index.js 檔案。使用軟重置,我們可以撤銷送出記錄,但是保留建立的 style.css 和 index.js 檔案。

圖解常用的 Git 指令含義

使用 git status 指令檢視,發現建立的 style.css 和 index.js 的兩個檔案還在,不過對應的送出記錄已經移除。這很好,我們可以對這些檔案内容重新編輯,稍後再做送出。

硬重置

有時重置時,無需保留送出已有的修改,直接将目前分支的狀态恢複到某個特定送出下,這種重置稱為硬重置,需要注意的是,硬重置還會将目前工作目錄(working directory)中的檔案、已暫存檔案(staged files)全部移除!💣

圖解常用的 Git 指令含義

使用 git status 檢視,發現目前操作空間空空如也。Git 丢棄了 9e78i 和 035cc 兩次送出引入的修改,将倉庫重置到 ec5be 時的狀态。

還原(git revert)

另一種撤銷更改的方式,是使用 git revert 指令。用于還原某次送出的修改,會建立一個包含已還原更改的 新送出記錄!

舉個例子,我們在 ec5be 上添加了 index.js 檔案。之後發現并不需要這個檔案。那麼就可以使用 git revert ec5be 指令還原之前的更改。

圖解常用的 Git 指令含義

新的送出記錄 9e78i 還原了 ec5be 引入的更改。git revert 可以在不修改分支曆史的前提下,還原某次送出引入的更改。

檢出送出(git cherry-pick)

如果某個分支上的某次送出的修改正是目前分支需要的,那我們可以使用 cherry-pick 指令檢出某次的送出更改作為新的送出添加到目前分支上面。

舉個例子(如下圖所示):dev 分支上的 76d12 送出添加了 index.js 檔案,我們需要将本次送出更改加入到 master 分支,那麼就可以使用 git cherry-pick 76d12 單獨檢出這條記錄修改。

圖解常用的 Git 指令含義

現在 master 分支包含了 76d12 中引入的修改,并添加了一條送出記錄 9e78i。

擷取(git fetch)

假設,我們在一個有關聯遠端分支(比如:在 Github 上)的分支上工作,那麼就要面臨一個問題——你和你的同僚都這個分支上工作,你的同僚将他做的更改(比如一個 quick fix)送出到了遠端分支上,而這些送出是你本地沒有的。

此時,就要使用 git fetch 指令将遠端分支上的最新的修改下載下傳下來。

圖解常用的 Git 指令含義

可以看見,git fetch 指令并沒有影響本地分支。

拉取(git pull)

除了 git fetch,我們還能使用 git pull 擷取遠端分支資料。有什麼不同呢?git pull 指令實際做了兩件事:git fetch 和 git merge。

如下圖所示:

圖解常用的 Git 指令含義

譯注:這裡的圖畫的是有問題的——目前主分支并沒有新的送出,是以 git merge 的結果是直接将遠端分支上的送出添加到目前分支之後,而不是如圖所示的産生一個合并送出。

Reflog(git reflog)

每個人都會犯錯,舉一個例子:假設你不小心使用 git reset 指令硬重置倉庫到某個送出。後面突然想到,重置導緻了一些已有的正常代碼的誤删!

git reflog 是一個非常有用的指令,用于顯示所有已執行操作的日志!包括合并、重置、還原:基本上記錄了對分支的任何更改。

圖解常用的 Git 指令含義

如果你不幸犯錯了,你可以使用 git reflog 的資訊通過重置 HEAD 輕松地重做此操作!

假設,我們不想合并 origin/master 分支了。執行 git reflog 指令,我們看到合并之前的倉庫狀态位于 HEAD@{1} 這個地方,我們使用 git reset 指令将 HEAD 頭指向 HEAD@{1}。

圖解常用的 Git 指令含義

可以看見,最新的操作資訊也已經記錄到 reflog 中了!

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/zhibo

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-04-07

本文作者:zhangbao90s

本文來自:“

掘金

”,了解相關資訊可以關注“掘金”