git基本操作,這篇文章就夠了!爆贊!

語言: CN / TW / HK

1.簡介

1.1 關於版本控制

版本控制是一種記錄一個或若干文件內容變化,以便將來查閲特定版本修訂情況的系統。

1.2 版本控制發展史

1.2.1 本地版本控制

記錄文件每次的更新,可以對每個版本做一個快照,或是記錄補丁文件,適合個人用,如RCS。

image.png

1.2.2 集中式的版本控制

所有的版本數據都保存在服務器上,協同開發者從服務器上同步更新或上傳自己的修改

image.png 所有的版本數據都存在服務器上,用户的本地只有自己以前所同步的版本,如果不連網的話,用户就看不到歷史版本,也無法切換版本驗證問題,或在不同分支工作。而且,所有數據都保存在單一的服務器上,有很大的風險這個服務器會損壞,這樣就會丟失所有的數據,當然可以定期備份。代表產品:SVN、CVS、VSS

1.2.3 分佈式版本控制系統

所有版本信息倉庫全部同步到本地的每個用户,這樣就可以在本地查看所有版本歷史,可以離線在本地提交,只需在連網時push到相應的服務器或其他用户那裏。由於每個用户那裏保存的都是所有的版本數據,只要有一個用户的設備沒有問題就可以恢復所有的數據,但這增加了本地存儲空間的佔用。

image.png

1.3 什麼是git

Git是目前世界上最先進的分佈式版本控制系統。

優點: - 適合分佈式開發,強調個體。 - 公共服務器壓力和數據量都不會太大。 - 速度快、靈活。 - 任意兩個開發者之間可以很容易的解決衝突。 - 離線工作 缺點: - 模式上比SVN更加複雜。 - 不符合常規思維。 - 代碼保密性差,一旦開發者把整個庫克隆下來就可以完全公開所有代碼和版本信息。

2.本地操作

2.1 安裝git

2.1.1 window安裝

在官網下載安裝文件,雙擊打開,然後一直“NEXT”就好。 下載地址如下:http://git-scm.com/download/win

image.png

2.2 初始化一個本地倉庫

我們現在要初始化一個本地倉庫:

git init 創建之後,目錄下會多一個".git"的文件夾,這個項目git的配置都在這個文件夾下面。注意:如果這個.git文件沒有顯示出來,需要我們把隱藏文件設置顯示出來即可,一般我們不需要修改此文件夾下的內容。

image.png

image.png

2.3 新增修改文件並且提交到git

先新建一個文件,在進到改文件打開 git Bash Here 接着執行如下 git add . // 更新到暫存區 git commit -m "build: 初始化項目" // 更新到資源庫 執行後出現了個錯誤:

image.png

這裏是説我們得吿訴git我們是誰,所以執行一下下面的命令

git config --global user.email "[email protected]" git config --global user.name "xiaoyuzhou" 再次執行 commit 命令

git commit -m "build: 初始化項目" 這樣文件就提交上去了。

這裏簡單説明一下:

Git本地有三個工作區域:工作目錄(Working Directory)、暫存區(Stage/Index)、資源庫(Repository或Git Directory)。 - Workspace:工作區,就是你平時存放項目代碼的地方 - Index / Stage:暫存區,用於臨時存放你的改動,事實上它只是一個文件,保存即將提交到文件列表信息 - Repository:倉庫區(或本地倉庫),就是安全存放數據的位置,這裏面有你提交到所有版本的數據。其中HEAD指向最新放入倉庫的版本

image.png

總結:

  • 我們使用 git add 工作區的文件添加到暫存區。
  • 使用 git commit -m "xxxx" 將暫存取的內容推到倉庫。裏面的內容信息可以參照 “Conventional Commits” 書寫規則。
  • 書寫良好的 commit message http://loveky.github.io/2018/06/04/write-good-commit-message/

2.4 查看歷史紀錄和狀態

我們可以使用 git status 查看狀態, 使用 git log 查看歷史紀錄。

我們來看下面的栗子

我們先建立三個文件

``` 第一步 vi a.txt // 新增 a.txt 文件 git add . git commit -m "feat: 新增a.txt文件"

第二步 vi b.txt // 新增 b.txt 文件 git add b.txt

第三步 vi c.txt // 新增 c.txt 文件 ``` 我們使用 git status 查看狀態

image.png

我們可以看到 a.txt 已提交到版本庫裏面,所以a.txt這裏看不到;b.txt 在暫存區中, c.txt在工作區。

