Git入門圖文教程(1.5W字40圖)??--深入淺出、圖文並茂

安木夕發表於2023-02-01

image.png

01、認識一下Git!—簡介

Git是當前最先進、最主流的分散式版本控制系統,免費、開源!核心能力就是版本控制。再具體一點,就是面向程式碼檔案的版本控制,程式碼的任何修改歷史都會被記錄管理起來,意味著可以恢復到到以前的任意時刻狀態。支援跨區域多人協作編輯,是團隊專案開發的必備基礎,所以Git也就成了程式設計師的必備技能。

image

?主要特點

  • 開源免費,使用廣泛。
  • 強大的文件(程式碼)的歷史版本管理,直接記錄完整快照(完整內容,而非差異),支援回滾、對比。
  • 分散式多人協作的的程式碼協同開發,幾乎所有操作都是本地執行的,支援程式碼合併、程式碼同步。
  • 簡單易用的分支管理,支援高效的建立分支、合併分支。

image.png

Git是Linux之父被迫開發的,為了解決Linux混亂的程式碼管理而開發的。Linux和Git之父 李納斯·託沃茲(Linus Benedic Torvalds),來自1969年的芬蘭。


02、Git是幹什麼的?—基礎概念

先了解下Git的基本概念,及基本框架、工作流程。

2.1、Git概念彙總?

概念名稱 描述
工作區(Workspace) 就是在電腦裡能看到的程式碼庫目錄,是我們搬磚的地方,新增、修改的檔案會提交到暫存區
暫存區(stage 或 index) 用於臨時存放檔案的修改,實際上上它只是一個檔案(.git/index),儲存待提交的檔案列表資訊。
版本庫/倉庫(Repository) Git的管理倉庫,管理版本的資料庫,記錄檔案/目錄狀態的地方,所有內容的修改記錄(版本)都在這裡。
服務端/遠端倉庫(origin 或 remote) 服務端的版本庫,專用的Git伺服器,為多人共享提供服務,承擔中心伺服器的角色。本地版本庫透過push指令把程式碼推送到服務端版本庫。
本地倉庫 使用者機器上直接使用的的的版本庫
分支(Branch) 分支是從主線分離出去的“副本”,可以獨立操作而互不干擾,倉庫初始化就有一個預設主分支master
(HEAD) HEAD類似一個“指標”,指向當前活動 分支最新版本
提交(Commit) 把暫存區的所有變更的內容提交到當前倉庫的活動分支。
推送(Push) 將本地倉庫的版本推送到服務端(遠端)倉庫,與他人共享。
拉取(Pull) 從服務端(遠端)倉庫獲取更新到本地倉庫,獲取他人共享的更新。
獲取(Fetch) 從服務端(遠端)倉庫更新,作用同拉取(Pull),區別是不會自動合併。
衝突(Conflict) 多人對同一檔案的工作副本進行更改,並將這些更改合併到倉庫時就會面臨衝突,需要人工合併處理。
合併(Merge) 對有衝突的檔案進行合併操作,Git會自動合併變更內容,無法自動處理的衝突內容會提示人工處理。
標籤(Tags) 標籤指的是某個分支某個特定時間點的狀態,可以理解為提交記錄的別名,常用來標記版本。
master(或main) 倉庫的“master”分支,預設的主分支,初始化倉庫就有了。Github上建立的倉庫預設名字為“main
origin/master 表示遠端倉庫(origin)的“master”分支
origin/HEAD 表示遠端倉庫(origin)的最新提交的位置,一般情況等於“origin/master

2.2、工作區/暫存區/倉庫

image.png

工作區、暫存區、版本庫是Git最基本的概念,關係如下圖:

image

?工作區(Workspace)就是在電腦裡能看到的程式碼庫目錄,是我們搬磚的地方,新增、修改的檔案會提交到暫存區。

  • 在這裡新增檔案、修改檔案內容,或刪除檔案。

?暫存區(stage或index) 用於臨時存放檔案的修改,實際上上它只是一個檔案(.git/index),儲存待提交的檔案列表資訊。

  • git add 命令將工作區的修改儲存到暫存區。

?版本庫/倉庫(Repository /rɪˈpɑːzətɔːri/ 倉庫)Git的管理倉庫,管理版本的資料庫,記錄檔案/目錄狀態的地方,所有內容的修改記錄(版本)都在這裡。就是工作區目錄下的隱藏資料夾.git,包含暫存區、分支、歷史記錄等資訊。

  • git commit 命令將暫存區的內容正式提交到版本庫。
  • master 為倉庫的預設分支masterHEAD是一個“指標”指向當前分支的最新提交,預設指向最新的master

image

如上圖,為對應本地倉庫目錄的結構關係。

  • KWebNote為專案目錄,也就是Git工作區。
  • 專案根目錄下隱藏的.git目錄就是Git倉庫目錄了,存放了所有Git管理的資訊。
  • .git/config為該倉庫的配置檔案,可透過指令修改或直接修改。
  • index檔案就是存放的暫存區內容。

2.3、Git基本流程(圖)

Git的工作流程核心就下面幾個步驟,掌握了就可以開始寫Bug了。

  • 0、準備倉庫:建立或從服務端克隆一個倉庫。
  • 1、搬磚:在工作目錄中新增、修改程式碼。
  • 2、暫存(git add):將需要進行版本管理的檔案放入暫存區域。
  • 3、提交(git commit):將暫存區域的檔案提交到Git倉庫。
  • 4、推送(git push):將本地倉庫推送到遠端倉庫,同步版本庫。
  • 5、獲取更新(fetch/pull):從服務端更新到本地,獲取他人推送的更新,與他人協作、共享。

image

  • git commit -a指令省略了add到暫存區的步驟,直接提交工作區的修改內容到版本庫,不包括新增的檔案。
  • git fetchgit pull 都是從遠端服務端獲取最新記錄,區別是git pull多了一個步驟,就是自動合併更新工作區。
  • git checkout .git checkout [file] 會清除工作區中未新增到暫存區的修改,用暫存區內容替換工作區。
  • git checkout HEAD . git checkout HEAD [file] 會清除工作區、暫存區的修改,用HEAD指向的當前分支最新版本替換暫存區、工作區。
  • git diff 用來對比不同部分之間的區別,如暫存區、工作區,最新版本與未提交內容,不同版本之間等。
  • git reset是專門用來撤銷修改、回退版本的指令,替代上面checkout的撤銷功能。

