最新、最全、最詳細的 Git 學習筆記總結(2021最新版)

Git 簡介

Git 是一個開源的分佈式版本控制系統。git

什麼是版本控制?
版本控制是一種記錄一個或若干文件內容變化,以便未來查閱特定版本修訂狀況的系統。數據庫

什麼是分佈式版本控制系統?

介紹分佈式版本控制系統前,有必要先了解一下傳統的集中式版本控制系統。編程

集中化的版本控制系統,諸如 CVS,Subversion 等,都有一個單一的集中管理的服務器,保存全部文件的修訂版本,而協同工做的人們都經過客戶端連到這臺服務器,取出最新的文件或者提交更新。緩存

這麼作最顯而易見的缺點是中央服務器的單點故障。若是宕機一小時,那麼在這一小時內,誰都沒法提交更新,也就沒法協同工做。要是中央服務器的磁盤發生故障,碰巧沒作備份,或者備份不夠及時,就會有丟失數據的風險。最壞的狀況是完全丟失整個項目的全部歷史更改記錄。安全

分佈式版本控制系統的客戶端並不僅提取最新版本的文件快照,而是把代碼倉庫完整地鏡像下來。這麼一來,任何一處協同工做用的服務器發生故障,過後均可以用任何一個鏡像出來的本地倉庫恢復。由於每一次的提取操做,實際上都是一次對代碼倉庫的完整備份。服務器

可參考:Git 從入門到精通app

Git vs SVN

Git 和 SVN 孰優孰好,每一個人有不一樣的體驗。dom

Git是分佈式的,SVN是集中式的ssh

這是 Git 和 SVN 最大的區別。若能掌握這個概念,二者區別基本搞懂大半。由於 Git 是分佈式的,因此 Git 支持離線工做,在本地能夠進行不少操做,包括接下來將要重磅推出的分支功能。而 SVN 必須聯網才能正常工做。curl

  • Git複雜概念多,SVN簡單易上手

全部同時掌握 Git 和 SVN 的開發者都必須認可,Git 的命令實在太多了,平常工做須要掌握add,commit,status,fetch,push,rebase等,若要熟練掌握,還必須掌握rebase和merge的區別,fetch和pull的區別等,除此以外,還有cherry-pick,submodule,stash等功能,僅是這些名詞聽着都很繞。

在易用性這方面,SVN對於新手來講會更有好一些。可是從另一方面看,Git 命令多意味着功能多,若咱們能掌握大部分 Git 的功能,體會到其中的奧妙,會發現再也回不去 SVN 的時代了。

  • Git分支廉價,SVN分支昂貴

在版本管理裏,分支是很常使用的功能。在發佈版本前,須要發佈分支,進行大需求開發,須要 feature 分支,大團隊還會有開發分支,穩定分支等。在大團隊開發過程當中,經常存在建立分支,切換分支的求。

Git 分支是指針指向某次提交,而 SVN 分支是拷貝的目錄。這個特性使 Git 的分支切換很是迅速,而且建立成本很是低。

並且 Git 有本地分支,SVN 無本地分支。在實際開發過程當中,常常會遇到有些代碼沒寫完,可是需緊急處理其餘問題,若咱們使用 Git,即可以建立本地分支存儲沒寫完的代碼,待問題處理完後,再回到本地分支繼續完成代碼。

更多關注Git與Svn的比較請參閱:通俗易懂|用好Git 和 SVN ,輕鬆駕馭版本管理

Git 工做原理

文字很差理解,請看 圖文詳解 Git 工做原理

Git 安裝

  • Debian/Ubuntu 環境安裝

若是你使用的系統是 Debian/Ubuntu , 安裝命令爲:

$ apt-get install libcurl4-gnutls-dev libexpat1-dev gettext \
> libz-dev libssl-dev
$ apt-get install git-core
$ git --version
git version 1.8.1.2
  • Centos/RedHat 環境安裝

