前言
- 說明:本文是為了給公司員工培訓(xùn)而編寫的教程,意在深度理解git原理,不適合“快餐式”學(xué)習(xí),適合“刨根問底”式學(xué)習(xí)。理解本文內(nèi)容,可以解決git常見的一切問題。
Git學(xué)習(xí)官方網(wǎng)址:https://git-scm.com/book/zh/v2
主要學(xué)習(xí)內(nèi)容:git原理、git命令。
githug游戲----git學(xué)習(xí)游戲:https://github.com/Gazler/githug
將git基本操作,設(shè)計成游戲卡關(guān)的方式,主要學(xué)習(xí)git命令行。
正文
一. 起步
1.1 Git工具
Git操作工具比較多,主要分為命令行和圖像化工具,本文主要介紹:iTerm2(命令行)和SourceTree兩種工具。
1.1.1 命令行工具:
- macOS系統(tǒng):iTerm2以及終端工具配置:iTerm2 + Zsh + Oh My Zsh + tmux
上面的配置工具包含:
1. iTerm2:一個終端模擬器,比macOS系統(tǒng)自帶的終端好用太多。
我剛接觸到iTerm2時的時候是極力抗拒的,但是發(fā)現(xiàn)了她的好自后,我寧愿花上20分種時間配置一個iTerm2環(huán)境出來。
具體我不多說,誰用誰知道
2. Solarized:為iTerm2增加配色方案
3. Zsh:使用brew更新macOS自帶的zsh(brew是macOS下強大的包管理工具)
4. Oh My Zsh:用來管理 Zsh 配置的,自帶了好用的基本配置,基本都是 Zsh 的標配了
5. tmux:一個終端復(fù)用軟件,可將終端方案化
配置完成的效果如下:


- windows系統(tǒng):cmder,安裝教程簡單,安裝教程:windows下的命令行工具-Cmder
配置完成的效果如下:

1.1.2 圖形化工具
- SourceTree:最好用的Git圖形化工具,沒有之一。
官網(wǎng)地址:https://www.sourcetreeapp.com
接下來我們以最受歡迎的Swift的http請求項目Alamofire為例子,查看SourceTree效果。

優(yōu)勢:
1. 強大的UI操作,遠端和本地分支清晰分明。
2. 強大的分支流顯示,可以顯示每個分支的狀態(tài),以及合并狀態(tài)。這是我使用它的重要原因。
3. 簡單,入門比較低,但是如果不懂git底層原理,容易造成誤操作。
不足:
1. 與基本命令行相比,功能不夠完善。
2. Git狀態(tài)顯示延時,不夠流暢。
1.2 Git配置
1.2.1 用戶信息配置
當安裝完 Git 應(yīng)該做的第一件事就是設(shè)置你的用戶名稱與郵件地址。 這樣做很重要,因為每一個 Git 的提交都會使用這些信息,并且它會寫入到你的每一次提交中。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
解釋說明
--global:配置全局的信息
- 疑惑:那我們?yōu)槭裁匆渲糜脩裘袜]箱呢?
這便于我們在提交代碼時候查看到開發(fā)者信息,方便找到提交的作者。
在git log查看git提交記錄命令中,正如Author信息所顯示:Christian Noon為作者,christian.noon@gmail.com為郵箱。

在SourceTree查看提交的作者信息,效果如下

1.2.2 查看用戶配置信息
當你配置完成用戶信息,想要查看用戶信息是否配置正確可以執(zhí)行一下命令
$ git config --global --list

1.2.3 SourceTree查看配置信息
Mac版的SourceTree配置用戶名和地址如下:

二. Git基礎(chǔ)
2.1 忽略文件
顧名思義,忽略文件,也就是不需要加入Git版本控制的文件,文件形式為.gitignore文件。比如macOS系統(tǒng)中的.DS_Store文件。
依舊以Alamofire為例,查看他的.gitignore文件

查看.gitignore文件內(nèi)容

疑惑:我的個XXX,這又是 . * / 什么鬼意思,那我的項目需要加入什么樣子內(nèi)容的.gitignore呢?
淡定,別急,我們同性交友網(wǎng)站的大神們幫我們整理出來了網(wǎng)頁地址如下:https://github.com/github/gitignore
下面是我貼出來的部分.gitignore的文件:

