一、什么是 Git
1. 何為版本控制
版本控制是一種記錄文件變化的系統(tǒng),可以跟蹤文件的修改歷史,并允許用戶在不同版本之間進行比較、恢復或合并。它主要用于軟件開發(fā)過程中管理代碼的變更,但也可以應用于任何需要跟蹤文件變更的場景。
版本控制系統(tǒng)(VCS)可以幫助團隊協(xié)作開發(fā),并提供以下功能:
- 歷史記錄管理:版本控制系統(tǒng)會記錄每個文件的修改歷史,包括修改內容、時間和作者等信息。這使得用戶可以查看文件的演變歷程,了解每次修改的目的和影響。
- 并行開發(fā)支持:多個開發(fā)者可以同時修改同一個項目的不同部分,版本控制系統(tǒng)能夠合并這些修改,并解決可能出現(xiàn)的沖突。
- 備份和恢復:通過版本控制系統(tǒng),可以輕松地恢復到之前的任意版本,即使文件丟失或損壞也能夠通過版本控制系統(tǒng)進行恢復。
- 分支管理:版本控制系統(tǒng)允許創(chuàng)建分支(Branch),開發(fā)者可以在分支上進行實驗性的修改,而不會影響到主要的代碼庫,這使得并行開發(fā)和功能開發(fā)更加靈活。
- 版本標記:可以對重要的版本進行標記(Tag),例如發(fā)布版本或里程碑版本,方便日后查找和引用。
常見的版本控制系統(tǒng)包括 Git、Subversion(SVN)、Mercurial 等,它們都提供了類似的功能,但在實現(xiàn)方式和使用上有所不同。其中,Git 是目前最流行的版本控制系統(tǒng)之一,被廣泛應用于軟件開發(fā)領域。
2. Git 的誕生
Git 的開發(fā)由 Torvalds(林納斯·托瓦茲,Linux 之父)于 2005 年 4 月啟動,起因是 2002 年時,用于 Linux 內核開發(fā)的專有源代碼控制管理(SCM)系統(tǒng) BitKeeper 撤銷了其 Linux 開發(fā)的免費許可證。BitKeeper 的版權所有者 Larry McVoy 聲稱,Andrew Tridgell(Linux 社區(qū)主要貢獻者,Samba之父)通過逆向工程破解了 BitKeeper 的協(xié)議,并創(chuàng)建了SourcePuller。 同一事件還刺激了另一個版本控制系統(tǒng) Mercurial 的創(chuàng)建。
引用:Git - Wikipedia
Git 的誕生是由于 Linux 內核社區(qū)與 BitKeeper 公司之間發(fā)生了一些糾紛,導致 Linux 內核社區(qū)無法繼續(xù)免費使用 BitKeeper。
由于這個事件,Linus Torvalds 決定開始開發(fā)一個新的版本控制系統(tǒng),這個系統(tǒng)要具有以下特點:
- 分布式:與傳統(tǒng)的集中式版本控制系統(tǒng)不同,分布式版本控制系統(tǒng)允許每個開發(fā)者在本地完整地拷貝整個代碼庫,這樣可以在沒有網絡連接的情況下繼續(xù)工作,并且更容易支持分支和合并操作。
- 性能:由于 Linux 內核的規(guī)模巨大,所以版本控制系統(tǒng)必須具備高效的性能,能夠快速處理大量的文件和提交。
- 簡單易用:Git 設計的目標之一是讓用戶更容易理解和使用,盡管它提供了豐富的功能,但命令和概念相對簡單,學習曲線較為平緩。
基于這些需求,Linus Torvalds 開始了 Git 的開發(fā),并于 2005 年 4 月 3 日發(fā)布了第一個版本。隨著時間的推移,Git 在開源社區(qū)中得到了廣泛的認可和應用,逐漸成為了最流行和最常用的版本控制系統(tǒng)之一。
3. 集中式 VS 分布式
集中式版本控制系統(tǒng)(Centralized Version Control System,CVCS)和分布式版本控制系統(tǒng)(Distributed Version Control System,DVCS)是兩種不同類型的版本控制系統(tǒng),它們在數(shù)據(jù)存儲、工作流程和協(xié)作模式等方面有所不同。
3-1. 集中式版本控制系統(tǒng)(CVCS)
CVCS 是一種傳統(tǒng)的版本控制系統(tǒng),所有的文件和版本歷史都存儲在中央服務器上。開發(fā)者需要通過從中央服務器檢出代碼(checkout)來獲取項目的副本,在本地進行修改后再提交到中央服務器。典型的 CVCS 包括 CVS(Concurrent Versions System)和 SVN(Subversion)等。
主要特點包括:
- 協(xié)作依賴于中央服務器:開發(fā)者必須與中央服務器保持連接,才能進行代碼的獲取和提交。
- 危險點:如果中央服務器發(fā)生故障或者網絡不穩(wěn)定,那么開發(fā)者將無法工作。
- 分支和合并相對復雜:通常需要由中央服務器來執(zhí)行分支和合并操作。
集中式版本控制系統(tǒng)最大的問題就是必須聯(lián)網才能工作,遇到帶寬不好的情況是,提交、更新較大文件可能會十分的緩慢。而且,集中式版本控制系統(tǒng)容災性差,萬一中心服務器硬盤出現(xiàn)的數(shù)據(jù)丟失,那后果是很嚴重的。
3-2. 分布式版本控制系統(tǒng)
DVCS 是一種新型的版本控制系統(tǒng),每個開發(fā)者都擁有完整的代碼倉庫(包括完整的歷史記錄)的副本。開發(fā)者可以在本地進行大部分的操作,而不需要與中央服務器保持連接。典型的 DVCS 包括 Git、Mercurial 等。
主要特點包括:
- 分布式架構:每個開發(fā)者都可以在本地進行工作,不受中央服務器的限制。
- 離線工作:開發(fā)者可以在沒有網絡連接的情況下繼續(xù)工作,而且操作效率更高。
- 分支和合并更靈活:由于每個開發(fā)者都擁有完整的歷史記錄,因此分支和合并操作更加輕松和快速。
分布式版本系統(tǒng)的優(yōu)點顯而易見,首先,它可以完全獨立的工作,不需要服務器的參與;其次,它具有很高的安全性,某一臺電腦的數(shù)據(jù)丟失后,可以通過其他電腦進行恢復。
現(xiàn)實情況下,分布式版本控制系統(tǒng)也需要一個“中心服務器”,但該服務器的作用僅限于為數(shù)據(jù)的交互提供便利性。
4. Git 的工作流程
Git 的命令大全和作用,可以從這個網站查閱:workspace :: Git Cheatsheet :: NDP Software
- 克隆倉庫:在開始工作之前,首先需要將遠程倉庫克隆到本地機器上。使用
git clone
命令可以將遠程倉庫完整地復制到本地。 - 創(chuàng)建分支:為了并行開發(fā)和隔離不同的功能或修復,通常會創(chuàng)建新的分支。使用
git branch
命令可以創(chuàng)建一個新的分支,例如:git branch feature-branch
。 - 切換分支:使用
git checkout
命令可以切換到創(chuàng)建的分支,例如:git checkout feature-branch
。 - 添加和提交更改:在所選分支上進行工作后,可以使用
git add
命令將更改的文件添加到暫存區(qū),然后使用git commit
命令將暫存區(qū)的更改提交到本地倉庫, - 推送更改:如果要將本地分支的更改推送到遠程倉庫,可以使用
git push
命令,例如:git push origin feature-branch
。這將把本地分支的更改推送到遠程倉庫中對應的分支。 - 合并分支:當分支的工作完成后,可以將其合并到主分支(通常是
master
分支)或其他目標分支中。使用git merge
命令可以執(zhí)行分支合并, - 解決沖突:如果在合并分支時發(fā)生沖突(即同一文件的不同部分具有不同的更改),需要手動解決沖突。在沖突解決后,再次執(zhí)行
git add
和git commit
命令以完成合并。 - 拉取更新:在團隊協(xié)作中,如果其他人推送了更改到遠程倉庫,可以使用
git pull
命令拉取更新到本地倉庫,以確保與最新代碼保持同步
二、Git 的下載與安裝
1. Git 的下載
Git 的下載鏈接:Git - Downloads (git-scm.com)
點擊進鏈接后,可以看到有四個版本,按操作系統(tǒng)位數(shù)可分為 32 位和 64 位,按使用版本可以分為 Standalone Installer(獨立安裝程序)和 Portable(便攜式),可以簡單的理解為前者需要安裝,后者不需要安裝可以直接使用(國內對這類不需要安裝的軟件也稱為綠色版)。
本文使用的是 64 位的獨立安裝版本。
2. Git 的安裝
以管理員身份運行 Git 安裝程序。
直接點Next
。
我這里選擇默認的安裝路徑,可以根據(jù)自己的喜好更改路徑,然后點擊Next
。
按默認的勾選安裝即可。
直接點Next
。
選擇文件的編輯器,一般都是用 VIM 作為默認的編輯器,直接點Next
。
決定初始化新項目(倉庫)的主干名字,第一種是讓 Git 自己選擇,即默認名字是 master ,但是未來也有可能會改為其他名字;第二種是用戶自行決定,默認是 main,當然,你也可以改為其他的名字。一般默認第一種,點擊Next
。
[!NOTE]
這個安裝流程在之前是沒有的,第二個選項下面有個
NEW!
,說很多團隊已經重命名他們的默認主干名為 main。起因是 2020 年非裔男子 George Floyd 因白人警察暴力執(zhí)法慘死而掀起的 Black Lives Matter(黑人的命也是命)運動,很多人認為 master 不尊重黑人,呼吁改為 main。
接著是調整 PATH 環(huán)境變量,默認使用第二個。第三個只適合懂的人折騰。
[!NOTE]
翻譯如下:
僅從 Git Bash 使用 Git
這是最謹慎的選擇,因為您的 PATH 根本不會被修改。您將只能使用 Git Bash 中的 Git 命令行工具。
從命令行以及第三方軟件進行 Git
(推薦)此選項僅將一些最小的 Git 包裝器添加到PATH中,以避免使用可選的 Unix 工具使環(huán)境混亂。您將能夠使用 Git Bash 中的 Git,命令提示符和 Windov PowerShell 以及在 PATH 中尋找 Git 的任何第三方軟件。
使用命令提示符中的 Git 和可選的 Unix 工具
Git 和可選的 Unix 工具都將添加到您的 PATH 中。
警告:這將覆蓋 Windows 工具,例如 “find” and “sort”. 僅在了解其含義后使用此選項。
選擇 SSH 執(zhí)行文件,按默認的即可。
[!NOTE]
以前的 Git 2.31 都沒有這個界面,估計是 2.4 開始可以使用外部的 SSH 文件。
選擇HTTPS后端傳輸,還是按默認的來,點擊Next
。
[!NOTE]
作為普通用戶,只是用 Git 來訪問 Github、GitLab 等網站,選擇前者就行了。如果在具有企業(yè)管理證書的組織中使用 Git,則將需要使用安全通道。如果你僅使用 Git 來訪問公共存儲庫(例如 GitHub ),或者你的組織不管理自己的證書,那么使用 SSL 后端(它們只是同一協(xié)議的不同實現(xiàn))就可以了。
兩個選項的具體區(qū)別,感興趣的可以去程序員社區(qū) stack overflow 查看,鏈接:git - What’s the difference between OpenSSL and the native windows Secure Channel library - Stack Overflow
配置行尾符號轉換, 這三種選擇分別是: ① 簽出 Windows 樣式,提交 Unix 樣式的行結尾;② 按原樣簽出,提交Unix樣式的行結尾;③ 按原樣簽出,按原樣提交。
那 Windows 樣式和 Unix 樣式到底有什么區(qū)別呢?
GitHub 中公開的代碼大部分都是以 Mac 或 Linux 中的 LF(Line Feed)換行。然而,由于 Windows 中是以 CRLF(Carriage Return+ Line Feed)換行的,所以在非對應的編輯器中將不能正常顯示。
Git 可以通過設置自動轉換這些換行符。使用 Windows 環(huán)境的各位,請選擇推薦的 “Checkout Windows-style,commit Unix-style line endings” 選項。換行符在簽出時會自動轉換為 CRLF,在提交時則會自動轉換為 LF 。
引用:《GitHub 入門與實踐》
上面說 Mac 、Linux、Unix 的 Line Feed ,翻譯過來就是換行符,用 “\n” 表示,換行符 “\n” 的 ASCII 值為 0x0A。而 Windows 的是 Carriage Return + Line Feed(回車 + 換行),用 “\r\n” 表示,回車符 “\r” 的 ASCII 值為 0x0D。
我們現(xiàn)在的教程就是介紹怎么安裝 Windows 版 Git,所以肯定選第一項啦。
至于 “回車”(carriage return)和 “換行”(line feed)這兩個概念的來歷和區(qū)別?
在計算機還沒有出現(xiàn)之前,有一種叫做電傳打字機(Teletype Model 33)的玩意,每秒鐘可以打 10 個字符。但是它有一個問題,就是打字機打完一行換行的時候,要用去 0.2 秒,正好可以打兩個字符。要是在這 0.2 秒里面,又有新的字符傳過來,那么這個字符將丟失。
于是,研制人員想了個辦法解決這個問題,就是在每行后面加兩個表示結束的字符。一個叫做"回車",告訴打字機把打印頭定位在左邊界;另一個叫做"換行",告訴打字機把紙向下移一行。
參考程序員社區(qū) stack overflow,鏈接:newline - What are carriage return, linefeed, and form feed? - Stack Overflow
接著來到配置終端模擬器與 Git Bash 一起使用,建議選擇第一個選項,因為 MinTTY 3功能比 cmd 多,cmd 只不過比 MinTTY 更適合處理 Windows 的一些接口問題,這個對 Git 用處不大,除此之外 Windows 的默認控制臺窗口有很多劣勢,比如 cmd 具有非常有限的默認歷史記錄回滾堆棧和糟糕的字體編碼等等。
相比之下,MinTTY 具有可調整大小的窗口和其他有用的可配置選項,可以通過右鍵單擊的工具欄來打開它們 git-bash 。
接著來到選擇默認的 “git pull” 行為的界面,先解釋一下 git pull 是什么意思,git pull 就是獲取最新的遠程倉庫分支到本地,并與本地分支合并。這里給出三個 git pull 的行為分別是:merge、rebase 和直接獲取。
一般默認選擇第一項,git rebase 絕大部分程序員都用不好或者不懂,而且風險很大,但是很多會用的人也很推崇,但是用不好就是災難。git pull 只是拉取遠程分支并與本地分支合并,而 git fetch 只是拉取遠程分支,怎么合并,選擇 merge 還是 rebase,可以再做選擇。
更詳細的解釋,我給各位總結了幾個比較好的說明,以下是鏈接:
git branch - Why does git perform fast-forward merges by default? - Stack Overflow
In git how is fetch different than pull and how is merge different than rebase? - Stack Overflow
Difference between git pull and git pull --rebase - Stack Overflow
接著是選擇一個憑證幫助程序, 第一個選項是提供登錄憑證幫助的,Git 有時需要用戶的憑據(jù)才能執(zhí)行操作;例如,可能需要輸入用戶名和密碼才能通過 HTTP 訪問遠程存儲庫(GitHub,GItLab 等等)。第二個則是不使用憑證助手。
建議默認,點擊Next
。
然后是配置額外的選項,分別是啟用文件系統(tǒng)緩存和啟用符號鏈接。啟用文件系統(tǒng)緩存就是將批量讀取文件系統(tǒng)數(shù)據(jù)并將其緩存在內存中以進行某些操作,可以顯著提升性能。這個選項默認開啟。啟用符號鏈接 ,符號鏈接是一類特殊的文件, 其包含有一條以絕對路徑或者相對路徑的形式指向其它文件或者目錄的引用,類似于 Windows 的快捷方式,不完全等同類 Unix(如 Linux) 下的符號鏈接。因為該功能的支持需要一些條件,所以默認不開啟。
建議默認,點擊Next
。
最后是配置實驗性選項,這些還是實驗性功能,可能會有一些小錯誤之類的,建議不用開啟。
直接點Install
安裝。
安裝完成,默認勾選的選項都去掉,點擊Finish
完成安裝。
3. Git 各個軟件的簡單介紹
安裝好后,可以在開始菜單中,找到 Git 的文件夾,里面包含了 Git Bash、Git CMD、Git FAQs、Git GUI、Git Release Note,下面我們就分別介紹一下這幾個軟件。
3-1. Git Bash
Git Bash 是基于CMD的,在CMD的基礎上增添一些新的命令與功能,平時主要用這個,功能很豐富。
3-2. Git CMD
Git CMD 不能說和 cmd 完全一樣,只能說一模一樣,功能少得可憐。
3-3. Git FAQs
Git FAQs 就是 Git Frequently Asked Questions(常問問題),點擊圖標直接就可以訪問地址:FAQ · git-for-windows/git Wiki (github.com)
3-4. Git GUI
Git GUI 就是 Git 的圖形化界面,可以通過它快速創(chuàng)建新倉庫(項目),克隆存在的倉庫(項目),打開存在的倉庫(倉庫)。這個我基本沒用過,建議還是用命令行學習Git。
3-5. Git Release Note
Git Release Note 就是版本說明,增加了什么功能,修復了什么 bug 之類的。一般使用瀏覽器打開。
三、Git 本地管理
1. 創(chuàng)建版本庫
版本庫(repository)又名倉庫,本質上就是一個目錄(文件夾),把需要控制管理的代碼、文檔放入到該目錄下。在該目錄下的所有文件的操作(添加、刪除、修改、回退、查詢等)都可以被管理起來。
為方便演示,我新建了一個文件來進行操作,而這個新建的文件夾就可以被稱為版本庫,但是此時還不是真正意義上的版本庫,它跟普通的文件夾沒有區(qū)別。
[!CAUTION]
為了避免遇到各種莫名其妙的問題,請確保目錄名(包括父目錄)不包含中文。
進入文件夾,右鍵彈出菜單,選擇“Open Git Bash here”。
輸入git init
并回車可初始化版本庫,執(zhí)行成功后,這個文件夾才是真正 Git 版本庫。同時,在文件夾中會多出一個隱藏文件夾,名為“.git”。
當版本庫創(chuàng)建好后,我們就可以用它來做項目的管理了。例如,在初始化版本庫后,通常都會添加一個說明文件來描述這個版本庫的作用,行業(yè)默認都是新建一個名為“README”的.txt
文件(普通文本文件)或者.md
文件(Markdown 文件)。
我這里直接就在 Git 的命令框中創(chuàng)建了,使用的是touch
命令創(chuàng)建,再用vim
命令進入編輯(如果你不會 VIM,可以用最簡單的右鍵新建文本文件的方法新建,不過我還是建議學習一下 VIM)。
在里面我輸入了“This is a version library for learning Git.”,然后保存退出。
可以使用cat
命令查看“README.md”。
根據(jù) Git 的工作流程,此時的 README.md 還在工作區(qū),可以通過git status
命令查看倉庫的狀態(tài)。下圖中,紅色字體的“README.md”就是新增或者被修改的文件,目前還在工作區(qū),還未提交到暫存區(qū),括號里也提示我們可以用git add
來添加到暫存區(qū)。
使用git add README.md
把 README.md 添加到 Git 的暫存區(qū)。
再次用git status
命令查看倉庫的狀態(tài),就可以看到 README.md 變成了綠色,已經保存到暫存區(qū)了。
根據(jù) Git 的工作流程,此時 README.md 也只是存在暫存區(qū),還并沒有提交到倉庫,需要使用git commit
命令將 README.md 提交到倉庫。
我在使用git commit
命令時,會加上參數(shù)-m
,用于表示本次提交的說明信息,說明信息最好統(tǒng)一格式,這樣對于后續(xù)的 Bug 管理、版本信息追蹤都會大有好處。
不過我們第一次使用時,會發(fā)現(xiàn)無法提交(如下圖)。
這個問題是由于 Git 無法檢測到用戶身份信息而引起的,Git 在每次提交時都需要知道提交者的姓名和電子郵件地址??梢园凑彰钚兄刑峁┑奶崾緛碓O置用戶身份信息。如下:
git config --global user.email "you@example.com"
git config --global user.name "Your Name"
把雙引號里面內容替換掉,我這里替換成我的 QQ 郵箱和英文名,如下圖所示:
再次提交就可以了。
這時使用git status
命令查看倉庫的狀態(tài),已經沒有修改或新增的文件在暫存區(qū)或者工作區(qū)了。
2. 提交修改
提交修改的步驟和前面提到的一樣,例如,我們給現(xiàn)有的 README.md 文件修改一些內容,如下圖:
這時使用git status
命令查看倉庫的狀態(tài):
上面的輸出表示 README.md 已經修改,但是還未添加到暫存區(qū)。我們可以通過git diff
查看當前的修改內容,輸出格式為 Linux 內核補丁所用的格式:
新增的內容會以綠色字體顯示,并且在每行開頭多一個+
,表示新增內容(如果是-
,則表示刪除內容,且字體為紅色)。
現(xiàn)在提交修改的內容,使用的命令還是git add
和git commit
。
可以通過git log
查看近期的提交記錄,提交記錄以時間倒敘輸出。
如果執(zhí)行git commit
之后,發(fā)現(xiàn)提交說明寫的有問題,可以通過git commit --amend
命令,修改最近一次的提交說明。輸入命令后,會用 VIM 編輯器打開提交信息(還是要會 VIM ,不會的先去查一下怎么用)。
修改一下提交記錄,如下圖(修改的內容沒什么特殊含義,只是為了示范):
保存退出后,再次用git log
查看提交記錄,可以看到提交信息已經更新了。
如果要添加代碼文件,也是類似的操作,例如新增一個.c 文件。
隨便寫一些內容。
只要有新文件加進來,都可以用git status
命令看到。
順便編譯一下程序,多一個可執(zhí)行文件。
用git status
命令查看倉庫。
提交修改的內容,使用的命令還是git add
和git commit
,但是同時提交兩個或兩個以上的文件,有兩種辦法。
-
方法一:
git add
命令后面把要添加的文件全部寫上,不同文件用空格隔開。 -
方法二:
如果要添加的文件是
git status
能看到的全部紅色字體的文件,直接用git add .
,在原來的命令上加一個.
即可。
然后用git commit
提交到倉庫即可。
這時用git log
查看提交記錄,就有三段記錄了。
3. 版本回退
在實際產品開發(fā)過程中,我們需要養(yǎng)成一個習慣,那就是代碼或文檔修改到一定程度時,要將修改的內容提交到版本庫。這樣,一旦后續(xù)代碼或文檔修改出了問題,或者誤刪了某些文件,還可以通過最近的一次 commit 進行恢復,這個恢復的過程就是版本回退。
在原來的 README.md 中,我重新做了修改,如下圖:
并且做了提交,如下圖:
可以通過git log
加上--pretty=oneline
參數(shù),查看簡化版的提交記錄信息:
可以看到有四條提交記錄,前面黃色的數(shù)字是 commit ID,是 Git 的提交的版本 ID(跟 SVN 遞增的 ID 不一樣),通常是 40 個字符的十六進制字符串,這是 SHA-1 哈希算法生成的。這個 ID 通常被稱為"SHA-1 哈希"或"SHA-1"。SHA-1 是一種加密哈希函數(shù),雖然在安全上已經存在一些漏洞,但在 Git 中仍然被廣泛使用。
回到正題,由于某種原因,需要將版本庫回退到“Added code and executable files.”這次的提交版本,可以使用git reset --hard
命令來回退。但是有個前提,就是要讓 Git 知道當前是什么版本,而且還要知道回退到哪個版本。
在 Git 中,用 HEAD 來表示當前版本,HEAD^ 表示上一個,HEAD^^ 表示上上一個版本,HEAD~100 表示往上 100 個版本。由上圖可知,當前的 HEAD 就指在最新提交的版本上,回退到“Added code and executable files.”這次的提交版本,就是當前版本的上一次,那么執(zhí)行下面命令即可:
git reset --hard HEAD^
執(zhí)行結果如下圖:
打開 README.md 查看一下,果然回退了。
那么假設過了一段時間,需要返回之前的版本,也非常簡單,只要能找到之前版本 commit ID,就可以通過git reset
命令回退就行。Git 提供了git reflog
命令用于記錄每次的命令,那么就可以通過git reflog
找到之前版本的 commit ID。
上圖紅框標記的就是最后一次的版本提交記錄,最開始的那串數(shù)字就是 commit ID,執(zhí)行下面的命令即可。
git reset --hard 6353f69
執(zhí)行結束,用git log
可以看到,版本已經復原了。
查看一下文件內容也是復原狀態(tài)。
Git 的版本回退速度之所以非??焖?,主要是 Git 在內部有個指向當前版本的 HEAD 指針,回退版本時,Git 僅僅只是把 HEAD 從指向需要回退的版本。
4. 理解工作區(qū)和暫存區(qū)
在使用 Git 管理版本時,經常會聽到工作區(qū)和暫存區(qū)這兩個概念,理解工作區(qū)和暫存區(qū)對于理解 Git 的很多操作十分有幫助。從前面提到的 Git 的工作流程,可以看出工作區(qū)和暫存區(qū)都包含在本地倉庫里面,下面分別介紹一下這兩個概念。
4-1. 工作區(qū)
當前開發(fā)程序所在目錄稱為工作區(qū),比如,我前面演示用的文件夾“git_test”就是一個工作區(qū),可以在這里新增或刪除文件,也可以修改文件里面的內容。
這里特別強調一下,隱藏文件夾“.git”不屬于工作區(qū),因為里面的內容不可以被用戶修改,用戶也不能在這個文件夾里新增或刪除。它跟接下來要講的暫存區(qū)有很大的關系。
4-2. 暫存區(qū)
先著重講一下隱藏文件夾“.git”,它是 Git 版本控制系統(tǒng)的核心所在,它包含了項目的版本控制信息,包括提交歷史、分支、標簽等。“.git”文件夾的作用如下:
- 版本控制信息存儲:“.git”文件夾保存了項目的整個版本控制歷史,包括每個提交的內容、作者、時間等信息。
- 分支和標簽管理:Git 使用“.git”文件夾來存儲和管理分支和標簽信息,以便于在不同的分支之間切換,或者查看特定標簽的快照。
- 配置信息:Git 的配置信息也存儲在“.git”文件夾中,包括用戶信息、遠程倉庫地址等。
- 暫存區(qū):“.git”文件夾包含一個暫存區(qū)(stage,也叫 index),用于暫存待提交的修改,以便在提交時將其納入版本控制。
- 工作樹狀態(tài)追蹤:Git 通過“.git”文件夾來追蹤工作樹(working tree)中文件的狀態(tài),以便確定哪些文件已經修改、添加或刪除。
綜上所述,我們可以知道暫存區(qū)就在“.git”里面,還有 Git 為我們自動創(chuàng)建的第一個分支 master,以及指向 master 的一個指針 HEAD。
分支和 HEAD 的概念我們以后再講,前面講了我們把文件往 Git 版本庫里添加的時候,分別用git add
和git commit
兩步執(zhí)行。其實本質上就是用git add
把文件修改添加到暫存區(qū),然后用git commit
提交更改,把暫存區(qū)的所有內容提交到當前分支。因為我們創(chuàng)建 Git 版本庫時,Git 自動為我們創(chuàng)建了唯一的 master 分支,所以git commit
就是往 master 分支上提交更改。
可以簡單理解為,需要提交的文件修改通通放到暫存區(qū),然后一次性提交暫存區(qū)的所有修改。
4-3. git diff 比較域
git diff
命令可以對比兩個版本的差異,一般會結合一些常用的參數(shù)運行,如下圖所示:
由上圖可知,git diff
是只比較比較工作區(qū)和暫存區(qū)(最后一次 add)的區(qū)別;git diff --cached
是只比較暫存區(qū)和版本庫的區(qū)別;git diff HEAD
是只比較工作區(qū)和版本庫(最后一次 commit)的區(qū)別。
5. 管理修改
Git 之所以比其他版本控制系統(tǒng)性能優(yōu)秀,主要就是它跟蹤并管理的是修改,即每次版本之間的差異,而不是簡單的文件。
例如,我現(xiàn)在重新修改一下 README.md 的內容,新增內容如下圖:
通過git status
命令可以查看被修改的文件,再通過git diff
可以對比工作區(qū)和暫存區(qū)的不同。
然后git add
之后,再次查看倉庫狀態(tài)。
先暫時不提交到 master 分支,再次修改 README.md,修改如下圖:
然后不進行git add
,直接用git commit
提交,此時可以發(fā)現(xiàn)提交是成功的,但是用git status
查看,還是存在工作區(qū)有被修改的文件。顯然,第二次的修改并沒有被提交。
那就證明了 Git 管理的是修改,當用git add
命令后,在工作區(qū)的第一次修改被放入暫存區(qū)并做好了被提交的準備,但是在工作區(qū)的第二次修改并沒有放入暫存區(qū),所以git commit
只負責把暫存區(qū)的修改提交了,也就是第一次的修改被提交了,第二次的修改不會被提交。
可以通過git diff HEAD
和git diff --cached
分別查看倉庫的情況,可以看出工作區(qū)的文件和倉庫的文件是有差別的,而暫存區(qū)和倉庫的并沒有區(qū)別。
6. 撤銷修改
實際的項目開發(fā)過程中難免會犯錯,比如 Bug 改錯了位置、代碼注釋寫錯了等等。出現(xiàn)了錯誤的修改之后,就要及時的撤銷修改,下面分別介紹不同場景下的撤銷操作。
6-1. 撤銷工作區(qū)的修改
假如因為某些原因,我們要放棄這一次工作區(qū)的修改,可以用git checkout
命令撤銷修改。先使用git status
命令查看一下當前版本庫的狀態(tài),當前有一個工作區(qū)的修改。
以前版本的 Git,第二行的括號里提示的是git checkout
,現(xiàn)在提示的是git restore
。這兩個都是 Git 中用于撤銷更改或者切換版本的命令,但是它們的使用方式和作用略有不同。
-
git checkout:
- 用法:
git checkout <branch>
切換分支;git checkout <commit> <file>
恢復單個文件到指定提交版本。 - 主要功能:
- 切換分支:將工作區(qū)的內容切換到指定分支的最新狀態(tài),包括所有文件和文件夾。
- 恢復文件:將單個文件的狀態(tài)恢復到指定提交版本的狀態(tài)。
- 用法:
-
git restore:
- 用法:
git restore <file>
恢復工作區(qū)中的文件到暫存區(qū)的狀態(tài);git restore --source=<commit> <file>
恢復單個文件到指定提交版本;git restore --staged <file>
將暫存區(qū)的文件恢復到工作區(qū)。 - 主要功能:
- 恢復工作區(qū):將工作區(qū)中的文件恢復到暫存區(qū)或指定提交版本的狀態(tài)。
- 將暫存區(qū)的文件恢復到工作區(qū)。
- 用法:
總的來說,git checkout
主要用于切換分支和恢復單個文件,而 git restore
則用于恢復工作區(qū)中的文件到指定狀態(tài),同時也可以用來操作暫存區(qū)的文件。兩者的功能有交叉,但是在實際使用時需要根據(jù)具體的情況選擇合適的命令。
這里我用git checkout -- README.md
來撤銷修改,再次用git status
查看,工作區(qū)已經clean了,并且 README.md 已經恢復到了版本庫的版本。
6-2. 撤銷暫存區(qū)的提交
對 README.md 再修改一些內容,并用git add
提交到暫存區(qū)。
使用git status
查看當前版本庫的狀態(tài),可以看到修改已經提交到了暫存區(qū)。
如果我們想撤銷這次的提交,可以看到在上圖中有個 git 命令已經給出了提示,可以用git restore
來撤銷,之前的 Git 的版本是提示使用git reset
來撤銷,我們還是用更廣為人知的git reset
來撤銷。
輸入git reset HEAD README.md
,表示我們要從 HEAD 只向的分支恢復 README.md 文件。
6-3. 撤銷本地版本庫的提交
如果已經把修改后的文件提交到 master 分支上了,想要撤銷是撤銷不了的,只能通過回退版本(第 3 小節(jié)的內容)的方式來進行。現(xiàn)在還只是本地版本庫,如果后續(xù)學到遠程版本庫,把修改提交到遠程版本庫,那可能就無力回天了,因為遠程版本庫不止一個人在用,可能會影響到其他人的工作。
因此,很多企業(yè)在合入遠程倉庫之前都會有一個環(huán)節(jié)叫代碼審查(review),所謂的 review 就是指開發(fā)團隊中的成員對其他成員編寫的代碼進行檢查和評審的過程。代碼審查是一種質量保證機制,通過讓其他團隊成員檢查代碼,可以發(fā)現(xiàn)潛在的問題、提供反饋和建議,以確保代碼質量和項目整體的穩(wěn)定性。
7. 刪除文件
在實際工作中,刪除文件也是常見的操作,在 Windows 系統(tǒng)常常使用手動刪除,習慣使用命令行的同學會使用rm
。例如,我們現(xiàn)在就把其中一個文件刪除,并查看當前版本庫的狀態(tài)。
Git 已經感知到了工作區(qū)的 Hello.exe 被刪除,但版本庫中的文件還未刪除,這時我們有兩種選擇:
-
使用
git add/rm <file>
命令更新修改到暫存區(qū)以備 commit。這個操作目的是為了刪除文件做準備,如果在執(zhí)行
git rm
之前,突然不想刪除了,那就是第二種選擇了。 -
使用
git checkout -- <file>
丟棄工作區(qū)的修改,即還原被刪除的文件。
8. 查看提交歷史
在提交了若干更新,又或是克隆了某個項目之后,通常都會回顧下提交歷史,看看項目都做了哪些修改。而查看歷史提交記錄最簡單而又有效的工具是git log
命令了。
我們去嵌入式大神稚暉君的 GitHub 上找一個項目并克隆下來,這是他的 Github 鏈接:peng-zhihui (稚暉) (github.com)。
我這里克隆了他的 HelloWord-Keyboard 項目,使用了git clone
命令。
我這里換了一個文件夾,并且在這個文件夾下重新打開了 Git 終端,克隆項目完成后,運行 Git 的目錄下會多出一個項目為名的文件夾。
用cd
命令進入文件夾。
在此項目中運行git log
命令時,可以看到很多歷史記錄。
歷史記錄甚至多到滾動不完,可以按q
鍵退出瀏覽歷史記錄。
不傳入任何參數(shù)的默認情況下,git log
會按時間先后順序列出所有的提交,最近的更新排在最上面。會包含每個提交的 commit ID、作者的名字、電子郵箱、提交時間和提交說明。
git log
有許多選項(或者叫參數(shù))可以有效搜索信息,例如需要顯示每次提交所引入的差異,就可以加入參數(shù)-p
或--patch
(patch 就是我們常說的補丁)。
如果要限制顯示的日志條目數(shù)量,可以輸入短桿后加上數(shù)量,例如git log -3
,就會顯示最近三次的提交信息。
如果想看到每次提交的簡略統(tǒng)計信息,可以使用–stat
選項。
–stat
選項在每次提交的下面列出所有被修改過的文件、有多少文件被修改了以及被修改過的文件的哪些行被移除或是添加了。 在每次提交的最后還有一個總結。
關于git log
還有很多選項,這里就不一一贅述了,感興趣的直接在這個鏈接學習:Git - git-log Documentation (git-scm.com)。
四、代碼托管平臺
1. 常見的代碼托管平臺
-
GitHub: GitHub 是最大的開源代碼托管平臺之一,提供了強大的版本控制功能和協(xié)作工具,支持 Git。
-
GitLab: GitLab 是一個開源的代碼托管平臺,提供了類似于 GitHub 的功能,但還包含了一些額外的功能,例如持續(xù)集成、CI/CD 等。
-
Gitee: Gitee(碼云)是開源中國(OSCHINA)的一個類似于 GitHub 的代碼托管平臺,支持 Git 和 SVN,提供 Git 倉庫托管、團隊協(xié)作、代碼審查、問題跟蹤、持續(xù)集成等功能。它是由中國的一家公司開發(fā)和運營,旨在為國內開發(fā)者提供一個方便、高效的代碼托管平臺。
-
Bitbucket: Bitbucket 是由 Atlassian 公司提供的代碼托管平臺,支持 Git 和 Mercurial,提供了私有倉庫、團隊協(xié)作、持續(xù)集成等功能。
-
SourceForge: SourceForge 是一個老牌的開源軟件托管平臺,提供了代碼托管、下載、論壇等功能,支持 Git、SVN 和 Mercurial。
-
Microsoft Azure DevOps: Azure DevOps(之前稱為 Visual Studio Team Services 或 VSTS)是微軟提供的一套全面的軟件開發(fā)工具,包括代碼托管、CI/CD、項目管理等功能。
-
AWS CodeCommit: AWS CodeCommit 是亞馬遜提供的托管 Git 存儲庫的服務,可以與其他 AWS 服務集成,例如 AWS CodePipeline 和 AWS CodeBuild。
-
Google Cloud Source Repositories: Google Cloud Source Repositories 是 Google Cloud Platform 提供的托管 Git 存儲庫的服務,可以與其他 Google Cloud 平臺的服務集成。
2. 注冊代碼托管平臺賬號
代碼托管平臺較多,這里只介紹其中兩個平臺的賬號申請,而且都是以官方的文檔為主要參考教程,分別是 GitHub 和 Gitee。推薦 GitHub 的原因是大部分開源項目都在 GitHub 上(包括 Linux kernel)。但畢竟 GitHub 的服務器在國外,國內訪問很不方便(無法訪問和超慢的響應時間是家常便飯),要正常訪問,還需要翻墻(這事違法哈)。所以這里補充一個類型 GitHub 的國內平臺,就是開源中國的 Gitee,同樣可以有很多開源項目,也可以在 Git 上配置賬號,與 GitHub 的體驗差別不大,主要對英語不好同學很友好,基本都是中文的。
2-1. GitHub
注冊 GitHub 賬號建議先翻墻,然后看官方文檔。
官方注冊文檔鏈接:《在 GitHub 上創(chuàng)建帳戶》
2-2. Gitee
官方注冊文檔鏈接:《注冊 Gitee 賬號》
3. 為 GitHub / Gitee 配置公鑰
3-1. GitHub 配置 SSH Key
在開始菜單中打開 Git Bash。
-
設置用戶信息:
git config --global user.name "your name" git config --global user.email "your e-mail"
把雙引號里面的內容替換成自己的,如下圖:
-
創(chuàng)建SSH密鑰:
ssh-keygen -t rsa -b 4096 -C "your e-mail"
同樣把雙引號的內容替換成自己的郵箱,不過創(chuàng)建密鑰時會遇到一個界面靜止不動,如下圖:
這是要我們設置一下密碼,這個 Key 我們只是個人使用,只要不設計軍事項目,不需要密碼,直接按三次回車跳過。
看到這個畫面就是 Key 創(chuàng)建成功了。
-
復制公鑰,在當前窗口輸入命令
cd .ssh
回車,再輸入ls
可以看到“.ssh”文件夾下生成了 Key 的密鑰對。其中,id_rsa 是私鑰,不能泄露出去, 是公鑰,可以放心地告訴任何人。輸入
cat id_rsa.pub
查看公鑰,并復制。 -
登錄 GitHub 網站,點擊網頁右上角的頭像,在彈出的菜單中選擇
Setting
。在左邊的選項卡中,選中
SSH and GPG keys
,然后點擊右邊綠色按鈕的New SSH key
。然后輸入 Title,再粘貼密鑰,最后點擊下面的按鈕
Add SSH key
。有時候可能要驗證一下是不是本人操作,輸入 GitHub 的密碼驗證就好了。
成功添加 Key 如下圖:
-
測試連接,輸入下面的命令行:
ssh -T git@github.com
如果看到類似于 “Hi username! You’ve successfully authenticated, but GitHub does not provide shell access.” 的消息,則說明 SSH 連接已成功設置。如下圖:
[!NOTE]
為什么 GitHub 需要 SSH Key 呢?
因為 GitHub 需要識別出你推送的提交確實是你推送的,而不是別人冒充的,而 Git 支持 SSH 協(xié)議,所以 GitHub 只要知道了你的公鑰,就可以確認只有你自己才能推送。
當然,GitHub 允許你添加多個 Key。假定你有若干電腦,你一會兒在公司提交,一會兒在家里提交,只要把每臺電腦的 Key 都添加到 GitHub,就可以在每臺電腦上往 GitHub 推送了。
3-2. Gitee 配置 SSH Key
Git 配置 Gitee 和配置 GitHub 過程一樣,但是不能使用同一個公鑰,所以這里需要生成新的 Key 的密鑰對。
為了區(qū)分之前的 Key,我們用基于ed25519
算法的 SSH 密鑰。
ssh-keygen -t ed25519 -C "your e-mail"
生成的密鑰對如下:
用同樣的方法復制密鑰,然后登錄 Gitee 網站和賬號,點擊右上角頭像,彈出菜單,選擇“設置”。
在左邊的選項卡中選擇 SSH 公鑰的選項卡,輸入標題和公鑰,點擊確定。
然后輸入密碼驗證一下。
公鑰成功添加。
測試方法和 GitHub 差不多,后面部分改成 gitee.com 就行。中間停頓的時候,輸入yes
回車即可,看到類似于 “Hi username! You’ve successfully authenticated, but GitHub does not provide shell access.” 的消息,則說明 SSH 連接已成功設置。
4. 添加遠程倉庫
到目前為止,我們已經學會了很多的關于 Git 的基本操作。但是這些功能與之前的 SVN 之類的集中式版本控制系統(tǒng)相比也沒有太大的差別,因為這些僅僅只是基本操作,而 Git 真正意義上的殺手锏是遠程倉庫。
Git 是分布式版本控制系統(tǒng),同一個 Git 倉庫,可以分布到不同的機器上。那么是怎么分布的呢?最早,只有一臺機器有一個原始版本庫,此后,別的機器可以“克隆”這個原始版本庫,而且每臺機器的版本庫其實都是一樣的,并沒有所謂的主次之分。
在實際工作場景往往是這樣的,找一臺電腦作為“服務器”,其他人都從這個服務器倉庫“克隆”一份到自己的電腦上,并且各自把各自的提交推送到服務器倉庫里,也從服務器倉庫中拉取別人的提交。服務器在這個過程中充當數(shù)據(jù)轉接的角色,僅僅作為數(shù)據(jù)共享的中介。
Git 服務器可以自己搭建,也可以使用代碼托管平臺,對于初學 Git 的小伙伴來說,搭建自己的服務器不太現(xiàn)實,所以直接注冊 GitHub 或者 Gitee 的賬號,使用外部的服務器來托管代碼是最實際最高效的選擇。前面三小節(jié)已經把賬號注冊完畢,并通過 SSH Key 加密連接了,現(xiàn)在我們就可以直接構建自己的遠程倉庫。
4-1. 構建 GitHub 的遠程倉庫
登錄 GitHub 賬號,先點擊右上角的小三角形,在下拉菜單中選擇New repository
,此時頁面會刷新,在Repository name
下面的輸入框中,輸入倉庫名,前面一直用git_test
這個倉庫名,這里要使用一樣的。最后點擊下面的綠色按鈕Create repository
創(chuàng)建倉庫。要提醒一點,就是倉庫名不能重復,如果你輸入了倉庫名是自己帳號里已存在的倉庫,是無法創(chuàng)建成功的。
創(chuàng)建成功會刷新成如下圖的界面。
回到本地,打開本地倉庫git_test
的文件夾,在這個文件夾下打開 Git Bash,粘貼下面的命令(上圖紅框復制的)。
git remote add origin https://github.com/zhengxinyu13/git_test.git
遠程庫的名字就是origin
,這是 Git 默認的叫法,也可以改成其它的,不過origin
這個名字一看就知道是遠程庫,所以建議不改。
然后執(zhí)行下面的命令:
git branch -M main
簡單解釋一下這個命令,這是用于將當前倉庫的默認分支名稱從舊名稱(如master
)更改為main
。這在許多情況下是為了避免使用具有歷史負擔的術語,比如master/slave
或master
分支的歷史含義。
具體來說,git branch -M main
命令執(zhí)行以下操作:
-
-M
選項表示move
或rename
。它會重命名分支,如果分支已存在,則會強制覆蓋。 -
main
是新的分支名稱。
這個命令將當前倉庫的默認分支重命名為 main
,如果之前存在名為 main
的分支,則會覆蓋它。
將本地庫同步到遠程庫可以執(zhí)行下面的命令:
git push -u origin main
由于遠程倉庫是空的,第一次推送main
分支時,加上了-u
參數(shù),Git 不但會把本地的main
分支內容推送的遠程新的main
分支,還會把本地的main
分支和遠程的main
分支關聯(lián)起來,在以后的推送或者拉取時就可以簡化命令。執(zhí)行命令后,會提示登錄 GitHub 的賬號,點擊Sign in with your browser
。
然后會自動跳轉到瀏覽器,點擊Authorize git-ecosystem
。
然后輸入密碼,點擊Confirm
。
如果看到這個界面,就表示配置成功。
Git 這邊也會提示,表示已經成功把本地倉庫推送到遠程倉庫了。
推送成功后,可以立刻在 GitHub 頁面中看到遠程庫的內容已經和本地一模一樣的文件了。
一旦有了遠程倉庫,本地倉庫做出修改,需要同步到遠程倉庫的話,就可以通過命令:
$ git push origin main
這樣就可以把本地的main
分支的最新修改推送到 GitHub 的遠程倉庫。
4-2. 構建 Gitee 的遠程倉庫
Gitee 創(chuàng)建遠程倉庫會 GitHub 基本上一模一樣,而且界面是中文的,對英語不好的小伙伴很友好,操作過程我就不贅述了,登錄 Gitee 后看圖操作。
創(chuàng)建好后,在本地倉庫的 Git Bash 上執(zhí)行下圖紅框的命令。
如果前面已經把本地倉庫和 GitHub 的遠程倉庫連接的話,再執(zhí)行git remote add origin
是會失敗的,如下圖:
通常情況下,Git 不允許你添加同名的遠程倉庫,因為每個遠程倉庫都應該有一個唯一的名稱。
如果你確定要將遠程倉庫更改為新的地址,你可以使用以下命令:
git remote set-url origin https://gitee.com/Grayson_Zheng/git_test.git
這將更新現(xiàn)有遠程倉庫 origin
的 URL 為指定的新地址。
不過這么做會使本地倉庫與 GitHub 的遠程倉庫失去連接,后面推送只能推到 Gitee 上,這就需要后面的克隆倉庫來解決了。
執(zhí)行git push -u origin "master"
時會出錯,這是因為本地倉庫現(xiàn)在的分支名為main
,而不是master
,所以改成main
之后就可以了。
同樣需要登錄 Gitee 的賬號,這一步比 GitHub 簡單多了。
執(zhí)行成功可以看到下圖紅框的內容。
Gitee 的遠程倉庫也同步完成。
5. 克隆遠程倉庫
由于有遠程倉庫,本地倉庫即使不小心刪除了,也可以通過克隆倉庫找回。
克隆倉庫需要用之前提到的命令git clone
,后面跟上遠程倉庫的地址就可以了。其實,不管是 GitHub 還是 Gitee ,它們給出的地址不止一個,實際上 Git 支持多種協(xié)議,比如 SSH、HTTPS 等。
以克隆git_test
這個項目為例,GitHub 的操作是先點擊綠色按鈕Code
,然后復制鏈接。
再git clone
后面粘貼鏈接就可以克隆了,如下所示:
git clone https://github.com/zhengxinyu13/git_test.git
而 Gitee 也是差不多的操作,在項目頁面點擊橘色按鈕克隆/下載
。
彈窗中,可以直接復制鏈接,比 GitHub 跟人性化一些的是,git clone
已經包含在里面了,不需要額外再輸入。
[!CAUTION]
需要注意的是,由于這個倉庫雖然分別存放在 GitHub 和 Gitee 上,但是倉庫的名字是一樣,如果兩個一起克隆就要注意,不能放在同一個文件夾下面,要分開存放,畢竟克隆下來就是一個本地倉庫,本地倉庫本身就是個文件夾,同一級目錄下是不允許有兩個同名文件或文件夾的。
五、分支管理
1. 為什么需要分支
分支是版本管理系統(tǒng)中的重要概念,一個版本庫中的不同分支互不干擾、完全獨立,直到分支合并那一天。那么實際工作中,分支的作用到底是什么呢?
[!NOTE]
假設你準備開發(fā)一個新功能,但是需要兩周的時間才能完成,第一周你寫了 50% 的代碼,如果立刻提交,由于代碼還沒寫完,不完整的代碼庫會導致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。但是有了分支,就不需要擔心這種事情了。你可以創(chuàng)建一個屬于你自己的分支,這樣團隊其他人是看不到的,而且還繼續(xù)在原來的分支上正常工作。你在自己的分支上干活,想什么時候提交都可以,直到開發(fā)完畢后,再一次性合并到原來的分支上,這樣即安全,又不影響別人工作。
Git 分支主要是為了實現(xiàn)并行開發(fā)和代碼管理的靈活性和效率。以下是一些使用分支的主要原因:
-
并行開發(fā): 分支允許團隊成員在不影響主代碼庫的情況下獨立地開發(fā)新功能或修復錯誤。每個分支都是代碼庫的一個拷貝,團隊成員可以在自己的分支上進行修改,然后在開發(fā)完成后將其合并回主分支。
-
功能開發(fā): 每個功能可以在自己的分支上進行開發(fā),這樣可以保持主分支的穩(wěn)定性。一旦功能開發(fā)完成并通過測試,就可以將其合并到主分支中。
-
錯誤修復: 當發(fā)現(xiàn)主分支中的錯誤時,可以創(chuàng)建一個新分支來修復該錯誤,而不會中斷其他正在進行的工作。修復后,可以將修復的代碼合并回主分支中。
-
版本管理: 分支可以用來管理不同的版本。例如,可以創(chuàng)建一個用于發(fā)布的穩(wěn)定分支,以及一個用于持續(xù)開發(fā)的開發(fā)分支。這樣可以確保發(fā)布版本的穩(wěn)定性,同時繼續(xù)進行新功能的開發(fā)。
-
代碼審查: 分支可以用于進行代碼審查。開發(fā)人員可以在自己的分支上進行工作,并在完成后請求代碼審查。這樣可以確保代碼的質量和一致性。
綜上所述,分支是 Git 的重要特性,可以提高團隊協(xié)作的效率,同時保持代碼庫的整潔和穩(wěn)定。但 Git 的分支是與眾不同的,無論創(chuàng)建、切換還是刪除,Git 都能快速完成,無論你的版本庫是 1 個文件還是 1 萬個文件。
關于怎么學會使用 Git 的分支,這里推薦一個很不錯的學習網站:Learn Git Branching。
這個網站也是 GitHub 上的一個開源項目pcottle/learnGitBranching,有興趣的可以克隆下來看看。
2. 理解分支
在前面提到的回退版本中可以知道,每次提交到版本庫, Git 都會把這些提交版本都串成一條時間線,這是比較抽象的概念,所以可以參考下圖:
在本地倉庫中,每一次的修改都會被 Git 記錄在這條時間線上,這條時間線也是一個分支,而且是主分支,以前版本的 Git 叫master
分支,Gitee 仍然保持這個叫法,現(xiàn)在版本的 Git 已經開始改名叫main
分支了,而且 GitHub 也同步了這個叫法。
前面我們還提到有個 HEAD 指針指向最后一個修改,其實這不是一個嚴謹?shù)恼f法。嚴格來講, HEAD 指向的是當前分支(更專業(yè)的說法是對當前所在分支的符號引用),而master
(或main
)才是指向提交的節(jié)點。一開始時,HEAD 只指向master
(或main
),而master
(或main
)指向一個初始節(jié)點,這個節(jié)點是在倉庫初始化之后就有了。之后每一次修改提交都會新增一個節(jié)點,同時也會使master
(或main
)指向新的節(jié)點。因此,隨著版本不斷地迭代修改,master
(或main
)這條分支也會越來越長。
[!NOTE]
從個人角度來講,這塊內容比較抽象,理解起來會比較困難,因為當時我學習 Git 的時候也是這樣的狀態(tài)。后面我把分支類比成數(shù)據(jù)結構里的鏈表,把分支類比成鏈表的頭指針,把修改類比成鏈表的結點。每次有新的提交,就當作有新的結點插入了鏈表,并且讓頭指針(分支)指向新結點(最新的修改)。
3. 分支的創(chuàng)建與合并
前面我們提到了一個場景,就是新功能的開發(fā)可能需要很多時間,而在這段開發(fā)的時間里,如果功能還沒做完就提交,可能會影響別人開發(fā),如果等到功能開發(fā)好后在提交,那么中間要是出現(xiàn)電腦宕機等不可抗力的原因導致代碼丟失,那也得不償失。那么,既不影響別人開發(fā),也不影響自己進度的辦法就是創(chuàng)建一個自己的分支。
通常我們都會用dev
來命名這個分支,在 Git 中,dev
指的是“development”(開發(fā))的縮寫,它是一個常見的命名約定,用于表示開發(fā)階段的分支,用于進行新功能的開發(fā)。
假設現(xiàn)在有個現(xiàn)在新建了版本庫,里面寫了初始版本的代碼,當下如果用 Git 進行版本管理的話,可以用下圖表示現(xiàn)在情況。
然后,對初始版本進行修改后,得到了C1
版本,提交后如下圖:
這時,我需要添加一個新的功能到這個版本里面,但是又害怕破環(huán)了原來的代碼,于是我就創(chuàng)建了一個新的分支進行開發(fā)。創(chuàng)建新分支并命名為dev
的命令如下:
git branch dev
此時有個需要注意地方,那就是 HEAD 指針。此時的 HEAD 還是指向主分支,如果我這時候修改代碼并提交了,這個提交記錄還是在主分支上,那我創(chuàng)建的新分支就沒有任何意義了。因此,在創(chuàng)建新分支之后,要及時把 HEAD 指向新的分支,之后的提交記錄才會記在新分支上。求換分支的命令如下:
git checkout dev
當然如果想在創(chuàng)建新分支后自動切換到新分支,可以用下面這個命令:
git checkout -b dev
這樣就不需要用到git branch
命令了,可以省一條命令。
這時我寫好了一部分的新功能,雖然沒有完成全部功能,但是為了保險起見,我提交了這次的修改,于是有了C2
版本的代碼,并且提交在了dev
分支上。
接著我有連續(xù)開發(fā)C3
版本和C4
版本,壞消息是,雖然我完成了新功能的開發(fā),但是經過測試都沒能達到預期,同時也影響到了原本好的功能。好消息是,主分支的代碼還能正常運行。
終于,功夫不負有心人,當開發(fā)到C5
版本時,終于實現(xiàn)了功能,測試也沒有發(fā)現(xiàn) Bug,于是我提交了C5
版本。
然后再就把這次提交合入到主分支中去,這個過程需要將 HEAD 切回主分支,再進行合并。切換回主分支的命令是git checkout
,后面接上主分支名,如下:
git checkout main
切換主分支后,再用git merge
命令合并dev
分支,具體如下:
git merge dev
對于dev
分支來說,它看到了幾個版本的迭代,但是對于主分支來說,只是C1
到C5
的迭代。合并之后,就可以放心的將dev
分支刪除了。不過不需要擔心曾經在dev
分支提交的各種記錄會被刪除,即使分支被刪除,這個分支上的提交記錄會被保留一段時間(直到 Git 觸發(fā)了垃圾回收并刪除了這些無用的提交)。刪除分支的命令如下:
git branch -d dev
因為創(chuàng)建、合并和刪除分支非???,所以 Git 鼓勵使用分支完成各種任務,合并后再刪掉分支,這和直接在主分支上工作效果是一樣的,但過程更安全。
4. 沖突解決
只要是團隊開發(fā)項目,代碼上的沖突是在所難免的,畢竟團隊成員基本都在各自的分支里開發(fā),那么合并分支就不可能一帆風順,這時就要解決各種沖突了。
在 Git 中,所謂的沖突指的是當合并操作(merge)或重置操作(reset)嘗試合并兩個不同的修改時發(fā)生的情況。這種情況會導致 Git 無法自動解決修改之間的矛盾,需要人工介入解決。
常見的情況是,當你試圖合并兩個不同的分支,但這兩個分支上的相同文件被修改了,且這些修改彼此之間存在沖突。例如,如果兩個分支都修改了同一個文件的同一行代碼,Git 就無法自動確定應該保留哪個版本的修改,因此會產生沖突。
當Git發(fā)現(xiàn)沖突時,會在受影響的文件中插入特殊標記來標識沖突的部分,例如:
<<<<<<< HEAD
這是當前分支(HEAD)的修改
=======
這是另一個分支的修改
>>>>>>> other_branch
沖突標記之間的內容就是沖突的部分。在解決沖突時,你需要手動編輯這些文件,選擇要保留哪些修改,然后將沖突標記刪除,以及合并雙方的修改。一旦解決了所有沖突,你就可以繼續(xù)完成合并操作。
下面舉一個簡單的例子,演示一下如何解決開發(fā)過程中遇到的版本庫沖突的問題。
首先在現(xiàn)有的 Git 版本庫創(chuàng)建一個新的分支feature
。
前面沒有提到,這里補充一下,查看本地倉庫有多少分支可以用git branch
命令,Git 會列出所有的本地分支,其中字體為綠色且前面帶有星號的分支,就是當前被 HEAD 指向的分支。
此時我修改了 README.md 文件,并保存提交。
此時我切換回主分支,同樣修改了 README.md 文件,并保存提交。修改的內容和上圖一樣,只是換了一個符號。
好了,現(xiàn)在兩個分支都有對同一個文件的提交,如果這時候合并分支就會有沖突,Git 也會有提示合并存在沖突,需要手動解決,然后重新提交。
可以用git status
命令來查看存在沖突的文件。
這時我們再打開 README.md 文件,可以看到 Git 標記出不同分支的內容。
修改成下圖所示的內容后保存,這個要修改成哪個分支的內容,全看實際的情況,我這里是隨便選的。
解決沖突后,使用 git add
命令將解決沖突的文件標記為已解決,再用 git merge --continue
來繼續(xù)合并進程。
用帶參數(shù)的git log
也可以看到分支的合并情況(別慌,這些命令我也沒記住,以前靠百度,現(xiàn)在靠 ChatGPT)。
git log --graph --pretty=oneline --abbrev-commit
5. BUG 分支
軟件開發(fā)中,bug 就像家常便飯一樣。有了 bug 就需要修復,在 Git 中,每個bug都可以通過一個新的臨時分支來修復,修復后合并分支,然后將臨時分支刪除。
假設我現(xiàn)在接到一個修復代號為 101 的 bug 的任務時,而且這個 bug 相對比較緊急,所以我需要放下當前的工作優(yōu)先去處理這個 bug,那么我就會創(chuàng)建一個名為 issue-101 的分支來修復它。不過,正在dev
分支上進行的工作還沒有提交,只是添加到了暫存區(qū)而已。
此時我還不能提交,畢竟當前的進度還未完成,沒辦法提交。同時代號 101 的 bug 又需要在今天解決,那要怎么辦呢?
在前面的 Git 工作流程中,有一個貯藏區(qū)(stash)一直沒提到,現(xiàn)在就是它發(fā)揮作用的時候了。貯藏區(qū)可以把當前的工作現(xiàn)場“貯藏”起來,等以后需要恢復工作現(xiàn)場時,再把工作現(xiàn)場還原到“貯藏”前,進而可以繼續(xù)進行未完成的工作。
現(xiàn)在用git status
查看版本庫的狀態(tài),還存在未提交的內容。
用git stash
命令貯藏當前的工作狀態(tài),用git status
查看版本庫的狀態(tài),可以看到工作區(qū)已經 clean 了,因此可以放心地創(chuàng)建分支來修復 bug 了。
這時就要注意了,先要確定以哪個分支的版本修復 bug,畢竟現(xiàn)在的 HEAD 指針還指向dev
分支,而且dev
分支上可能有很多提交是不完整的,這時就需要切換回主分支,以主分支的最后一個提交的版本為基準,去創(chuàng)建新的 bug 分支。
分支創(chuàng)建好后,就可以開始修復 bug 了。修復好后,提交修改,切回主分支,合并 bug 分支,最后刪除 bug 分支。
這時候再回到dev
分支干活,但是工作區(qū)是干干凈凈的,需要去貯藏區(qū)恢復后才能繼續(xù)。
用git stash list
命令可以查看當前貯藏區(qū)的所有貯藏記錄,目前看來只有一條記錄。
想要恢復成貯藏之前的狀態(tài),有兩種情況:
-
恢復貯藏前的工作狀態(tài),不刪除貯藏區(qū)的貯藏記錄,命令如下:
git stash apply
后續(xù)想要刪除要用
git stash drop
,而且還要指定刪除哪條記錄,不指定就是刪除最新的,指定的話,命令如下,stash@{<index>}
里面的<index>
是記錄編號,如上圖的stash@{0}
。git stash drop stash@{<index>}
-
恢復貯藏前的工作狀態(tài),同時刪除貯藏區(qū)的貯藏記錄,命令如下:
git stash pop
我這里直接用git stash pop
,不需要用git status
,恢復的時候會直接顯示版本庫的狀態(tài)。
6. 分支管理策略
在合并分支時,可以注意到有個“Fast-forward”的字樣,這是 Git 中的一種合并模式。在 Fast-forward 模式(快進合并)下,Git 可以通過簡單地將目標分支指向合并的分支的最新提交來完成合并,而無需創(chuàng)建新的合并提交。
在這種模式下,Git 只需將目標分支指向合并分支的最新提交,而不會創(chuàng)建新的提交來記錄合并的過程??爝M合并的好處是可以保持提交歷史的線性和簡潔,因為不會創(chuàng)建額外的合并提交。這在處理簡單的合并情況時非常方便和高效。但這種模式有個缺點,那就是刪除分支后,會丟掉分支信息。
所以有時候快進合并可能不太適用,比如當我想要保留合并操作的記錄或者在合并過程中需要解決沖突時。在這種情況下,可以使用--no-ff
選項來禁用快進合并,強制 Git 創(chuàng)建一個新的合并提交。這樣可以更清晰地記錄分支的合并歷史以及解決合并沖突所做的修改。
例如,我現(xiàn)在在dev
分支提交了一筆代碼,準備合并dev
分支。如果想要保留提交信息,就要強制禁用 Fast forward 模式,Git 就會在 merge 時生成一個新的 commit,那么從分支歷史上就可以看出分支信息了。
在dev
分支提交后,切回主分支,然后合并dev
分支時,帶上--no-ff
和合并信息,命令如下(雙引號是合并信息):
git merge --no-ff -m "merge with no-ff" dev
合并后看看分支歷史,可以明顯看到,前面演示的分支合并,和這次的禁用快進合并的分支合并有著明顯的信息差別,禁用快進合并的分支合并操作,會記錄下這次的提交是從dev
分支合并過來的。
在實際開發(fā)中,分支管理是一個至關重要的實踐,它可以幫助團隊更好地組織和協(xié)作。以下是一些基本原則和最佳實踐,可以進行有效的分支管理:
- 主分支保持穩(wěn)定性: 主分支(通常是 master 或 main)應該保持穩(wěn)定,反映了生產環(huán)境中的代碼狀態(tài)。在主分支上應該只合并已經經過測試和驗證的代碼。
- 使用特性分支: 對于新功能或修復問題,應該創(chuàng)建專門的特性分支。每個特性分支都應該專注于解決一個特定的問題或實現(xiàn)一個特定的功能。這樣可以使得代碼更容易管理和測試。
- 及時合并主分支變更: 團隊成員應該經常將主分支上的最新變更合并到自己的特性分支中,以避免特性分支與主分支之間的差異過大,導致合并沖突難以解決。
- 小步快走: 盡可能頻繁地提交和合并代碼變更,以減小每次合并的規(guī)模。這有助于降低合并沖突的發(fā)生率,并使得問題的定位和解決更加容易。
- Code Review: 所有代碼變更都應該經過代碼審查。通過 Code Review 可以發(fā)現(xiàn)潛在的問題并提高代碼質量。通常,在代碼審查通過后才允許將代碼合并到主分支。
- 避免直接推送到主分支: 避免直接推送代碼到主分支,除非是緊急修復或小的修改。這樣可以確保所有的代碼變更都經過了適當?shù)膶彶楹蜏y試。
- 定期清理不需要的分支: 定期清理已經完成的特性分支或不再需要的分支,以保持倉庫的清潔和可管理性。
- 合并策略選擇: 根據(jù)團隊的需求和項目的特點選擇合適的合并策略,比如快進合并、非快進合并、rebase 等。
- 文檔化: 在團隊中建立清晰的分支管理規(guī)范和流程,并確保所有成員了解和遵守這些規(guī)范。文檔化可以幫助新成員快速上手,并減少誤解和混亂。
- 持續(xù)改進: 不斷地評估和改進分支管理流程,以適應項目的發(fā)展和團隊的需求。及時調整流程可以幫助團隊更加高效地進行開發(fā)工作。
有了這些原則,實際的團隊合作的分支其實就像下圖這樣(很多大型項目,上萬條分支都是正常的)。
7. 特性分支
做軟件開發(fā)總有無窮無盡的新功能要添加,從上圖也可以知道,新功能一般都會在dev
分支上的基礎上,構建一個feature
分支來開發(fā)。這也是多數(shù)團隊默認的習慣,還是那個原則,不能讓實驗性代碼破壞主分支。
假設我現(xiàn)在接到了 Leader 安排的新任務,要我開發(fā)一個新功能,任務的代號為 feat-013。
于是我在dev
分支的基礎上,創(chuàng)建了feat-013
分支。
過程很順利,我提交了新功能,并切回了dev
分支,準備把性能合并進來。
但就在這時,Leader 跟我說,預算不足,我負責的功能被砍掉了。然白干了,但是這個包含機密資料的分支還是必須就地銷毀。但是用git branch -d
會發(fā)現(xiàn)刪不掉這個分支,因為這個分支還沒有合并。不過 Git 也會提示,可以用git branch -D
來刪除分支。
8. 多人協(xié)作
從遠程倉庫克隆時,Git 會自動把本地的主分支和遠程的主分支對應起來了,并且遠程倉庫的默認名稱是origin
。要查看遠程庫的信息,用git remote
命令或者git remote -v
命令。
上圖顯示了可以抓取和推送的origin
地址。如果沒有推送權限,就看不到push
的地址。
8-1. 推送分支
所謂推送分支,就是把該分支上的所有本地提交推送到遠程庫,推送時要指定本地分支。在 Git 中,要推送分支到遠程倉庫,可以使用 git push
命令。如下圖:
在推送前,要確認推送的分支是哪一個,比如要推送主分支,那就先切換到主分支上,在執(zhí)行git push
命令,后面的origin mian
表示遠程倉庫的main
分支,也就是我把本地主分支的提交,合并到遠程倉庫的主分支上。
同理,推送其他分支也是類似的操作,比如dev
分支,先切分支,再推送。
使用git branch -a
可以查看本地和遠程倉庫的所有分支信息。
不過要注意一點,不是本地所有的分支和提交都要往遠程倉庫推送。首先主分支,基本都是時刻與遠程同步。其次是dev
分支,團隊所有成員都想要在上面工作,所以也要與遠程同步。最后,類似修復 bug 用的臨時分支和用于開發(fā)新功能feature
分支,就看情況同步了。一般來說,本地用于修復 bug 的分支是不需要推送的(除非 Leader 要看你的進度),而feature
分支就取決于是單獨開發(fā)新功能,還是團隊協(xié)作開發(fā)了。
8-2. 抓取分支
多人協(xié)作時,團隊成員都會往遠程倉庫推送各自的修改,以及向遠程倉庫抓取分支。不過要注意一點,抓取分支和克隆是 Git 中的兩個不同的操作??寺∈侵笍倪h程倉庫復制整個倉庫的操作。當使用git clone
命令時,Git 會復制遠程倉庫的所有文件、提交歷史、分支等信息到本地,并創(chuàng)建一個與遠程倉庫相同的本地倉庫副本。
假設,我現(xiàn)在所處的團隊中,我和另一個小伙伴被安排一起開發(fā)一個功能,我們一起克隆了同一個遠程倉庫,默認情況下,都是克隆遠程倉庫的主分支到本地。
但有時候開發(fā)需要克隆的是遠程倉庫的dev
分支(如上圖,倉庫遠程倉庫有兩個分支),那么指定遠程dev
分支可以用下面的命令:
git clone -b dev https://github.com/zhengxinyu13/git_test.git
如果一開始克隆時,沒有加上-b
選項和指定分支,克隆的倉庫則是默認克隆主分支,這時也不用著急把本地倉庫刪掉,可以創(chuàng)建遠程 origin 的dev
分支到本地,如下命令:
git checkout -b dev origin/dev
現(xiàn)在我和小伙伴都用相同分支克隆下來的版本做開發(fā),期間他把對某個文件的修改推送到origin/dev
分支,而碰巧我也對同個文件做出了修改,如果我也推送到origin/dev
分支,就會推送失敗。因為小伙伴最新的提交和我試圖推送的提交有沖突,解決辦法也很簡單,Git 也會提示用git pull
命令把最新的提交從origin/dev
分支抓下來,然后在本地合并,解決沖突后再推送。具體命令如下:
git pull origin dev
這就是多人協(xié)作的工作模式,一旦熟悉了,就非常簡單。
9. 刪除遠程分支
要刪除遠程倉庫中的分支,可以使用git push
命令來向遠程倉庫推送一個空的分支,實際上相當于刪除遠程分支。以下是具體步驟:
git push origin --delete branch_name
其中,origin
是遠程倉庫的名稱,branch_name
是要刪除的分支的名稱。
例如,如果你要刪除遠程倉庫origin
中的dev
分支,可以使用以下命令:
git push origin --delete dev
執(zhí)行這個命令后,dev
分支將會被從遠程倉庫origin
中刪除。
六、標簽管理
1. 什么是標簽
Git 標簽(Tag)是用來標記某個特定提交的,通常用于標識版本發(fā)布、重要里程碑等。Git 的標簽是版本庫的快照,但其實它就是指向某個 commit ID 的指針,跟分支會像,但是分支可以移動,標簽不能移動。
[!TIP]
那么為什么 Git 已經有 commit ID,卻還要引入 tag 呢?
同樣來假設一個場景,某個軟件版本發(fā)布日,Leader 跟我說:“請把上周一的那個版本打包發(fā)布,commit ID 是 6a5819e…”,我心想:“一串亂七八糟的數(shù)字不好找!”
但是同樣的場景,Leader 跟我說:“請把上周一的那個版本打包發(fā)布,版本號是 v1.2。”,我就會這么想:“按照 tag v1.2 查找 commit ID 就行了?!?/p>
可以這么理解,標簽就是一個讓人容易記住且有意義的名字。
2. 創(chuàng)建標簽
在 Git 中打標簽非常簡單,先切換到需要打標簽的分支上,然后用git tag
加上標簽名稱既可以了。
git tag
可以查看所有的標簽,加上標簽名則是給最新的提交打上標簽。同時用git log
查看,也可以看到標簽跟提交綁定在一起。
由于默認是最新的提交打標簽,如果給之前的提交打標簽,就需要找到對應的 commit ID 了。例如,我要給上圖所示的“fix issues-101”打個標簽,那我就先復制一下對應的 commit ID,再用git tag
打上標簽。上圖的 commit ID 太長了,可以用下面的命令獲得簡短 SHA-1 標識符(abbreviated commit):
git log --pretty=oneline --abbrev-commit
再用git tag
可以查看所有的標簽,可以看多了個v0.9
的標簽。注意,標簽不是按時間順序列出,而是按字母排序的。
標簽還可以顯示提交信息,用git show
命令加上標簽名就可以了。
而且創(chuàng)建標簽時,還可以順帶寫上一些描述說明,用-a
指定標簽名,-m
指定描述說明。
3. 管理標簽
只要是人做的事都有可能犯錯,因此標簽也有可能會打錯,但是沒關系,Git 是可以刪除標簽的,同樣是git tag
命令加上-d
選項就可以了。
目前所有的標簽都只是在本地倉庫,不會自動推送到遠程倉庫。如果要推送某個標簽到遠程倉庫,可以用git push origin <tagname>
命令。
如果要一次性推送所有的標簽,可以只用git push origin --tags
。
當把所有的標簽都推送到遠程倉庫,發(fā)現(xiàn)有一個標簽本來要刪除,一時疏忽給忘了,那就需要先在本地把標簽刪了,然后用下面的命令刪除遠程倉庫的標簽,其中<tag_name>
是標簽名。
git push origin :refs/tags/<tag_name>
這個命令的語法是通過將一個空的本地分支推送到遠程倉庫的標簽位置來刪除標簽。如果要直接刪除遠程倉庫中的標簽,可以使用以下命令:
git push origin --delete <tag_name>
七、Git 自定義
1. 文件忽略
日常開發(fā)中,工作區(qū)可能有些文件是不需要提交的,例如一些測試功能時產生的 log,或者是數(shù)據(jù)庫密碼的配置文件等等。這些文件需要放在工作區(qū),但是又不能提交,每次輸入git status
時,又會顯示 Untracked files,著實讓強迫癥患者抓狂。
好在 Torvalds 也是個強迫癥晚期,在開發(fā) Git 的時候也想到了這一點,可以通過.gitignore
文件來指定需要忽略的文件和文件夾。.gitignore
文件通常位于項目的根目錄中,用于告訴 Git 哪些文件和文件夾不應該被納入版本控制。
以下是一些常見的 .gitignore
文件的用法:
-
忽略特定文件或文件夾:
如果想忽略特定的文件或文件夾,只需在.gitignore
文件中添加它們的名稱即可。例如:file_to_ignore.txt folder_to_ignore/
-
使用通配符:
可以使用通配符來匹配一類文件。例如,使用*
可以匹配任意字符序列,使用?
可以匹配單個字符。例如:*.log # 忽略所有 .log 文件 *.tmp # 忽略所有 .tmp 文件 secret_* # 忽略以 secret_ 開頭的文件
-
注釋:
可以在.gitignore
文件中使用#
符號添加注釋。例如:# 這是一個注釋
-
忽略整個文件夾:
如果想忽略整個文件夾及其所有內容,只需在.gitignore
文件中添加文件夾的名稱即可。例如:node_modules/ # 忽略 node_modules 文件夾及其所有內容
[!CAUTION]
.gitignore
文件中的每一行都描述了一個忽略模式。模式可以是文件名、文件路徑或者通配符,Git 會根據(jù)這些模式來確定哪些文件應該被忽略。
不過,現(xiàn)在也不需要從頭寫.gitignore
文件,這個 GitHub 上的項目《github/gitignore:》(點擊跳轉),為我們總結了幾乎適用于所有軟件開發(fā)的.gitignore
文件,可以根據(jù)自己開發(fā)項目所用的編程語言選擇,例如,我常用 C/C++ 開發(fā),我就下載對應的文件夾。
那么可能會有這樣的問題,那就是有時候可能需要提交某個文件,剛好是被忽略的,那要怎么添加呢?
如果打開.gitignore
文件重新修改就很麻煩,也不高效,所以在把工作區(qū)提交到暫存區(qū)時,加上-f
選項,表示強制提交。具體如下:
git add -f <file_name>
2. 配置別名
在 Git 中,你可以通過配置別名來創(chuàng)建自定義的命令或簡化常用的 Git 命令??梢栽?code>.gitconfig文件中設置別名,也可以使用git config
命令來設置。
以下是一些常見的 Git 別名配置示例:
-
使用
git config
命令設置別名:git config --global alias.co checkout
這個命令會創(chuàng)建一個名為
co
的別名,用于執(zhí)行git checkout
命令。 -
在
.gitconfig
文件中設置別名:
打開.gitconfig
文件,并添加類似以下內容的配置:[alias] co = checkout
這個配置會創(chuàng)建一個名為
co
的別名,用于執(zhí)行git checkout
命令。 -
設置帶參數(shù)的別名:
git config --global alias.br "branch -a"
這個命令會創(chuàng)建一個名為
br
的別名,用于執(zhí)行git branch -a
命令。 -
設置自定義命令別名:
git config --global alias.history "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
這個命令會創(chuàng)建一個名為
history
的別名,用于執(zhí)行自定義的git log
命令,可以顯示更簡潔的提交歷史。
設置好別名后,你可以直接使用別名來執(zhí)行相應的 Git 命令,這樣可以提高效率并減少輸入量。
3. 配置文件
配置 Git 的時候,加上--global
是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。每個倉庫本地的配置文件的位置都放在本倉庫的.git/config
文件中。
Git 的配置文件包括三個級別:系統(tǒng)級別、全局級別和倉庫級別。它們分別存儲在不同的位置,作用范圍也不同。
-
系統(tǒng)級別配置文件:
這個配置文件位于 Git 安裝目錄下的etc/gitconfig
文件中。它包含了對系統(tǒng)上所有用戶都適用的配置,通常由系統(tǒng)管理員進行管理。你可以使用git config --system
命令來修改系統(tǒng)級別的配置,但可能需要管理員權限。 -
全局級別配置文件:
這個配置文件位于用戶的主目錄下的.gitconfig
或者.config/git/config
文件中(取決于操作系統(tǒng)和 Git 版本)。它包含了對當前用戶所有倉庫都適用的配置。你可以使用git config --global
命令來修改全局級別的配置。 -
倉庫級別配置文件:
這個配置文件位于 Git 倉庫的根目錄下的.git/config
文件中。它包含了對當前倉庫的特定配置。你可以使用git config
命令來修改倉庫級別的配置,不需要任何特殊權限。
在配置文件中,你可以設置一些 Git 的行為選項、別名、用戶信息等。以下是一個簡單的示例:
[user]
name = Your Name
email = your.email@example.com
[alias]
co = checkout
ci = commit
st = status
[core]
editor = nano
這個配置文件設置了用戶信息、一些常用的別名,以及指定了默認的文本編輯器。你可以根據(jù)需要在配置文件中添加、修改或刪除配置項。
要查看當前的 Git 配置,可以使用git config --list
命令,它會列出當前生效的所有配置。
附錄
1. 關于 commit 提交信息規(guī)范
編寫規(guī)范的 Git commit 信息對于團隊協(xié)作和項目維護非常重要。以下是一個適用于嵌入式開發(fā)的 Git commit 信息規(guī)范示例:
<type>(<scope>): <subject>
<description>
<footer>
-
<type>
:同樣是描述 commit 的類型,可能包括:- feat:新功能
- fix:修復問題
- docs:文檔修改
- refactor:重構代碼
- test:增加或修改測試
- chore:構建過程或輔助工具的變動
-
<scope>
:描述 commit 影響的范圍,可以是一個模塊、驅動、功能名字等。 -
<subject>
:簡短描述 commit 的目的,用一句話概括。 -
<description>
:詳細描述 commit 的內容。對于嵌入式系統(tǒng),可能需要說明與硬件相關的修改、驅動的更新、性能優(yōu)化等。 -
<footer>
:一些附加信息,比如關聯(lián)的 issue、版本號、特定的硬件平臺等。
例如:
feat(sensor): implement driver for temperature sensor
Added driver for XYZ temperature sensor to handle temperature readings.
- Implemented initialization routine
- Added functions to read temperature in Celsius and Fahrenheit
- Tested on hardware version 2.1
Fixes #321
在嵌入式開發(fā)中,還可能會有一些特定的標簽或者約定,比如硬件版本、特定的編譯器或工具鏈版本等信息,需要根據(jù)項目實際情況進行調整和添加。
參考資料
Git教程 - 廖雪峰的官方網站 (liaoxuefeng.com)文章來源:http://www.zghlxwxcb.cn/news/detail-858167.html
這個配置會創(chuàng)建一個名為 co
的別名,用于執(zhí)行 git checkout
命令。
-
設置帶參數(shù)的別名:
git config --global alias.br "branch -a"
這個命令會創(chuàng)建一個名為
br
的別名,用于執(zhí)行git branch -a
命令。 -
設置自定義命令別名:
git config --global alias.history "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
這個命令會創(chuàng)建一個名為
history
的別名,用于執(zhí)行自定義的git log
命令,可以顯示更簡潔的提交歷史。
設置好別名后,你可以直接使用別名來執(zhí)行相應的 Git 命令,這樣可以提高效率并減少輸入量。
[外鏈圖片轉存中…(img-2u3qc6K0-1713703279247)]
3. 配置文件
配置 Git 的時候,加上--global
是針對當前用戶起作用的,如果不加,那只針對當前的倉庫起作用。每個倉庫本地的配置文件的位置都放在本倉庫的.git/config
文件中。
[外鏈圖片轉存中…(img-oEZbJta0-1713703279247)]
Git 的配置文件包括三個級別:系統(tǒng)級別、全局級別和倉庫級別。它們分別存儲在不同的位置,作用范圍也不同。
-
系統(tǒng)級別配置文件:
這個配置文件位于 Git 安裝目錄下的etc/gitconfig
文件中。它包含了對系統(tǒng)上所有用戶都適用的配置,通常由系統(tǒng)管理員進行管理。你可以使用git config --system
命令來修改系統(tǒng)級別的配置,但可能需要管理員權限。 -
全局級別配置文件:
這個配置文件位于用戶的主目錄下的.gitconfig
或者.config/git/config
文件中(取決于操作系統(tǒng)和 Git 版本)。它包含了對當前用戶所有倉庫都適用的配置。你可以使用git config --global
命令來修改全局級別的配置。 -
倉庫級別配置文件:
這個配置文件位于 Git 倉庫的根目錄下的.git/config
文件中。它包含了對當前倉庫的特定配置。你可以使用git config
命令來修改倉庫級別的配置,不需要任何特殊權限。
在配置文件中,你可以設置一些 Git 的行為選項、別名、用戶信息等。以下是一個簡單的示例:
[user]
name = Your Name
email = your.email@example.com
[alias]
co = checkout
ci = commit
st = status
[core]
editor = nano
這個配置文件設置了用戶信息、一些常用的別名,以及指定了默認的文本編輯器。你可以根據(jù)需要在配置文件中添加、修改或刪除配置項。
要查看當前的 Git 配置,可以使用git config --list
命令,它會列出當前生效的所有配置。
參考資料
Git教程 - 廖雪峰的官方網站 (liaoxuefeng.com)
Git - Book (git-scm.com)文章來源地址http://www.zghlxwxcb.cn/news/detail-858167.html
到了這里,關于Git 新手快速入門教程的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!