若是你使用的系統是 Centos/RedHat ,安裝命令爲:

$ yum install curl-devel expat-devel gettext-devel \
> openssl-devel zlib-devel
$ yum -y install git-core
$ git --version
git version 1.7.1
  • Windows 環境安裝

在 Git 官方下載地址下載 exe 安裝包。按照安裝嚮導安裝便可。

建議安裝 Git Bash 這個 git 的命令行工具。

  • Mac 環境安裝

在 Git 官方下載地址下載 mac 安裝包。按照安裝嚮導安裝便可。

Git配置

Git 自帶一個 git config 的工具來幫助設置控制 Git 外觀和行爲的配置變量。這些變量存儲在三個不一樣的位置:

/etc/gitconfig 文件: 包含系統上每個用戶及他們倉庫的通用配置。若是使用帶有 --system 選項的 git config 時,它會今後文件讀寫配置變量。

\~/.gitconfig 或 \~/.config/git/config 文件:只針對當前用戶。能夠傳遞 --global 選項讓 Git 讀寫此文件。

當前使用倉庫的 Git 目錄中的 config 文件(就是 .git/config):針對該倉庫。

每個級別覆蓋上一級別的配置,因此 .git/config 的配置變量會覆蓋 /etc/gitconfig 中的配置變量。

在 Windows 系統中,Git 會查找 $HOME 目錄下(通常狀況下是 C:\Users\$USER)的 .gitconfig 文件。Git 一樣也會尋找 /etc/gitconfig 文件,但只限於 MSys 的根目錄下,即安裝 Git 時所選的目標位置。

Git 基本概念

  • 版本庫

當你一個項目到本地或建立一個 git 項目,項目目錄下會有一個隱藏的 .git 子目錄。這個目錄是 git 用來跟蹤管理版本庫的,千萬不要手動修改。

  • 哈希值

Git 中全部數據在存儲前都計算校驗和,而後以校驗和來引用。這意味着不可能在 Git 不知情時更改任何文件內容或目錄內容。這個功能建構在 Git 底層,是構成 Git 哲學不可或缺的部分。若你在傳送過程當中丟失信息或損壞文件,Git 就能發現。

Git 用以計算校驗和的機制叫作 SHA-1 散列(hash,哈希)。這是一個由 40 個十六進制字符(0-9 和 a-f)組成字符串,基於 Git 中文件的內容或目錄結構計算出來。SHA-1 哈希看起來是這樣:

24b9da6552252987aa493b52f8696cd6d3b00373
Git 中使用這種哈希值的狀況不少,你將常常看到這種哈希值。實際上,Git 數據庫中保存的信息都是以文件內容的哈希值來索引,而不是文件名。

  • 文件狀態

在 GIt 中,你的文件可能會處於三種狀態之一:

  • 已修改(modified) - 已修改表示修改了文件,但還沒保存到數據庫中。
  • 已暫存(staged) - 已暫存表示對一個已修改文件的當前版本作了標記,使之包含在下次提交的快照中。
  • 已提交(committed) - 已提交表示數據已經安全的保存在本地數據庫中。
  • 工做區域