我們使用 git log 查看歷史紀錄:(git log 查看到的必須添加是執行了git commit 到資源庫(Repository)

image.png

2.5 版本回退

2.5.1 工作區的回退

我們先把上面栗子中的文件提交到資源庫:

git add . git commit -m "feat: 新增b,c模塊" 然後在重新分別對b、c文件進行修改,在再次執行git status

git status

image.png

我們可以看到, c.txt之前存在版本庫中,我們需要把修改丟棄。 d.txt在版本庫中沒有,所以我們需要刪除文件。 使用如下命令:

git checkout c.txt(把c.txt修改的丟棄) rm d.txt image.png

總結: - 對於版本庫中存在的文件使用 git checkout 命令放棄修改,全部們見放棄修改使用git checkout . - 對於版本庫中不存在的文件使用 rm 命令刪除文件

2.5.2 暫存區回退

當文件已提交到暫存區,我們應該如何回退呢?我們先來修改一些文件,並且提交到暫存區

修改a.txt文件 新增b.txt文件 git add . git status

image.png

使用如下命令移除暫存區,讓文件回到工作區,然後使用上一節的方法丟棄修改

``` git reset HEAD 文件名 或者全部移使用: git reset HEAD . git status

```

image.png

總結:

  • 使用 git reset HEAD 命令使文件移除暫存區,回到工作區

2.5.2 資源庫版本切換

我們先查看一下歷史:

git log 我們查到了版本對應的git的id,接下來使用下面命令回退到之前提交的'項目初始化'這一版本,執行完之後在git status 發現我們現在目錄內容回到最初的樣子了

git reset --hard dfa4391707f9a64baa8eecf94e07e01a959fa091 git status

image.png

注意:如果突然我們發現自己回退錯版本了,需要回退到 "新增a.txt文件模塊"的那個版本,我們可以使用下面命令找到所以變更的版本歷史:

git reflog

image.png

PS:我們經常看到 git reset --hard HEAD^ 這樣的命令, 這句話表示放棄修改的內容,回退當前的版本,HEAD 表示當前版本,HEAD^ 表示上一個版本, HEAD~100表示上100個版本

總結:

  • 使用git reset --hard <版本號> 進行版本切換
  • 使用git reflog 查看所有的版本變更歷史
  • HEAD 表示當前版本

3 分支

3.1 分支介紹

分支就是科幻電影裏面的平行宇宙,當你正在電腦前努力學習Git的時候,另一個你正在另一個平行宇宙裏努力學習SVN。 如果兩個平行宇宙互不干擾,那對現在的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合併了,結果,你既學會了Git又學會了SVN!

image.png

分支在實際中有什麼用呢?假設你準備開發一個新功能,但是需要兩週才能完成,第一週你寫了50%的代碼,如果立刻提交,由於代碼還沒寫完,不完整的代碼庫會導致別人不能幹活了。如果等代碼全部寫完再一次提交,又存在丟失每天進度的巨大風險。

現在有了分支,就不用怕了。你創建了一個屬於你自己的分支,別人看不到,還繼續在原來的分支上正常工作,而你在自己的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工作。

其他版本控制系統如SVN等都有分支管理,但是用過之後你會發現,這些版本控制系統創建和切換分支比蝸牛還慢,簡直讓人無法忍受,結果分支功能成了擺設,大家都不去用。

但Git的分支是與眾不同的,無論創建、切換和刪除分支,Git在1秒鐘之內就能完成!無論你的版本庫是1個文件還是1萬個文件。

3.2 分支的創建、合併以及刪除

當我們創建新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:

image.png

你看,Git創建一個分支很快,因為除了增加一個dev指針,改改HEAD的指向,工作區的文件都沒有任何變化!

不過,從現在開始,對工作區的修改和提交就是針對dev分支了,比如新提交一次後,dev指針往前移動一步,而master指針不變:

假如我們在dev上的工作完成了,就可以把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合併:

image.png

所以Git合併分支也很快!就改改指針,工作區內容也不變!

合併完分支後,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉後,我們就剩下了一條master分支:

image.png

下面開始實戰:

1)創建分支

git checkout -b dev git checkout命令加上-b參數表示創建並切換,相當於以下兩條命令:

git branch dev (創建dev分支) git checkout dev (切換到dev分支) 2) 查看分支

git branch

image.png

3)修改文件並提交

修改 a.txt 文件裏的內容 git add . git commit -m "feat: a模塊新增一行" 4)合併dev到master

git checkout master // 切回master分支 git merge dev // 合併dev分支到master

image.png

執行cat a.txt 就可以看到a.txt文件裏面的內容了