找到屬于你的語言的.gitigonre文件,使用命令行工具,加入項目中。
如果你不知道怎么創(chuàng)建.gitignore文件我也告訴你,方法如下:
1. 用命令行工具(iTerm2)打開項目根路徑
2. 然后 vim .gitignore ,創(chuàng)建或者編輯 .gitignore 文件
3. 然后將 gitignore 官方提供的 gitignore 提供的內(nèi)容拷貝下來,
粘貼到 .gitignore 文件中,推出并且保存。到此 .gitignore 文件添加成功
4. 你還可以用 cat .gitignore 命令查看自己的.gitignore文件是否添加正確
- 提高部分:
探究或者增加自己的.gitignore內(nèi)容,可以閱讀以下地址的忽略文件章節(jié)
網(wǎng)址:.gitignore忽略文件學(xué)習(xí)
2.2 獲取Git倉庫
兩種方式獲取一個git倉庫
1. 在現(xiàn)有目錄中初始化倉庫
打算使用Git對現(xiàn)有項目進行管理,只需要進入該項目的根路徑,可以使用cd命令進入該項目路徑
$ git init

當你完成git初始化命令之后,你會發(fā)現(xiàn),在項目的根目錄下多了一個.git的文件夾,那個git進行版本控制的最核心的文件夾。

Tips:Mac如何顯示隱藏文件呢?之前一直使用命令行,我日,那個方法太麻煩了?,F(xiàn)在我教你一個最簡單的方法,一般人我可不告訴他,哈哈。顯示或隱藏隱藏文件快捷鍵:Command + .
2. 克隆現(xiàn)有的遠端倉庫
Git 支持多種數(shù)據(jù)傳輸協(xié)議。 上面的例子使用的是 https:// 協(xié)議,不過你也可以使用 git:// 協(xié)議或者使用 SSH 傳輸協(xié)議,比如 user@server:path/to/repo.git
// git協(xié)議
$ git clone git@github.com:Alamofire/Alamofire.git
// https協(xié)議
$ git clone https://github.com/Alamofire/Alamofire.git
克隆一個遠端倉庫需要兩點注意的問題:
- 克隆后的項目路徑問題:因為本人有點小潔癖,對這個克隆后的文件路徑都很嚴謹
我們以克隆AlamofireImage為例子,我想在Project文件夾下,克隆這個開源項目。

解釋說明:
命令說明:
pwd:輸出當前所在路徑
ls -a:查看當前文件夾下所有的子文件
克隆結(jié)果說明:
當前目錄下創(chuàng)建一個名為 “AlamofireImage” 的目錄,并在這個目錄下初始化一個 .git 文件夾,
從遠程倉庫拉取下所有數(shù)據(jù)放入 .git 文件夾,然后從中讀取最新版本的文件的拷貝。
如果你進入到這個新建的 AlamofireImage 文件夾,你會發(fā)現(xiàn)所有的項目文件已經(jīng)在里面了,
準備就緒等待后續(xù)的開發(fā)和使用。
- 克隆方式選擇:https方式一般需要輸入賬號密碼,git方式需要配置ssh。
3. 使用SourceTree克隆遠端倉庫
點擊順序:新倉庫->從URL克隆,彈出第二個頁面。

克隆倉庫時,輸入信息說明:
源URL:是遠程倉庫地址
目標路徑:你想要在電腦磁盤保存的路徑,這里需要自己增加項目倉庫的名稱
名稱:項目倉庫的名稱
注意事項:第一次克隆項目如果是https需要輸入用戶名和密碼,如果是git方式
并且你的ssh密鑰有密碼需要你輸入密碼。

2.2 記錄每次更新到倉庫
2.2.1 文件狀態(tài)查看
- 請記住,你工作目錄下的每一個文件都不外乎這兩種狀態(tài):已跟蹤或未跟蹤
未跟蹤:Untracked(未跟蹤)
已經(jīng)跟蹤:Unmodified(未修改)、Modified(已修改)、Staged(已暫存)
總結(jié):第一次理解這個圖片比較難,但是理解之后,你就會發(fā)現(xiàn),對于git文件狀態(tài)你就完全掌握。