與文件狀態對應的,不一樣狀態的文件在 Git 中處於不一樣的工做區域。

  • 工做區(working) - 當你 git clone 一個項目到本地,至關於在本地克隆了項目的一個副本。工做區是對項目的某個版本獨立提取出來的內容。這些從 Git 倉庫的壓縮數據庫中提取出來的文件,放在磁盤上供你使用或修改。
  • 暫存區(staging)- 暫存區是一個文件,保存了下次將提交的文件列表信息,通常在 Git 倉庫目錄中。有時候也被稱做 `‘索引’',不過通常說法仍是叫暫存區。
  • 本地倉庫(local) - 提交更新,找到暫存區域的文件,將快照永久性存儲到 Git 本地倉庫。
  • 遠程倉庫(remote) - 以上幾個工做區都是在本地。爲了讓別人能夠看到你的修改,你須要將你的更新推送到遠程倉庫。同理,若是你想同步別人的修改,你須要從遠程倉庫拉取更新。

  • 分支(Branch)

分支是爲了將修改記錄的整個流程分開存儲,讓分開的分支不受其它分支的影響,因此在同一個數據庫裏能夠同時進行多個不一樣的修改

主分支(Master)前面提到過 master 是 Git 爲咱們自動建立的第一個分支,也叫主分支,其它分支開發完成後都要合併到 master

  • 標籤(Tag)

標籤是用於標記特定的點或提交的歷史,一般會用來標記發佈版本的名稱或版本號(如:publish/0.0.1),雖然標籤看起來有點像分支,但打上標籤的提交是固定的,不能隨意的改動,參見上圖中的1.0 / 2.0 / 3.0

  • HEAD

HEAD 指向的就是當前分支的最新提交圖片

以上概念瞭解的差很少,那就能夠繼續往下看。

Git 命令

  • 建立倉庫

克隆一個已建立的倉庫:

# 經過 SSH
$ git clone ssh://user@domain.com/repo.git

#經過 HTTP
$ git clone http://domain.com/user/repo.git

建立一個新的本地倉庫:

$ git init
  • 添加修改
    添加修改到暫存區:

    # 把指定文件添加到暫存區
    $ git add xxx
    
    # 把當前全部修改添加到暫存區
    $ git add .
    
    # 把全部修改添加到暫存區
    $ git add -A

    提交修改到本地倉庫:

    # 提交本地的全部修改
    $ git commit -a
    
    # 提交以前已標記的變化
    $ git commit
    
    # 附加消息提交
    $ git commit -m 'commit message'
  • 儲藏

有時,咱們須要在同一個項目的不一樣分支上工做。當須要切換分支時,恰恰本地的工做尚未完成,此時,提交修改顯得不嚴謹,可是不提交代碼又沒法切換分支。這時,你可使用 git stash 將本地的修改內容做爲草稿儲藏起來。

官方稱之爲儲藏,但我我的更喜歡稱之爲存草稿。

# 1. 將修改做爲當前分支的草稿保存
$ git stash

# 2. 查看草稿列表
$ git stash list
stash@{0}: WIP on master: 6fae349 :memo: Writing docs.

# 3.1 刪除草稿
$ git stash drop stash@{0}

# 3.2 讀取草稿
$ git stash apply stash@{0}
  • 撤銷修改

撤銷本地修改:

# 移除緩存區的全部文件(i.e. 撤銷上次git add)
$ git reset HEAD

# 將HEAD重置到上一次提交的版本,並將以後的修改標記爲未添加到緩存區的修改
$ git reset <commit>

# 將HEAD重置到上一次提交的版本,並保留未提交的本地修改
$ git reset --keep <commit>

# 放棄工做目錄下的全部修改
$ git reset --hard HEAD

# 將HEAD重置到指定的版本,並拋棄該版本以後的全部修改
$ git reset --hard <commit-hash>

# 用遠端分支強制覆蓋本地分支
$ git reset --hard <remote/branch> e.g., upstream/master, origin/my-feature

# 放棄某個文件的全部本地修改
$ git checkout HEAD <file>

刪除添加.gitignore文件前錯誤提交的文件:

$ git rm -r --cached .
$ git add .
$ git commit -m "remove xyz file"

撤銷遠程修改(建立一個新的提交,並回滾到指定版本):

$ git revert <commit-hash>

完全刪除指定版本:

# 執行下面命令後,commit-hash 提交後的記錄都會被完全刪除,使用需謹慎
$ git reset --hard <commit-hash>
$ git push -f
  • 更新與推送

更新:

# 下載遠程端版本,但不合併到HEAD中
$ git fetch <remote>

# 將遠程端版本合併到本地版本中
$ git pull origin master

# 以rebase方式將遠端分支與本地合併
$ git pull --rebase <remote> <branch>

推送:

# 將本地版本推送到遠程端
$ git push remote <remote> <branch>

# 刪除遠程端分支
$ git push <remote> :<branch> (since Git v1.5.0)
$ git push <remote> --delete <branch> (since Git v1.7.0)

# 發佈標籤
$ git push --tags
  • 查看信息

顯示工做路徑下已修改的文件:

$ git status

顯示與上次提交版本文件的不一樣:

$ git diff

顯示提交歷史:

# 從最新提交開始,顯示全部的提交記錄(顯示hash, 做者信息,提交的標題和時間)
$ git log

# 顯示某個用戶的全部提交
$ git log --author="username"

# 顯示某個文件的全部修改
$ git log -p <file>
  • 顯示搜索內容:

    # 從當前目錄的全部文件中查找文本內容
    $ git grep "Hello"
    
    # 在某一版本中搜索文本
    $ git grep "Hello" v2.5
  • 分支

增刪查分支:

# 列出全部的分支
$ git branch

# 列出全部的遠端分支
$ git branch -r

# 基於當前分支建立新分支
$ git branch <new-branch>

# 基於遠程分支建立新的可追溯的分支
$ git branch --track <new-branch> <remote-branch>

# 刪除本地分支
$ git branch -d <branch>

# 強制刪除本地分支,將會丟失未合併的修改
$ git branch -D <branch>

切換分支:

# 切換分支
$ git checkout <branch>

# 建立並切換到新分支
$ git checkout -b <branch>

標籤

# 給當前版本打標籤
$ git tag <tag-name>

# 給當前版本打標籤並附加消息
$ git tag -a <tag-name>

合併與重置

merge 與 rebase 雖然是 git 經常使用功能,可是強烈建議不要使用 git 命令來完成這項工做。

由於若是出現代碼衝突,在沒有代碼比對工具的狀況下,實在太艱難了。

你能夠考慮使用各類 Git GUI 工具。

合併:

# 將分支合併到當前HEAD中
$ git merge <branch>

重置:

# 將當前HEAD版本重置到分支中,請勿重置已發佈的提交
$ git rebase <branch>

更多命令參考:三年 Git 使用心得 & 常見問題整理

Git 分支開發

Git 是目前最流行的源代碼管理工具。爲規範開發,保持代碼提交記錄以及 git 分支結構清晰,方便後續維護,現規範 git 的相關操做。

分支命名

一、master 分支

master 爲主分支,也是用於部署生產環境的分支,確保master分支穩定性, master 分支通常由develop以及hotfix分支合併,任什麼時候間都不能直接修改代碼

二、develop 分支

develop 爲開發分支,始終保持最新完成以及bug修復後的代碼,通常開發的新功能時,feature分支都是基於develop分支下建立的。

  • feature 分支

開發新功能時,以develop爲基礎建立feature分支。
分支命名: feature/ 開頭的爲特性分支, 命名規則: feature/user_module、 feature/cart_module

  • release分支

release 爲預上線分支,發佈提測階段,會release分支代碼爲基準提測。當有一組feature開發完成,首先會合併到develop分支,進入提測時會建立release分支。若是測試過程當中若存在bug須要修復,則直接由開發者在release分支修復並提交。當測試完成以後,合併release分支到master和develop分支,此時master爲最新代碼,用做上線。

  • hotfix 分支

分支命名: hotfix/ 開頭的爲修復分支,它的命名規則與feature分支相似。線上出現緊急問題時,須要及時修復,以master分支爲基線,建立hotfix分支,修復完成後,須要合併到master分支和develop分支

更多開發規範請參閱:全網最全的 Git 分支開發規範手冊 | 掌握這10條規範,輕鬆搞定Git!

Git這些高級用法,喜歡就拿去用!

Git 提交規範

爲何須要規範?

無規矩不成方圓,編程也同樣。

若是你有一個項目,從始至終都是本身寫,那麼你想怎麼寫均可以,沒有人能夠干預你。但是若是在團隊協做中,你們都張揚個性,那麼代碼將會是一團糟,好好的項目就被糟踐了。無論是開發仍是往後維護,都將是災難。

這時候,有人提出了何不統一標準,你們都按照這個標準來。因而 ESLint,JSHint 等代碼工具如雨後春筍般涌現,成爲了項目構建的必備良品。

Git Commit 規範可能並無那麼誇張,但若是你在版本回退的時候看到一大段糟心的 Commit,恐怕會懊惱不已吧。因此,嚴格遵照規範,利人利己。

具體請參閱:你可能會忽略的 Git 提交規範

Git使用技巧

只有在遇到問題的時候,才體會到技巧帶來的好處!

常見企業工做流程

主要介紹,企業中經常使用的 Git 工做流程!

  • Git Flow
  • 主幹分支
  • 穩定分支
  • 開發分支
  • 補丁分支
  • 修改分支

Github Flow
  • 建立分支
  • 添加提交
  • 提交 PR 請求
  • 討論和評估代碼
  • 部署檢測
  • 合併代碼

圖片

Gitlab Flow
  • 帶生產分支
  • 帶環境分支
  • 帶發佈分支

平常使用最佳實踐

總結平常工做中應該遵循的 Git 使用方式和方法!

  • 使用命令行代替圖形化界面
  • 使用命令行來操做,簡潔且效率高
  • 提交應該儘量的表述提交修改內容
  • 區分 subject 和 body 內容,使用空行隔開
  • subject 通常不超過 50 個字符
  • body 每一行的長度控制在 72 個字符
  • subject 結尾不須要使用句號或者點號結尾
  • body 用來詳細解釋這次提交具體作了什麼
  • 使用 .gitignore 文件來排除無用文件
  • 可以使用模板文件,而後根據項目實際進行修改
  • 基於分支或 fork 的開發模式
  • 不要直接在主幹分支上面進行開發
  • 在新建的分支上進行功能的開發和問題的修復
  • 使用 release 分支和 tag 標記進行版本管理
  • 使用 release 分支發佈代碼和版本維護(release/1.32)
  • 使用 tag 來標記版本(A-大feature功能.B-小feature功能.C-只修bug)

經常使用命令彙總整理

平常使用只要記住 6 個命令就能夠了。

# 工做區 -> 暫存區
$ git add <file/dir>

# 暫存區 -> 本地倉庫
$ git commit -m "some info"

# 本地倉庫 -> 遠程倉庫
$ git push origin master  # 本地master分支推送到遠程origin倉庫
# 工做區 <- 暫存區
$ git checkout -- <file>  # 暫存區文件內容覆蓋工做區文件內容

# 暫存區 <- 本地倉庫
$ git reset HEAD <file>   # 本地倉庫文件內容覆蓋暫存區文件內容

# 本地倉庫 <- 遠程倉庫
$ git clone <git_url>        # 克隆遠程倉庫
$ git fetch upstream master  # 拉取遠程代碼到本地但不該用在當前分支
$ git pull upstream master   # 拉取遠程代碼到本地但應用在當前分支
$ git pull --rebase upstream master  # 若是平時使用rebase合併代碼則加上
# 工做區 <- 本地倉庫
$ git reset <commit>          # 本地倉庫覆蓋到工做區(保存回退文件內容修改)
$ git reset --mixed <commit>  # 本地倉庫覆蓋到工做區(保存回退文件內容修改)
$ git reset --soft <commit>   # 本地倉庫覆蓋到工做區(保留修改並加到暫存區)
$ git reset --hard <commit>   # 本地倉庫覆蓋到工做區(不保留修改直接刪除掉)

更多關於Git的使用技巧介紹請查閱:學會這 11 條,你離 Git 大神就不遠了!

Git 知識體系動態更新看這裏

相關文章
相關標籤/搜索