image.png

4)刪除dev分支,執行 git branch -d dev

image.png

總結

1)Git鼓勵大量使用分支:

``` 查看分支:git branch

創建分支:git branch

切換分支:git checkout 或者git switch

創建+切換分支:git checkout -b 或者git switch -c

合併某分支到當前分支:git merge

刪除分支:git branch -d

``` 2)有文件存在工作區或者暫存區時,切換分支後,這些文件會原封不動的帶到新的分支。

3.3 解決衝突

人生不如意之事十之八九,合併分支往往也不是一帆風順的。

我們先修改一下master分支的a.txt文件

git add . git commit -m "feat: 新增一行master" 我們再切到qa分支上,修改a.txt文件

``` git checkout -b qa

git add . git commit -m "feat: 新增一行qa" ``` 然後我們再master分支合併一下

git checkout master git merge qa git status Git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容。 ======= 上面的內容為當前分支的內容,下面的為合併過來分支的內容我們做相應的修改,然後提交.

git add . git commit -m "chore: 解決qa合併到master的衝突" 小結: - 當Git無法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。 - - 解決衝突就是把Git合併失敗的文件手動編輯為我們希望的內容,再提交。

3.4 bug分支

軟件開發中,bug就像家常便飯一樣。有了bug就需要修復,在Git中,由於分支是如此的強大,所以,每個bug都可以通過一個新的臨時分支來修復,修復後,合併分支,然後將臨時分支刪除。

當你接到一個修復一個代號101的bug的任務時,很自然地,你想創建一個分支bug-101來修復它,但是,等等,當前正在dev上進行的工作還沒有提交:

image.png

我們可以使用 stash命令把修改儲藏起來

git stash git status

image.png

我們再創建bug-101分支進行修改

git checkout -b bug-101 新建b.tex,並進行修改一下 git add . git commit -m "fix: 修正bug101" 切回master分支,並且合併

git checkout master git merge --no-ff -m "chore: bug101合併到master上" bug-101

取出儲藏的修改

git stash pop

image.png

我們發現b.txt文件衝突了,根據上面的內容解決衝突就可以了。

總結: 修復bug時,我們會通過創建新的bug分支進行修復,然後合併,最後刪除; 當手頭工作沒有完成時,先把工作現場git stash一下,然後去修復bug,修復後,再git stash pop,回到工作現場。 一般我們都是切獨立分支修改的,所以這個方法我們用的不是特別多。

4 遠程倉庫的使用

上面的章節裏面,我們介紹了git的本地使用,知道了在本地各版本之間進行穿梭。 但這僅限於我們自己玩,如果要大家一起工作完成一個項目,勢必需要遠程倉庫。

雖然git是分佈式的,大家可以相互傳輸文件,但其實很少在兩人之間的電腦上推送版本庫的修改,因為可能你們倆不在一個局域網內,兩台電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。因此,分佈式版本控制系統通常也有一台充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣幹活,只是交換修改不方便而已。而為了方便管理,我們一般會把託管平台選為“中央服務器”。

image.png

4.1 託管平台(github拓展)

託管平台可以是第三方提供的,如github,碼雲等,也可以是我們自己搭建的(公司使用gogs自己搭建了一個)。各種託管平台操作大同小異,下面我就用第三方提供的github來當作我們的“中央處理器”。 - github 網址:github.com/ 接下來我們在github上新建一個項目:

1) 註冊登陸github

image.png

2) 新建倉庫

image.png

image.png

image.png

4.1.1 本地倉庫與遠程倉庫關聯

在倉庫頁面,我們有兩種關聯倉庫的方式,我們使用SSH的方式來關聯。

注意: 第一次關聯遠程倉庫之前最好先配置下用户郵箱和姓名,這樣在提交到遠程倉庫的時候git知道你是誰

git config --global user.name"zhangzhengzhou"

git config --global user.email"[email protected]"

image.png

執行下面命令:

git remote add origin [email protected]:zhangzhengzhou/yanshi.git git push -u origin main(第一次提交一定要帶上-u) 執行完成後會報一個權限驗證不通過的錯誤。

image.png

要消除這個錯誤,需要把我們服務器的SSH公鑰放到github上

4.1.2 生成ssh公鑰

我們使用下面命令生成公鑰和私鑰。 1.驗證下本地有沒有生成.ssh文件,如果沒提示説明本地有了 反之要去生成.ssh

image.png

2.本地沒有ssh 執行以下命令

ssh-keygen -t rsa 或者 ssh-keygen -t rsa -C "[email protected]" 之後執行 cd ~/.ssh 去查看有沒有提示 沒提示説明已生成