各種狀態(tài)剖析:
- Untracked(未跟蹤):
- 新增加的文件
- 從git跟蹤中移除(git rm --cached <file path>)

圖片說明:我創(chuàng)建了一個
status.txt文件,在使用git status命令時,他已經(jīng)變成一個Untracked(未跟蹤)文件。
- Staged(已暫存):
- 使用
git add命令跟蹤文件,只要一個文件被git add過,它就變成Staged狀態(tài)(可以被git add狀態(tài)是Unmodified和Untracked)
- 使用

圖片說明:圖片中的"changes to be",意思是
status.txt文件已經(jīng)被暫存,你可用于提交。
- Unmodified(未修改)
- 已經(jīng)提交的文件狀態(tài):
git commit提交修改文件,文件狀態(tài)將變成此狀態(tài)。 - 丟棄這個文件的當前修改:
git checkout -- <file path>
- 已經(jīng)提交的文件狀態(tài):

- Modified(已修改)
- 已經(jīng)提交的文件,修改此文件,他會變成此狀態(tài)。
- 已經(jīng)暫存的文件,修改此文件,他也會變成此狀態(tài)。

圖片說明:我使用vim命令編輯了status.txt文件,在用git status命令查看文件狀態(tài)時,它已經(jīng)變成已修改狀態(tài)了。
2.2.2 查看文件狀態(tài)
使用git status查看項目所有文件狀態(tài),其中包含哪些文件時新增、被修改、被刪除、已暫存等等,其實就是上面四種狀態(tài)的具體形式的反應(yīng)。
$ git status

- SourceTree查看文件狀態(tài)
黃色的"-"號表示Modified(已修改)文件,紫色的"?"表示Untracked(未跟蹤)文件。當然還有其他狀態(tài)文件,途中沒有盡列出來。

2.2.3 跟蹤并暫存文件
對于新建文件,或者已經(jīng)從git跟蹤中移除的文件,或者已經(jīng)修改的文件,使用git add命令,讓他們變成已經(jīng)暫存的狀態(tài)。
// 跟蹤并暫存單個文件
$ git add <file name>
// 跟蹤并暫存所有文件,常用?。?!
$ git add -A

- SourceTree跟蹤并暫存文件
- 跟蹤并暫存單個文件,相當于命令
git add <file name> - 跟蹤并暫存所有文件,相當于命令
git add -A或者git add .
- 跟蹤并暫存單個文件,相當于命令

2.2.4 查看已暫存和未暫存的修改
- 查看未暫存的修改
盡管 git status 可以看到路徑下那些文件發(fā)現(xiàn)變動,但是我們無法知曉具體改動那一行代碼?而git diff 將通過文件補丁的格式顯示具體哪些行發(fā)生了改變。
// 查看未暫存文件的修改
$ git diff

注意事項:"+"號標識的是修改中增加內(nèi)容,同理推測,"-"標識的就是修改中刪除內(nèi)容
- 查看已暫存的修改
若要查看已暫存的將要添加到下次提交里的內(nèi)容,可以用 git diff --cached 命令。(Git 1.6.1 及更高版本還允許使用 git diff --staged,效果是相同的,但更好記些。)
$ git diff --cached <file path>

- SourceTree 查看已暫存和未暫存的修改
點擊順序:文件狀態(tài)->已暫存文件(未暫存文件)->選擇具體文件名->查看文件狀態(tài)

2.2.5 提交更新
-
可以提交的條件:確認所有的新建或者修改被
git add過,因為git無法記錄未暫存的變動。 -
規(guī)避提交遺漏:先用
git status看下,是不是都已暫存起來了,然后在運行提交命令git commit
$ git commit
- 注意事項:這種提交方式會啟動文本編輯器以便輸入本次提交的說明。



- 圖片說明:
- 輸入提交內(nèi)容,以"#"為開頭的行將被忽略,如果你輸入的內(nèi)容為空,提交將被中斷。
- 提交成功后,在反饋信息中會有本次提交的修改信息。(包含文件個數(shù),增加行數(shù),刪除行數(shù))
我們比較常用的方法,會在 commit 命令后添加 -m 選項,將提交信息與命令放在同一行,如下所示:
$ git commit -m "<commit message>"

- 使用SourceTree提交,三部曲:

2.2.5 移除文件
- 移除文件的三種方式
-
rm <file path>: 將文件只從磁盤中移除 -
git rm --cached <file path>:將文件只從git暫存中移除 -
git rm <file path>:相當于上面兩個操作的合并,將文件從磁盤和git暫存中同時移除。
-
2.3 查看提交歷史
這邊涉及的知識點比較零散,一般使用者只要知道基本命令就行,不做詳細的說明。
具體可以看官網(wǎng)教程,我在這邊附上鏈接:官方文檔-查看提交歷史。
- 查看最基礎(chǔ)的git提交記錄
// 查看提交記錄,最簡單的數(shù)據(jù)呈現(xiàn)
$ git log

- 查看前某幾次的提交的變動
// 參數(shù)說明:"-1"表示最后一次提交的變動,以此類推"-2"則是最后兩次提交的變動
$ git log -p -1
// 查看作者為caiqiujun的,提交前最后一次的變動
git log --author=caiqiujun -p -1

- 查看某個文件的變動記錄(俗稱:找鍋)
// file path為文件路徑
$ git log -p -- <file path>

- 查看分支的圖形化變動
目的:分析當前分支的合并情況
$ git log --graph

- SourceTree 查看歷史變動情況,三部曲:

2.4 撤消操作
2.4.1 將修改補充到上次提交中
有時候我們提交完了才發(fā)現(xiàn)漏掉了幾個文件沒有添加,或者提交信息寫錯了。 此時,可以運行帶有 --amend 選項的提交命令嘗試重新提交:
$ git commit --amend

圖片說明:
-
vim編輯 forget.txt 文件 -
git add -A將文件暫存 -
git status查看文件狀態(tài),確認文件已經(jīng)暫存 -
git commit --amend將forget.txt提交到上次提交中
2.4.2 撤消對文件的修改
- 需要撤銷的文件--未暫存
有時候我們需要,放棄對某個未暫存文件的修改,可以使用git checkout 命令丟棄文件修改,這是一個很危險的命令,一旦丟棄就無法找回。

圖片說明:
-
git status查看文件forget.txt文件是已修改狀體 -
git checkout -- <file name>撤銷該文件修改 -
git status在此查看文件狀態(tài),已經(jīng)沒有被修改的文件了,對forget.txt文件修改撤銷成功。
- 需要撤銷的文件--已暫存

圖片說明:
-
git status查看文件狀態(tài),forget.txt為已經(jīng)暫存的修改 -
git reset HEAD <filename>放棄暫存文件 -
git status查看文件是否已經(jīng)變成未暫存狀態(tài) - 再調(diào)用上一小節(jié)
git checkout -- <file name>撤銷對文件的修改。
2.4.3 SourceTree 撤銷操作
- 將忘記提交的文件補充到賞賜提交中,類似于
git commit --amend

- 撤銷該文件的修改,到賞賜提交的狀態(tài),類似于
git checkout -- <filename>

- 將文件變成未暫存文件,類似于
git reset HEAD <filename>

2.5 遠程倉庫的使用
2.5.1 查看遠程倉庫
如果想查看你已經(jīng)配置的遠程倉庫服務(wù)器,可以運行 git remote -v 命令,會顯示需要讀寫遠程倉庫使用的 Git 保存的簡寫與其對應(yīng)的 URL。
$ git remote -v

2.5.2 添加遠程倉庫
運行 git remote add <shortname> <url> 添加一個新的遠程 Git 倉庫,同時指定一個你可以輕松引用的簡寫:

2.5.3 從遠程倉庫中抓取與拉取
從遠程倉庫中獲得數(shù)據(jù),可以執(zhí)行:
$ git fetch [remote-name]
這個命令會訪問遠程倉庫,從中拉取所有你還沒有的數(shù)據(jù)。 執(zhí)行完成后,你將會擁有那個遠程倉庫中所有分支的引用,可以隨時合并或查看。
必須注意 git fetch 命令會將數(shù)據(jù)拉取到你的本地倉庫 - 它并不會自動合并或修改你當前的工作。 當準備好時你必須手動將其合并入你的工作 。
運行 git pull 通常會從最初克隆的服務(wù)器上抓取數(shù)據(jù)并自動嘗試合并到當前所在的分支。
$ git pull [remote-name]
這個操作比較危險,因為她會自動幫你合并,或許有時候你只想看看遠端倉庫,有沒有其他開發(fā)者更新了代碼而已。
2.5.4 遠程倉庫的移除與重命名
如果想要重命名引用的名字可以運行 git remote rename 去修改一個遠程倉庫的簡寫名。
$ git remote rename [old-name] [new-name]