2.4、Git狀態(圖)

Git在執行提交的時候,不是直接將工作區的修改儲存到倉庫,而是將暫存區域的修改儲存到倉庫。要提交檔案,首先需要把檔案加入到暫存區域中。因此,Git管理的檔案有三(+2)種狀態:

  • 未跟蹤(untracked):新新增的檔案,或被移除跟蹤的檔案,未建立跟蹤,透過git add新增暫存並建立跟蹤。
  • 未修改:從倉庫簽出的檔案預設狀態,修改後就是“已修改”狀態了。
  • 已修改(modified):檔案被修改後的狀態。
  • 已暫存(staged):修改、新增的檔案新增到暫存區後的狀態。
  • 已提交(committed):從暫存區提交到版本庫。

image


03、起步:Git安裝配置

Git官網:https://www.git-scm.com/ 下載安裝包進行安裝。Git的使用有兩種方式:

  • 命令列:Git的命令透過系統命令列工具,或Git提供的命令列工具執行(C:\Program Files\Git\git-bash.exe
  • GUI工具:Windows(GUI)、Mac(GUI)工具,需單獨安裝,使用更簡單、更易上手。

指令git --version檢視安裝版本號

$ git --version
git version 2.33.0.windows.2

? 本文是在Windows 平臺上完成的,不過這個對學習Git沒什麼影響。

3.1、Git的配置檔案

Git有三個主要的配置檔案:三個配置檔案的優先順序是① < ② < ③

  • ① 系統全域性配置(--system):包含了適用於系統所有使用者和所有倉庫(專案)的配置資訊,存放在Git安裝目錄下C:\Program Files\Git\etc\gitconfig
  • ② 使用者全域性配置(--system):當前系統使用者的全域性配置,存放使用者目錄:C:\Users\[系統使用者名稱]\.gitconfig
  • ③ 倉庫/專案配置(--local):倉庫(專案)的特定配置,存放在專案目錄下.git/config

image

#檢視git配置
git config --list
git config -l

#檢視系統配置
git config --system --list

#檢視當前使用者(global)全域性配置
git config --list --global

#檢視當前倉庫配置資訊
git config --local  --list

倉庫的配置是上面多個配置的集合:

$ git config --list
$ git config -l
diff.astextplain.textconv=astextplain
http.sslbackend=openssl
http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
core.autocrlf=true
core.fscache=true
core.symlinks=false
pull.rebase=false
credential.helper=manager-core
credential.https://dev.azure.com.usehttppath=true
init.defaultbranch=master
user.name=Kanding
user.email=123anding@163.com

3.2、配置-初始化使用者

當安裝Git後首先要做的事情是配置你的使用者資訊—— 告訴Git你是誰?配置 使用者名稱郵箱地址,每次提交檔案時都會帶上這個使用者資訊,檢視歷史記錄時就知道是誰幹的了。

配置使用者資訊:

$ git config --global user.name "Your Name"
$ git config --global user.email "email@example.com"
# 配置完後,看看使用者配置檔案:
$ cat 'C:\Users\Kwongad\.gitconfig'
[user]
        name = Kanding
        email = 123anding@163.com
  • user.name為使用者名稱,user.email為郵箱。
  • --globalconfig的引數,表示使用者全域性配置。如果要給特定倉庫配置使用者資訊,則用引數--local配置即可,或直接在倉庫配置檔案.git/config裡修改。

3.3、配置-忽略.gitignore

工作目錄中的檔案並不是全都需要納入版本管理,如日誌、臨時檔案、私有配置檔案等不需要也不能納入版本管理,那該怎麼辦呢?

image.png

在工作區根目錄下建立“.gitignore”檔案,檔案中配置不需要進行版本管理的檔案、資料夾。“.gitignore”檔案本身是被納入版本管理的,可以共享。有如下規則:

  • #符號開頭為註釋。
  • 可以使用Linux萬用字元。
    • 星號(*)代表任意多個字元,
    • 問號(?)代表一個字元,
    • 方括號([abc])代表可選字元範圍,
    • 大括號({string1,string2,...})代表可選的字串等。
  • 感嘆號(!)開頭:表示例外規則,將不被忽略。
  • 路徑分隔符(/f)開頭:,表示要忽略根目錄下的檔案f
  • 路徑分隔符(f/)結尾:,表示要忽略資料夾f下面的所有檔案。
#為註釋
*.txt #忽略所有“.txt”結尾的檔案
!lib.txt #lib.txt除外
/temp #僅忽略專案根目錄下的temp檔案,不包括其它目錄下的temp,如不包括“src/temp”
build/ #忽略build/目錄下的所有檔案
doc/*.txt #會忽略 doc/notes.txt 但不包括 doc/server/arch.txt

? 各種語言專案的常用.gitignore檔案配置:https://github.com/github/gitignore


04、Git的GUI工具們

如果不想用命令列工具,完全可以安裝一個Git的GUI工具,用的更簡單、更舒服。不用記那麼多命令了,極易上手,不過Git基礎還是需要學習瞭解一下的。

❓對於Git,建議用命令列,這樣你才能真的理解Git的思想?
✔️其實都只是工具而已,適合自己的就是最好的,沒必要糾結,多寫點Bug更重要!

  • TortoiseGit:小烏龜,SVN時代就很流行的程式碼管理GUI利器。
    • ?只有Windows版本,支援中文,需要單獨下載安裝中文語言包。
    • ✔️開源,免費,與檔案管理器的良好整合。
    • ✔️內建衝突對比解決工具。
  • Sourcetree:SourceTree是老牌的Git GUI管理工具了,也號稱是最好用的Git GUI工具。
    • ✔️適用於 Windows 和 Mac 系統,內建中文版,自動識別語言。
    • ✔️免費、功能強大,使用簡單。
    • ✔️功能豐富,基本操作和高階操作都設計得非常流暢,適合初學者上手,支援Git Flow。
    • ?無衝突對比工具,支援配置第三方元件。
  • GitHub Desktop:Github官方出品的Git管理工具。
  • GitKraken:GitKraken是一個跨平臺GUI Git客戶端,有免費版,專業版和企業版,這些版本啟用了不同的功能。

4.1、SourceTree

SourceTree的官網 下載安裝包,支援Window、Mac系統,按照提示完成安裝。

  • SourceTree支援管理多個倉庫,透過+按鈕,可選擇多種方式新增倉庫。

image.png

  • 然後就是視覺化的倉庫管理了,不用記住繁瑣的指令(引數)了,視覺化操作。

image

4.2、TortoiseGit

image.png

TortoiseGit 官網下載安裝包,及中文語言包,按照提示完成安裝。小烏龜的Git是整合到作業系統裡的,直接右鍵資料夾就可以進行Git操作了。

image.png

  • 先進入設定:右鍵資料夾選單 --> TortoiseGit --> Settings 進入設定,設定中文語言。
  • 小烏龜的各種Git操作都在右鍵選單了,深度整合到了作業系統的資源管理器中了,檔案圖示也是有Git狀態的,比較容易分辨。

image.png

image.png

4.3、VSCode中的Git

VSCode自帶的Git工具基本已經可以滿足日常使用了,既有視覺化功能,也能敲命令,習慣了不就不用安裝其他GUI工具了。不過還是可以再安裝一些VSCode外掛,來增強Git功能。

  • GitLens :在團隊專案開發中非常實用,必備!!!用於快速檢視程式碼提交歷史記錄,在程式碼上會顯示最近的修改資訊,包括提交者,只就這一點就值得推薦了。

image.png

  • Git History:可以輕鬆快速瀏覽Git檔案操作歷史記錄的工具,視覺化展示,操作簡單。

05、Git使用入門

5.1、建立倉庫

建立本地倉庫的方法有兩種:

  • 一種是建立全新的倉庫:git init,會在當前目錄初始化建立倉庫。
  • 另一種是克隆遠端倉庫:git clone [url]
# 準備一個資料夾“KwebNote”作為倉庫目錄,命令列進入該資料夾
Kwongad@Kwongad-T14 MINGW64 ~
$ cd d:
Kwongad@Kwongad-T14 MINGW64 /d
$ cd Project_Files
Kwongad@Kwongad-T14 MINGW64 /d/Project_Files
# 多次cd指令進入到倉庫目錄KwebNote:“cd <目錄名稱>”指令進入目錄,“cd ..”返回上級目錄(有空格)
Kwongad@Kwongad-T14 MINGW64 /d/Project_Files/github.kwong/KwebNote

# 開始初始化專案,也可指定目錄:git init [檔案目錄]
$ git init
Initialized empty Git repository in D:/Project_Files/github.Kwong/KwebNote/.git/

?注意:Git指令的執行,都需在倉庫目錄下。

建立完多出了一個被隱藏的.git目錄,這就是本地倉庫Git的工作場所。

image.png

克隆遠端倉庫,如在github上建立的倉庫“https://github.com/kwonganding/KWebNote.git

$ git clone 'https://github.com/kwonganding/KWebNote.git'
Cloning into 'KWebNote'...
remote: Enumerating objects: 108, done.
remote: Counting objects: 100% (108/108), done.
remote: Compressing objects: 100% (60/60), done.
remote: Total 108 (delta 48), reused 88 (delta 34), pack-reused 0
Receiving objects: 100% (108/108), 9.36 KiB | 736.00 KiB/s, done.
Resolving deltas: 100% (48/48), done.

會在當前目錄下建立“KWebNote”專案目錄。

image.png

5.2、暫存區add

可以簡單理解為,git add命令就是把要提交的所有修改放到暫存區(Stage),然後,執行git commit就可以一次性把暫存區的所有修改提交到倉庫。

指令 描述
git add [file1] [file2] 新增檔案到暫存區,包括修改的檔案、新增的檔案
git add [dir] 同上,新增目錄到暫存區,包括子目錄
git add . 同上,新增所有修改、新增檔案(未跟蹤)到暫存區
git rm [file] 刪除工作區檔案,並且將這次刪除放入暫存區
# 新增指定檔案到暫存區,包括被修改的檔案
$ git add [file1] [file2] ...

# 新增當前目錄的所有檔案到暫存區
$ git add .

# 刪除工作區檔案,並且將這次刪除放入暫存區
$ git rm [file1] [file2] ...

# 改名檔案,並且將這個改名放入暫存區
$ git mv [file-original] [file-renamed]

修改檔案“R.md”,未暫存:

image.png

執行git add .暫存:

image.png

5.3、提交commit-記錄

git commit提交是以時間順序排列被儲存到資料庫中的,就如遊戲關卡一樣,每一次提交(commit)就會產生一條記錄:id + 描述 + 快照內容

  • ?commit id:根據修改的檔案內容採用摘要演算法(SHA1)計算出不重複的40位字元,這麼長是因為Git是分散式的,要保證唯一性、完整性,一般本地指令中可以只用前幾位(6)。即使多年以後,依然可透過id找到曾經的任何內容和變動,再也不用擔心丟失了。
  • ?描述:針對本次提交的描述說明,建議準確填寫,就跟程式碼中的註釋一樣,很重要。
  • ?快照:就是完整的版本檔案,以物件樹的結構存在倉庫下\.git\objects目錄裡,這也是Git效率高的秘訣之一。
  • SHA1 是一種雜湊演算法,可以用來生成資料摘要
  • Git不適合大的非文字檔案,會影響計算摘要、快照的效能。

多個提交就形成了一條時間線,每次提交完,會移動當前分支masterHEAD的“指標”位置。

image

Sourcetree上的歷史記錄:

image.png

?一般情況,每完成一個小功能、一個Bu就可以提交一次,這樣會形成比較清晰的歷史記錄。

?指令:

指令 描述
git commit -m '說明' 提交變更,引數-m設定提交的描述資訊,應該正確提交,不帶該引數會進入說明編輯模式
git commit -a 引數-a,表示直接從工作區提交到版本庫,略過了git add步驟,不包括新增的檔案
git commit [file] 提交暫存區的指定檔案到倉庫區
git commit --amend -m 使用一次新的commit,替代上一次提交,會修改commithash值(id)
git log -n20 檢視日誌(最近20條),不帶引數-n則顯示所有日誌
git log -n20 --oneline 引數“--oneline”可以讓日誌輸出更簡潔(一行)
git log -n20 --graph 引數“--graph”視覺化顯示分支關係
git log --follow [file] 顯示某個檔案的版本歷史
git blame [file] 以列表形式顯示指定檔案的修改記錄
git reflog 檢視所有可用的歷史版本記錄(實際是HEAD變更記錄),包含被回退的記錄(重要
git status 檢視本地倉庫狀態,比較常用的指令,加引數-s簡潔模式

image

透過git log指令可以檢視提交記錄日誌,可以很方便的檢視每次提交修改了哪些檔案,改了哪些內容,從而進行恢復等操作。

# 提交暫存區到倉庫區
$ git commit -m [message]
# 提交所有修改到倉庫
$ git commit -a -m'修改README的版權資訊'

# 提交暫存區的指定檔案到倉庫區
$ git commit [file1] [file2] ... -m [message]

# 使用一次新的commit,替代上一次提交
# 如果程式碼沒有任何新變化,則用來改寫上一次commit的提交資訊
$ git commit --amend -m [message]

$ git log -n2
commit 412b56448568ff362ef312507e78797befcf2846 (HEAD -> main)
Author: Kanding <123anding@163.com>
Date:   Thu Dec 1 19:02:22 2022 +0800

commit c0ef58e3738f7d54545d8c13d603cddeee328fcb
Author: Kanding <123anding@163.com>
Date:   Thu Dec 1 16:52:56 2022 +0800

# 用引數“--oneline”可以讓日誌輸出更簡潔(一行)
$ git log -n2 --oneline
5444126 (HEAD -> main, origin/main, origin/HEAD) Update README.md
228362e Merge branch 'main' of github.com:kwonganding/KWebNote

5.4、Git的“指標”引用們

Git中最重要的就是提交記錄了,其他如標籤分支HEAD 都對提交記錄的“指標”引用,指向這些提交記錄,理解這一點很重要。

  • 提交記錄之間也存在“指標”引用,每個提交會指向其上一個提交。
  • 標籤 就是對某一個提交記錄的的 固定 “指標”引用,取一個別名更容易記憶一些關鍵節點。儲存在工作區根目錄下.git\refs\tags
  • 分支 也是指向某一個提交記錄的“指標”引用,“指標”位置可變,如提交、更新、回滾。儲存在工作區根目錄下.git\refs\heads
  • HEAD:指向當前活動分支(最新提交)的一個“指標”引用,存在在“.git/HEAD”檔案中,儲存的內容為“ref: refs/heads/master”。

image

上圖中:

  • HEAD始終指向當前活動分支,多個分支只能有一個處於活動狀態。
  • 標籤t1在某一個提交上建立後,就不會變了。而分支、HEAD的位置會改變。

開啟這些檔案內容看看,就更容易理解這些“指標”的真面目了。

# tag
$ git tag -a 'v1' -m'v1版本'
$ cat .git/refs/tags/v1
a2e2c9caea35e176cf61e96ad9d5a929cfb82461

# main分支指向最新的提交
$ cat .git/refs/heads/main
8f4244550c2b6c23a543b741c362b13768442090

# HEAD指向當前活動分支
$ cat .git/HEAD
ref: refs/heads/main

# 切換到dev分支,HEAD指向了dev
$ git switch dev
Switched to branch 'dev'
$ cat .git/HEAD
ref: refs/heads/dev

這裡的主分支名字為“main”,是因為該倉庫是從Github上克隆的,Github上建立的倉庫預設主分支名字就是“main”,本地建立的倉庫預設主分支名字為“master”。

?“指標”引用:之所以用引號的“指標”,是為了便於統一和理解。和指標原理類似,都是一個指向,只是實際上可能更復雜一點,且不同的“指標”引用會有區別。

5.5、提交的唯一標識id,HEAD~n是什麼意思?

每一個提交都有一個唯一標識,主要就是提交的hashcommit id,在很多指令中會用到,如版本回退、揀選提交等,需要指定一個提交。那標識唯一提交有兩種方式:

  • 首先就是commit id,一個40位編碼,指令中使用的時候可以只輸入前幾位(6位)即可。
  • 還有一種就是HEAD~n,是基於當前HEAD位置的一個相對座標。
    • HEAD 表示當前分支的最新版本,是比較常用的引數。
    • HEAD^上一個版本,HEAD^^ 上上一個版本。
    • HEAD~HEAD~1 表示上一個版本,以此類推,HEAD^10 為最近第10個版本。
    • HEAD@{2}git reflog日誌中標記的提交記錄索引。

透過git loggit reflog可以檢視歷史日誌,可以看每次提交的唯一編號(hash)。區別是git reflog可以檢視所有操作的記錄(實際是HEAD變更記錄),包括被撤銷回退的提交記錄。

$ git reflog -n10
5acc914 (HEAD -> main) HEAD@{0}: reset: moving to HEAD~
738748b (dev) HEAD@{1}: reset: moving to HEAD~
9312c3e HEAD@{2}: reset: moving to HEAD~
db03fcb HEAD@{3}: reset: moving to HEAD~
1b81fb3 HEAD@{4}: reset: moving to HEAD~
41ea423 HEAD@{5}: reset: moving to HEAD~
d3e15f9 HEAD@{6}: reset: moving to d3e15f9
1b81fb3 HEAD@{7}: reset: moving to HEAD~1
41ea423 HEAD@{8}: reset: moving to HEAD~
d3e15f9 HEAD@{9}: reset: moving to HEAD~

5.6、比較diff

git diff用來比較不同檔案版本之間的差異。

指令 描述
git diff 檢視暫存區和工作區的差異
git diff [file] 同上,指定檔案
git diff --cached 檢視已暫存的改動,就是暫存區與新版本HEAD進行比較
git diff --staged 同上
git diff --cached [file] 同上,指定檔案
git diff HEAD 檢視已暫存的+未暫存的所有改動,就是與最新版本HEAD進行比較
git diff HEAD~ 同上,與上一個版本比較。HEAD~表示上一個版本,HEAD~10為最近第10個版本
git diff [id] [id] 檢視兩次提交之間的差異
git diff [branch] 檢視工作區和分支直接的差異

☘️畫個圖更清晰些:

image

# 檢視檔案的修改
$ git diff README.md

# 檢視兩次提交的差異
$ git diff 8f4244 1da22

# 顯示今天你寫了多少行程式碼:工作區+暫存區
$ git diff --shortstat "@{0 day ago}"

06、遠端倉庫

Git作為分散式的版本管理系統,每個終端都有自己的Git倉庫。但團隊協作還需一箇中間倉庫,作為中心,同步各個倉庫。於是服務端(遠端)倉庫就來承擔這個職責,服務端不僅有倉庫,還配套相關管理功能。

image

可以用公共的Git伺服器,也可以自己搭建一套Git伺服器。

6.1、遠端使用者登入

Git伺服器一般提供兩種登入驗證方式:

  • HTTS:基於HTTPS連線,使用使用者名稱、密碼身份驗證。
    • 每次都要輸入使用者名稱、密碼,當然可以記住。
    • 地址形式:https://github.com/kwonganding/KWebNote.git
  • SSL:採用SSL通訊協議,基於公私鑰進行身份驗證,所以需要額外配置公私秘鑰。
    • 不用每次輸入使用者名稱、密碼,比較推薦的方法。
    • 地址形式:git@github.com:kwonganding/KWebNote.git

image.png

#檢視當前遠端倉庫使用的那種協議連線:
$ git remote -v
origin  git@github.com:kwonganding/KWebNote.git (fetch)
origin  https://github.com/kwonganding/KWebNote.git (push)

# 更改為https地址,即可切換連線模式。還需要禁用掉SSL, 才能正常使用https管理git
git config --global http.sslVerify false

?遠端使用者登入:HTTS

基於HTTPS的地址連線遠端倉庫,Github的共有倉庫克隆、拉取(pull)是不需要驗證的。

image.png

$ git clone 'https://github.com/kwonganding/KWebNote.git'
Cloning into 'KWebNote'...

# 倉庫配置檔案“.git/config”
[remote "origin"]
 	url = https://github.com/kwonganding/KWebNote.git
	fetch = +refs/heads/*:refs/remotes/origin/*
	pushurl = https://github.com/kwonganding/KWebNote.git

推送(push)程式碼的時候就會提示輸入使用者名稱、密碼了,否則無法提交。記住使用者密碼的方式有兩種:

  • ?URL地址配置:在原本URL地址上加上使用者名稱、密碼,https://後加使用者名稱:密碼@
# 直接修改倉庫的配置檔案“.git/config”
[remote "origin"]
 	url = https://使用者名稱:密碼@github.com/kwonganding/KWebNote.git
	fetch = +refs/heads/*:refs/remotes/origin/*
	pushurl = https://github.com/kwonganding/KWebNote.git
  • ?本地快取:會建立一個快取檔案.git-credentials,儲存輸入的使用者名稱、密碼。
# 引數“--global”全域性有效,也可以針對倉庫設定“--local”
# store 表示永久儲存,也可以設定臨時儲存
git config --global credential.helper store

# 儲存內容如下,開啟檔案“倉庫\.git\.git-credentials”
https://kwonganding:[加密內容付費可見]@github.com

?遠端使用者登入:SSH

image.png

SSH(Secure Shell,安全外殼)是一種網路安全協議,透過加密和認證機制實現安全的訪問和檔案傳輸等業務,多用來進行遠端登入、資料傳輸。SSH透過公鑰、私鑰非對稱加密資料,所以SSH需要生成一個公私鑰對,公鑰放伺服器上,私有自己留著進行認證。

① 生成公私鑰:透過Git指令ssh-keygen -t rsa生成公私鑰,一路回車即可完成。生成在“C:\Users\使用者名稱\.ssh”目錄下,檔案id_rsa.pub的內容就是公鑰。

image.png

② 配置公鑰:開啟id_rsa.pub檔案,複製內容。Github上,開啟SettingSSH and GPG keysSSH keys ➤ 按鈕New SSH key,標題(Title)隨意,秘鑰內容貼上進去即可。

image.png

SSH配置完後,可用ssh -T git@github.com來檢測是否連線成功。

$ ssh -T git@github.com
Hi kwonganding! You've successfully authenticated, but GitHub does not provide shell access.

6.2、遠端倉庫指令?

指令 描述
git clone [git地址] 從遠端倉庫克隆到本地(當前目錄)
git remote -v 檢視所有遠端倉庫,不帶引數-v只顯示名稱
git remote show [remote] 顯示某個遠端倉庫的資訊
git remote add [name] [url] 增加一個新的遠端倉庫,並命名
git remote rename [old] [new] 修改遠端倉庫名稱
git pull [remote] [branch] 取回遠端倉庫的變化,並與本地版本合併
git pull 同上,針對當前分支
git fetch [remote] 獲取遠端倉庫的所有變動到本地倉庫,不會自動合併!需要手動合併
git push 推送當前分支到遠端倉庫
git push [remote] [branch] 推送本地當前分支到遠端倉庫的指定分支
git push [remote] --force/-f 強行推送當前分支到遠端倉庫,即使有衝突,⚠️很危險!
git push [remote] --all 推送所有分支到遠端倉庫
git push –u 引數–u表示與遠端分支建立關聯,第一次執行的時候用,後面就不需要了
git remote rm [remote-name] 刪除遠端倉庫
git pull --rebase 使用rebase的模式進行合併

6.3、推送push/拉取pull

git pushgit pull是團隊協作中最常用的指令,用於同步本地、服務端的更新,與他人協作。

?推送(push):推送本地倉庫到遠端倉庫。

  • 如果推送的更新與服務端存在衝突,則會被拒絕,push失敗。一般是有其他人推送了程式碼,導致檔案衝突,可以先pull程式碼,在本地進行合併,然後再push

?拉取(pull):從服務端(遠端)倉庫更新到本地倉庫。

  • git pull:拉取服務端的最新提交到本地,並與本地合併,合併過程同分支的合併。
  • git fetch:拉取服務端的最新提交到本地,不會自動合併,也不會更新工作區。

image

6.4、fetch與pull有什麼不同?

兩者都是從服務端獲取更新,主要區別是fetch不會自動合併,不會影響當前工作區內容。

git pull = git fetch + git merge

  • 如下面圖中,git fetch只獲取了更新,並未影響masterHEAD的位置。
  • 要更新masterHEAD的位置需要手動執行git merge合併。

image

# fetch只更新版本庫
$ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 663 bytes | 44.00 KiB/s, done.
From github.com:kwonganding/KWebNote
   2ba12ca..c64f5b5  main       -> origin/main

# 執行合併,合併自己
$ git merge
Updating 2ba12ca..c64f5b5
Fast-forward
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

07、Git利器-分支

分支是從主線分離出去的“副本”,分支就像是平行宇宙,可獨立發展,獨立編輯、提交,也可以和其他分支合併。分支是Git的核心必殺利器之一,分支建立、切換、刪除都非常快,他非常的輕量。所以,早建分支!多用分支!

image.png

7.1、分支Branch

比如有一個專案團隊,準備10月份釋出新版本,要新開發一堆黑科技功能,佔領市場。你和小夥伴“小美”一起負責開發一個新功能A,開發週期2周,在這兩週你們的程式碼不能影響其他人,不影響主分支。這個時候就可以為這個新功能建立一個分支,你們兩在這個分支上幹活,2周後程式碼開發完了、測試透過,就可以合併進要發版的開發分支了。安全、高效,不影響其他人工作,完美!

image

在實際專案中,一般會建幾個主線分支。

  • ?master:作為主分支,存放穩定的程式碼,就是開發後測試透過的程式碼,不允許隨便修改和合並。
  • ?開發分支:用於團隊日常開發用,比如團隊計劃10月份開發10個功能併發版,則在此分支上進行,不影響主分支的穩定。
  • ?功能A分支:開發人員根據自己的需要,可以建立一些臨時分支用於特定功能的開發,開發完畢後再合併到開發分支,並刪除該分支。

分支就是指向某一個提交記錄的“指標”引用,因此建立分支是非常快的,不管倉庫多大。當我們執行git branch dev建立了一個名字為dev的分支,Git實際上是在.git\refs\heads下建立一個dev的引用檔案(沒有副檔名)。

$ git branch dev
$ cat .git/refs/heads/dev
ca88989e7c286fb4ba56785c2cd8727ea1a07b97

7.2、分支指令?

指令 描述
git branch 列出所有本地分支,加引數-v顯示詳細列表,下同
git branch -r 列出所有遠端分支
git branch -a 列出所有本地分支和遠端分支,用不同顏色區分
git branch [branch-name] 新建一個分支,但依然停留在當前分支
git branch -d dev 刪除dev分支,-D(大寫)強制刪除
git checkout -b dev 從當前分支建立並切換到dev分支
git checkout -b feature1 dev 從本地dev分支程式碼建立一個 feature1分支,並切換到新分支
git branch [branch] [commit] 新建一個分支,指向指定commit id
git branch --track [branch] [remote-branch] 新建一個分支,與指定的遠端分支建立關聯
git checkout -b hotfix remote hotfix 從遠端remotehotfix分支建立本地hotfix分支
git branch --set-upstream [branch] [remote-branch] 在現有分支與指定的遠端分支之間建立跟蹤關聯:
git branch --set-upstream hotfix remote/hotfix
git checkout [branch-name] 切換到指定分支,並更新工作區
git checkout . 撤銷工作區的(未暫存)修改,把暫存區恢復到工作區。
git checkout HEAD . 撤銷工作區、暫存區的修改,用HEAD指向的當前分支最新版本替換
git merge [branch] 合併指定分支到當前分支
git merge --no-ff dev 合併dev分支到當前分支,引數--no-ff禁用快速合併模式
git push origin --delete [branch-name] 刪除遠端分支
git rebase master 將當前分支變基合併到master分支
✅switch:新的分支切換指令 切換功能和checkout一樣,switch只單純的用於切換
git switch master 切換到已有的master分支
git switch -c dev 建立並切換到新的dev分支

?關於 checkout 指令checkout是Git的底層指令,比較常用,也比較危險,他會重寫工作區。支援的功能比較多,能撤銷修改,能切換分支,這也導致了這個指令比較複雜。在Git 2.23版本以後,增加了git switchgit reset指令。

  • git switch:專門用來實現分支切換。
  • git reset:專門用來實現本地修改的撤銷,更多可參考後續“reset”內容。
$ git branch
  dev
* main
# 列出了當前的所有分支,星號“*”開頭的“main”為當前活動分支。

7.3、分支的切換checkout

程式碼倉庫可以有多個分支,master為預設的主分支,但只有一個分支在工作狀態。所以要操作不同分支,需要切換到該分支,HEAD就是指向當前正在活動的分支。

image

# 切換到dev分支,HEAD指向了dev
# 此處 switch 作用同 checkout,switch只用於切換,不像checkout功能很多
$ git switch dev
Switched to branch 'dev'
$ cat .git/HEAD
ref: refs/heads/dev

使用 git checkout dev切換分支時,幹了兩件事:

  • ①、HEAD指向dev:修改HEAD的“指標”引用,指向dev分支。
  • ②、還原工作空間:把dev分支內容還原到工作空間。

此時的活動分支就是dev了,後續的提交就會更新到dev分支了。

❓切換時還沒提交的程式碼怎麼辦?

  • 如果修改(包括未暫存、已暫存)和待切換的分支沒有衝突,則切換成果,且未提交修改會一起帶過去,所以要注意!
  • 如果有衝突,則會報錯,提示先提交或隱藏,關於隱藏可檢視後續章節內容“stash”。

7.4、合併merge&衝突

把兩個分支的修改內容合併到一起,常用的合併指令git merge [branch],將分支[branch]合併到當前分支。根據要合併的內容的不同,具體合併過程就會有多種情況。

image

?快速合併(Fast forward)

如下圖,master分支麼有任何提交,“git merge dev”合併分支devmaster,此時合併速度就非常快,直接移動master的“指標”引用到dev即可。這就是快速合併(Fast forward),不會產生新的提交。

image

  • 合併devmaster,注意要先切換到master分支,然後執行git merge dev,把dev合併到當前分支。

?強制不用快速合併git merge --no-ff -m "merge with no-ff" dev,引數--no-ff不啟用快速合併,會產生一個新的合併提交記錄。

?普通合併

如果master有變更,存在分支交叉,則會把兩邊的變更合併成一個提交。

  • 如果兩邊變更的檔案不同,沒有什麼衝突,就自動合併了。
  • 如果有修改同一個檔案,則會存在衝突,到底該採用哪邊的,程式無法判斷,就換產生衝突。衝突內容需要人工修改後再重新提交,才能完成最終的合併。

image

上圖中,建立dev分支後,兩個分支都有修改提交,因此兩個分支就不在一條順序線上了,此時合併devmaster就得把他們的修改進行合併操作了。

  • v5v7共同祖先是v4,從這裡開始分叉。
  • Git 會用兩個分支的末端v6v8以及它們的共同祖先v4進行三方合併計算。合併之後會生成一個新(和並)提交v9
  • 合併提交v9就有兩個祖先v6v8

?處理衝突<<<<<<< HEAD

在有衝突的檔案中,<<<<<<< HEAD開頭的內容就表示是有衝突的部分,需要人工處理,可以藉助一些第三方的對比工具。人工處理完畢後,完成合並提交,才最終完成此次合併。=======分割線上方是當前分支的內容,下方是被合併分支的變更內容。

image.png

7.5、變基rebase

把兩個分支的修改內容合併到一起的辦法有兩種:mergerebase,作用都是一樣的,區別是rebase的提交歷史更簡潔,幹掉了分叉,merge的提交歷史更完整。

image

  • dev上執行“git rebase master”變基,將dev分支上分叉的v7v8生成補丁,然後在master分支上應用補丁,產生新的v7'v8'新的提交。
  • 然後回到master分支,完成合並git merge dev,此時的合併就是快速合併了。
  • 最終的提交記錄就沒有分叉了。
$ git rebase master
$ git checkout master
$ git merge dev

08、標籤管理

標籤(Tags)指的是某個分支某個特定時間點的狀態,是對某一個提交記錄的的固定“指標”引用。一經建立,不可移動,儲存在工作區根目錄下.git\refs\tags。可以理解為某一次提交(編號)的別名,常用來標記版本。所以釋出時,一般都會打一個版本標籤,作為該版本的快照,指向對應提交commit

當專案達到一個關鍵節點,希望永遠記住那個特別的提交快照,你可以使用 git tag 給它打上標籤。比如我們今天終於完成了V1.1版本的開發、測試,併成功上線了,那就可給今天最後這個提交打一個標籤“V1.1”,便於版本管理。

預設標籤是打在最新提交的commit上的,如果希望在指定的提交上打標籤則帶上提交編號(commit id):git tag v0.9 f52c633

image

指令 描述
git tag 檢視標籤列表
git tag -l 'a*' 檢視名稱是“a”開頭的標籤列表,帶查詢引數
git show [tagname] 檢視標籤資訊
git tag [tagname] 建立一個標籤,預設標籤是打在最新提交的commit上的
git tag [tagname] [commit id] 新建一個tag在指定commit上
git tag -a v5.1 -m'v5.1版本' 建立標籤v5.1.1039-a指定標籤名,-m指定說明文字
git tag -d [tagname] 刪除本地標籤
git checkout v5.1.1039 切換標籤,同切換分支
git push [remote] v5.1 推送標籤,標籤不會預設隨程式碼推送推送到服務端
git push [remote] --tags 提交所有tag

如果要推送某個標籤到遠端,使用命令git push origin [tagname],或者,一次性推送全部到遠端:git push origin --tags

?注意:標籤總是和某個commit掛鉤。如果這個commit既出現在master分支,又出現在dev分支,那麼在這兩個分支上都可以看到這個標籤。

# tag
$ git tag -a 'v1' -m'v1版本'
$ cat .git/refs/tags/v1
a2e2c9caea35e176cf61e96ad9d5a929cfb82461

# 檢視標籤列表
$ git tag
v1

09、後悔藥-怎麼撤銷變更?

發現寫錯了要回退怎麼辦?看看下面幾種後悔指令吧!

  • 還沒提交的怎麼撤銷? —— checkoutreset
    • 還未提交的修改(工作區、暫存區)不想要了,用簽出指令(checkout)進行撤銷清除。
    • 或者用checkout的新版回滾指令reset
  • 已提交但麼有push的提交如何撤銷?—— resetrevert
  • 已push的提交如何撤銷?—— 同上,先本地撤銷,然後強制推送git push origin -f⚠️注意慎用! 記得先pull獲取更新。

image

9.1、後悔指令?

指令 描述
git checkout . 撤銷工作區的(未暫存)修改,把暫存區恢復到工作區。不影響暫存區,如果沒暫存,則撤銷所有工作區修改
git checkout [file] 同上,file指定檔案
git checkout HEAD . 撤銷工作區、暫存區的修改,用HEAD指向的當前分支最新版本替換工作區、暫存區
git checkout HEAD [file] 同上,file指定檔案
git reset 撤銷暫存區狀態,同git reset HEAD,不影響工作區
git reset HEAD [file] 同上,指定檔案fileHEAD可省略
git reset [commit] 回退到指定版本,清空暫存區,不影響工作區。工作區需要手動git checkout簽出
git reset --soft [commit] 移動分支masterHEAD到指定的版本,不影響暫存區、工作區,需手動git checkout簽出更新
git reset --hard HEAD 撤銷工作區、暫存區的修改,用當前最新版
git reset --hard HEAD~ 回退到上一個版本,並重置工作區、暫存區內容。
git reset --hard [commit] 回退到指定版本,並重置工作區、暫存區內容。
git revert[commit] 撤銷一個提交,會用一個新的提交(原提交的逆向操作)來完成撤銷操作,如果已push則重新push即可
  • git checkout .git checkout [file] 會清除工作區中未新增到暫存區的修改,用暫存區內容替換工作區。
  • git checkout HEAD . git checkout HEAD [file] 會清除工作區、暫存區的修改,用HEAD指向的當前分支最新版本替換暫存區、工作區。
# 只撤銷工作區的修改(未暫存)
$ git checkout .
Updated 1 path from the index

# 撤銷工作區、暫存區的修改
$ git checkout HEAD .
Updated 1 path from f951a96

9.2、回退版本reset

reset是專門用來撤銷修改、回退版本的指令,支援的場景比較多,多種撤銷姿勢,所以引數組合也比較多。簡單理解就是移動master分支、HEAD的“指標”地址,理解這一點就基本掌握reset了。

如下圖:

  • 回退版本git reset --hard v4 或 git reset --hard HEAD~2masterHEAD會指向v4提交,v5v6就被廢棄了。
  • 也可以重新恢復到v6版本:git reset --hard v6,就是移動masterHEAD的“指標”地址。

image

reset有三種模式,對應三種引數:mixed(預設模式)、softhard。三種引數的主要區別就是對工作區、暫存區的操作不同。

  • mixed為預設模式,引數可以省略。
  • 只有hard模式會重置工作區、暫存區,一般用這個模式會多一點。

image

模式名稱\ 描述 HEAD的位置 暫存區 工作區
soft 回退到某一個版本,工作區不變,需手動git checkout 修改 不修改 不修改
mixed(預設) 撤銷暫存區狀態,不影響工作區,需手動git checkout 修改 修改 不修改
hard 重置未提交修改(工作區、暫存區) 修改 修改 修改

穿梭前,用git log可以檢視提交歷史,以便確定要回退到哪個版本。要重返未來,用git reflog檢視命令歷史,以便確定要回到未來的哪個版本。

git reset [--soft | --mixed | --hard] [HEAD]

# 撤銷暫存區
$ git reset
Unstaged changes after reset:
M       R.md

# 撤銷工作區、暫存區修改
$ git reset --hard HEAD

# 回退版本庫到上一個版本,並重置工作區、暫存
$ git reset --hard HEAD~

# 回到原來的版本(恢復上一步的撤銷操作),並重置工作區、暫存
$ git reset --hard 5f8b961

# 檢視所有歷史提交記錄
$ git reflog
ccb9937 (HEAD -> main, origin/main, origin/HEAD) HEAD@{0}: commit: 報表新增匯入功能
8f61a60 HEAD@{1}: commit: bug:修復報表匯出bug
4869ff7 HEAD@{2}: commit: 使用者報表模組開發
4b1028c HEAD@{3}: commit: 財務報表模組開發完成

9.3、撤銷提交revert

安全的撤銷某一個提交記錄,基本原理就是生產一個新的提交,用原提交的逆向操作來完成撤銷操作。注意,這不同於resetreset是回退版本,revert只是用於撤銷某一次歷史提交,操作是比較安全的。

image

如上圖:

  • 想撤銷v4的修改,執行git revert v4,會產生一個新的提交v-4,是v4的逆向操作。
  • 同時更新maserHEAD“指標”位置,以及工作區內容。
  • 如果已push則重新push即可。
# revert撤銷指定的提交,“-m”附加說明
$ git revert 41ea42 -m'撤銷對***的修改'
[main 967560f] Revert "123"
                            1 file changed, 1 deletion(-)

9.4、checkout/reset/revert總結

標題 \ 指令 checkout reset revert
主要作用(撤銷) 撤銷工作區、暫存區未提交修改 回退版本,重置工作區、暫存區 撤銷某一次提交
撤銷工作區 git checkout [file] git reset HEAD [file]
撤銷工作區、暫存區 git checkout HEAD [file] git reset --hard HEAD [file]
回退版本 git reset --hard [commit]
安全性 只針對未提交修改,安全 如回退了已push提交,不安全 安全

可看出reset完全可以替代checkout來執行撤銷、回退操作,reset本來也是專門用來幹這個事情的,可以拋棄checkout了(撤銷的時候)。


10、工作中的Git實踐

10.1、Git flow

Git flow(Git工作流程)是指軟體專案中的一種Git分支管理模型,經過了大量的實踐和最佳化,被認為是現代敏捷軟體開發和DevOps(開發、技術運營和質量保障三者的交集)的最佳實踐。Git flow主要流程及關鍵分支:原圖地址-processon

image.png

✅主分支:master,穩定版本程式碼分支,對外可以隨時編譯釋出的分支,不允許直接Push程式碼,只能請求合併(pull request),且只接受hotfixrelease分支的程式碼合併。

✅熱修復分支:hotfix,針對線上緊急問題、bug修復的程式碼分支,修復完後合併到主分支、開發分支。

  • ① 切換到hotfix分支,從master更新程式碼;
  • ② 修復bug;
  • ③ 合併程式碼到dev分支,在本地Git中操作即可;
  • ④ 合併程式碼到master分支。

image.png

✅發版分支:release,版本釋出分支,用於迭代版本釋出。迭代開發完成後,合併dev程式碼到release,在release分支上編譯釋出版本,以及修改bug(定時同步bug修改到dev分支)。測試完成後此版本可以作為發版使用,然後把穩定的程式碼push到master分支,並打上版本標籤。

✅開發分支:dev,開發版本分支,針對迭代任務開發的分支,日常開發原則上都在此分支上面,迭代完成後合併到release分支,開發、發版兩不誤。

image.png

✅其他開發分支:dev-xxx,開發人員可以針對模組自己建立本地分支,開發完成後合併到dev開發分支,然後刪除本地分支。

10.2、金屋藏嬌stash

當你正在dev分支開發一個功能時,程式碼寫了一半,突然有一個線上的bug急需要馬上修改。dev分支Bug沒寫完,不方便提交,就不能切換到主分支去修復線上bug。Git提供一個stash功能,可以把當前工作區、暫存區 未提交的內容“隱藏”起來,就像什麼都沒發生一樣。

# 有未提交修改,切換分支時報錯
$ git checkout dev
error: Your local changes to the following files would be overwritten by checkout:
        README.md
Please commit your changes or stash them before you switch branches.
Aborting

# 隱藏
$ git stash
Saved working directory and index state WIP on main: 2bc012c s

# 檢視被隱藏的內容
$ git stash list
stash@{0}: WIP on main: 2bc012c s

# 比較一下,什麼都沒有,一切都沒有發生過!
$ git diff

# 去其他分支修改bug,修復完成回到當前分支,恢復工作區
$ git stash pop

在上面示例中,有未提交修改,切換分支時報錯。錯誤提示資訊很明確了,commit提交或stash隱藏:Please commit your changes or stash them before you switch branches.

? 如果切換分支時,未提交修改的內容沒有衝突,是可以成功切換的,未提交修改會被帶過去。

指令 描述
git stash 把未提交內容隱藏起來,包括未暫存、已暫存。 等以後恢復現場後繼續工作
git stash list 檢視所有被隱藏的內容列表
git stash pop 恢復被隱藏的內容,同時刪除隱藏記錄
git stash save "message" git stash,可以備註說明message
git stash apply 恢復被隱藏的檔案,但是隱藏記錄不刪除
git stash drop 刪除隱藏記錄

?當然這裡先提交到本地也是可以的,只是提交不是一個完整的功能程式碼,而是殘缺的一部分,影響也不大。

揀選提交cherry-pick

當有一個緊急bug,在dev上修復完,我們需要把dev上的這個bug修復所做的修改“複製”到master分支,但不想把整個dev合併過去。為了方便操作,Git專門提供了一個cherry-pick命令,讓我們能複製一個特定的提交到當前分支,而不管這個提交在哪個分支。

image

如上圖,操作過程相當於將該提交匯出為補丁檔案,然後在當前HEAD上重放,形成無論內容還是提交說明都一致的提交。

  • 希望把dev分支上的v7提交的內容合併到master,但不需要其他的內容。
  • master分支上執行指令git cherry-pick v7,會產生一個新的v7'提交,內容和v7相同。
  • 同時更新masterHEAD,以及工作區。
# 選擇一個commit,合併進當前分支
$ git cherry-pick [commit]

參考資料


©️版權申明:版權所有@安木夕,本文內容僅供學習,歡迎指正、交流,轉載請註明出處!原文編輯地址-語雀

相關文章