image.png

image.png

一般生成的路徑如下

image.png

把公鑰的內容複製到github上。

image.png

image.png

image.png

image.png

image.png

點擊確認之後,要輸入github的登錄密碼進行確認 image.png

image.png

我們再執行一次,就可以把master 分支推到遠程倉庫中去了。

git push -u origin master - u :代表關聯的主機 - origin:代表遠程倉庫源 image.png

推送遠程倉庫成功! image.png

小結:

  • 我們使用 git remote add origin <遠程地址> 關聯遠程倉庫
  • 第一次使用 git push -u origin master 推送
  • 使用SSH協議,需要配置SSHkey
  • 以後再次推送直接使用 git push 即可

4.1.3 推送遠程分支和刪除遠程分支

我們把qa分支推送到遠程倉庫:

git checkout qa git push origin qa //第一次使用和遠程qa分支想關聯

github 裏面的提交記錄 image.png

使用下面命令來刪除遠程分支: git push origin --delete qa 查看遠程分支用git branch -r

image.png

4.1.4 從遠程倉庫克隆

如果我們本地沒有倉庫,需要把線上的倉庫克隆下來,可以使用下面的命令,這裏我們使用http的方式

git clone http://github.com/.git -b qa yanshi 我們來解釋一下里面的兩個參數 - -b qa: 表示克隆qa分支,如果不加,默認拷貝master分支 - yanshi: 把克隆下來的內容放在"yanshi"文件夾下面 小結:

  • 使用 git clone [email protected]:zhangzhengzhou/yanshi.git [-b 分支名] [目錄名] 來克隆倉庫
  • 我們不建議使用htts的方式,因為https除了慢,還要經常輸入口令(即github或者gitlab的登錄賬號和密碼)非常麻煩

思考題

如果我們遠程分支推錯了怎麼辦?

4.2託管平台(gitlab 主講)

4.2.1 創建項目

1)創建項目

image.png 選擇Private項

  • Private:項目訪問權必須明確授予每個用户
  • Internal:任何登錄的用户都可以訪問該項目
  • Public: 無需任何身份驗證即可訪問該項目

image.png

4.2.2 本地倉庫與遠程倉庫關聯同目錄4.1.1

4.2.3 同生成ssh公鑰目錄 4.1.2

image.png

4)同4.1.4 從遠程倉庫克隆

5 Pull Request 的命令行管理

5.1 Pull Request介紹

"Pull Request 是一種通知機制。你修改了他人的代碼,將你的修改通知原來的作者,希望他合併你的修改,這就是 Pull Request。

5.2 Pull Request 的流程

github的pull requst

image.png

gitlab的流程

第一步,你需要把別人的代碼,克隆clone到你自己的倉庫,Github 的術語叫做 fork。

比如定義別人的倉庫定義為A,克隆到你自己的倉庫B

image.png

image.png

接着我們要在自己的倉庫裏面clone到本地,進行一些列的add、commit、push修改提交

image.png

然後進行merge requests

image.png

image.png

image.png

確認提交信息

image.png

接下來我們就可以在A 也就是別人的倉庫裏面就可以收到merge requests 的請求記錄列表,

查看是否進merge和並

image.png

image.png

image.png

5.3 刪除自己倉庫fork的項目

image.png

點擊刪除的彈框裏面 一定要輸入項目名稱例如BdBiProcSrvShEduOmc_ForeEndWeb 不然不能confirm確認

image.png

image.png

6. 操作git的兩種工作流程

1)第一種 把遠程的dev分支拷貝到本地

  1. 把遠程的dev分支拷貝到本地
  2. 修改dev分支,並push給遠程倉庫
  3. 遠程倉庫把dev分支合併到qa
  4. 遠程倉庫把qa合併到prod

image.png

2)第二種 從遠程prod分支check出一個tmp分支

  1. 從遠程prod分支check出一個tmp分支
  2. 修改tmp分支,把tmp分支合併到遠程倉庫的dev
  3. 把tmp分支合併到遠程倉庫的qa
  4. 把tmp分支合併到遠程倉庫的prod

image.png

思考題:

這兩種方式孰優孰劣?我們應該如何選擇?

7 拓展: vscode的安裝和使用git

地址:http://code.visualstudio.com/

vscode有內置的git插件,所以無需安裝,當然你也可以使用其他git插件輔助(比如SourceTree客户端)

image.png

SourceTree客户端

image.png

打開對應的文件夾即可 image.png

image.png