如果因為一些原因想要移除一個遠程倉庫,可以使用 git remote rm [remote-name] :
$ git remote rm [remote-name]

2.5.5 SourceTree 遠端倉庫操作
- 配置遠端倉庫
首先看遠端倉庫的增刪改查:設(shè)置->遠端倉庫->其他操作...

- 執(zhí)行抓取操作
注意點:一定要勾選第二復(fù)選框。
比如:團隊里面其他開發(fā)者刪除了一些遠端分支,在你的git遠端分支依然還顯示者那些分支。如果你嘗試勾選它時,在抓取一次,你就會發(fā)現(xiàn)那些已經(jīng)刪除的分支消失了。

- 執(zhí)行拉取操作

三. Git 分支
3.1 分支簡介
分支原理介紹請參照官網(wǎng):官網(wǎng)地址
3.1.1 分支創(chuàng)建
創(chuàng)建分支,原理就是創(chuàng)建一個新的可以移動的分支。如下命令是創(chuàng)建一個testing分支
$ git branch testing
注意事項
- 創(chuàng)建分支之前最好保證所有修改已經(jīng)提交,即工作樹是干凈的。
- 創(chuàng)建新分支時,會拷貝當前分支代碼。(從分支原理可以解釋)
- 創(chuàng)建分支后,不會主動切換到新建分支上,必須執(zhí)行
git checkout [branch-name]命令切換分支。如果你想創(chuàng)建一個新分支,并切換到新分支上可以執(zhí)行git checkout -b testing命令

3.2 分支合并
如果你想將testing分支修改的內(nèi)容合并到master主分支上,你可以執(zhí)行以下操作:
// 切換到master分支
$ git checkout master
// 將testing分支合并到master分支
$ git merge testing

注意事項
- 創(chuàng)建分支之前最好保證所有修改已經(jīng)提交,即工作樹是干凈的。
- 分支合并完成如果有沖突,需要解決沖突,在作出一次新的提交。
- 沖突原因
兩個分支不同的代碼塊修改了同一代碼區(qū)域,git不能判斷需要保留哪個分支的提交。
- 沖突案例分析
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
- 沖突區(qū)域模型
<<<<<<< 分支A
[沖突代碼塊]
=======
[沖突代碼塊]
>>>>>>> 分支B
解決沖突步驟
- 讀懂沖突代碼實現(xiàn)的功能
- 構(gòu)建最終需要的代碼
- 刪除沖突標記
<<<<<<<(沖突開始標記) 、=======(兩個沖突分割標記) 、>>>>>>>(沖突開始結(jié)束) ,最終讓整個文件變成一個正常的代碼文件。 -
git add緩存修改,git commit完成沖突修改提交
3.3 分支管理
3.3.1 查看本地分支
如果你想查看你的本地有哪些分支,你可以使用以下命令:
$ git branch
3.3.2 過濾已經(jīng)合并或尚未合并到當前分支的分支
如果要查看哪些分支已經(jīng)合并到當前分支,可以運行 git branch --merged:
$ git branch --merged
iss53
* master
查看所有包含未合并工作的分支,可以運行 git branch --no-merged:
$ git branch --no-merged
testing
如果未合并的分支,無法正常刪除。如果需要強制刪除使用git branch -D [branch-name]
$ git branch -d testing
error: The branch 'testing' is not fully merged.
If you are sure you want to delete it, run 'git branch -D testing'.
3.4 遠程分支
遠程跟蹤分支是遠程分支狀態(tài)的引用。 它們是你不能移動的本地引用,當你做任何網(wǎng)絡(luò)通信操作時,它們會自動移動。 遠程跟蹤分支像是你上次連接到遠程倉庫時,那些分支所處狀態(tài)的書簽。
本篇文章持續(xù)更新中,有什么意見可以提,謝謝!