Git實戰

對弈發表於2019-07-27

Git實戰

1、Git特點

1.1、Git兩大特點

  • 版本控制:可以解決多人同時開發的程式碼問題,也可以解決找回歷史程式碼的問題。
  • 分散式:Git是分散式版本控制系統,同一個Git倉庫,可以分佈到不同的機器上。首先找一臺電腦充當伺服器的角色,每天24小時開機,其他每個人都從這個“伺服器”倉庫克隆一份到自己的電腦上,並且各自把各自的提交推送到伺服器倉庫裡,也從伺服器倉庫中拉取別人的提交。可以自己搭建這臺伺服器,也可以使用GitHub網站。

2、Git安裝與配置

2.1、安裝命令

sudo apt-get install git

Git實戰

2.2、安裝成功後,檢視版本資訊

git

Git實戰

3、建立版本庫

3.1、新建一個目錄git_test,在git_test目錄下建立一個版本庫

git init

Git實戰

可以看到在git_test目錄下建立了一個.git隱藏目錄,這就是版本庫目錄。

4、版本建立與回退

4.1、使用

4.1.1、在git_test目錄下建立一個檔案code.txt,編輯內容如下:

Git實戰

4.1.2、使用如下兩個命令建立一個版本

git add code.txt
git commit -m '版本一'

Git實戰

4.1.3、使用如下命令可以檢視版本記錄

git log

Git實戰

4.1.4 、繼續編輯code.txt,在裡面增加一行

Git實戰

4.1.5、使用如下命令再建立一個版本並檢視版本記錄

Git實戰

4.1.6、現在若想回到某一個版本,可以使用如下命令

git reset --hard HEAD^

​ 其中HEAD表示當前最新版本,HEAD^表示當前版本的前一個版本,HEAD^^表示當前版本的前前個版本,也可以使用HEAD~1表示當前版本的前一個版本,HEAD~100表示當前版本的前100版本。

​ 現在若覺得想回到版本1,可以使用如下命令:

Git實戰

​ 執行命令後使用git log檢視版本記錄,發現現在只能看到版本1的記錄,cat code.txt檢視檔案內容,現在只有一行,也就是第一個版本中code.txt的內容

4.1.7、假如我們現在又想回到版本2,這個時候怎麼辦?可以使用如下命令

git reset --hard 版本號

從上面可以看到版本2的版本號為:

Git實戰

4.1.8、在終端執行如下命令

Git實戰

現在發現版本2有回來了。可以cat code.txt檢視其裡面的內容如下:

Git實戰

4.1.9、假如說上面的終端已經關了改怎麼回退版本。我們在執行如下命令將版本回退到版本1

Git實戰

下面把終端關了,然後再開啟終端,發現之前版本2的版本號看不到了。

那麼怎麼再回到版本2呢?git reflog命令可以檢視我們的操作記錄

git reflog

Git實戰

可以看到版本2的版本號,我們再使用如下命令進行版本回退,版本重新回到了版本2。

Git實戰

4.2、工作區和暫存區

4.2.1、工作區(Working Directory)

電腦中的目錄,比如我們的git_test,就是一個工作區。

4.2.2、版本庫(Repository)

​ 工作區有一個隱藏目錄.git,這個不是工作區,而是git的版本庫。

​ git的版本庫裡存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區,還有git為我們自動建立的第一個分支master,以及指向master的一個指標叫HEAD。

​ 因為我們建立git版本庫時,git自動為我們建立了唯一一個master分支,所以,現在,git commit就是往master分支上提交更改。

​ 你可以簡單理解為,需要提交的檔案修改通通放到暫存區,然後,一次性提交暫存區的所有修改。

Git實戰

​ 前面講了我們把檔案往git版本庫裡新增的時候,是分兩步執行的:

​ 第一步是用git add把檔案新增進去,實際上就是把檔案修改新增到暫存區;

​ 第二步是用git commit提交更改,實際上就是把暫存區的所有內容提交到當前分支。

4.2.3、下面在git_test目錄下再建立一個檔案code2.txt,然後編輯內容如下

Git實戰

4.2.4、然後再次編輯code.txt內容,在其中加入一行,編輯後內容如下

Git實戰

4.2.5、使用如下命令檢視當前工作樹的狀態

git status

Git實戰

上面提示我們code.txt被修改,而code2.txt沒有被跟蹤。

4.2.6、我們使用如下命令把code.txt和code2.txt加入到暫存區,然後再執行git status命令,結果如下

Git實戰

所有git add命令是把所有提交的修改存放到暫存區。

4.2.7、 然後,執行git commit就可以一次性把暫存區的所有修改提交到分支建立一個版本

Git實戰

4.2.8、一旦提交後,如果你又沒有對工作區做任何修改,那麼工作區就是“乾淨”的。執行如下命令可以發現

Git實戰

現在我們的版本庫變成了這樣:

Git實戰

4.3、管理修改

git管理的檔案的修改,它只會提交暫存區的修改來建立版本

4.3.1、編輯code.txt,並使用git add 命令將其新增到暫存區中

Git實戰

4.3.2、繼續編輯code.txt,並在其中新增一行

Git實戰

4.3.3、git commit建立一個版本,並使用git status檢視,發現第二次修改code.txt內容之後,並沒有將其新增的暫存區,所以建立版本的時候並沒有被提交

Git實戰

4.4、撤銷修改

4.4.1、繼續上面的操作,提示我們可以使用 git checkout -- 來丟棄工作區的改動。執行如下命令,發現工作區乾淨了,第二次的改動內容也沒了

Git實戰

4.4.2、我們繼續編輯code.txt,並在其中新增如下內容,並將其新增的暫存區

Git實戰

4.4.3、git同樣告訴我們,用命令git reset HEAD file可以把暫存區的修改撤銷掉,重新放回工作區

Git實戰

4.4.4、現在若想丟棄code.txt的修改,執行如下命令即可

Git實戰

現在,如果你不但改錯了東西,還從暫存區提交到了版本庫,則需要進行版本回退。

小結

場景1:當你改亂了工作區某個檔案的內容,想直接丟棄工作區的修改時,用命令git checkout -- file。

場景2:當你不但改亂了工作區某個檔案的內容,還新增到了暫存區時,想丟棄修改,分兩步,第一步用命令 git reset HEAD file,就回到了場景1,第二步按場景1操作。

場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節。

4.5、對比檔案的不同

對比工作區和某個版本中檔案的不同

4.5.1、繼續編輯檔案code.txt,在其中新增一行內容

Git實戰

4.5.2、現在要對比工作區中code.txt和HEAD版本中code.txt的不同。使用如下命令

Git實戰

4.5.3、使用如下命令丟棄工作區的改動

Git實戰

對比兩個版本間檔案的不同

4.5.4、現在要對比HEAD和HEAD^版本中code.txt的不同,使用如下命令

Git實戰

4.6、刪除檔案

4.6.1、我們把目錄中的code2.txt刪除

Git實戰

這個時候,git知道刪除了檔案,因此,工作區和版本庫就不一致了,git status命令會立刻提示哪些檔案被刪除了

Git實戰

4.6.2、現在你有兩個選擇,一是確實要從版本庫中刪除該檔案,那就用命令git rm刪掉,並且git commit

Git實戰

​ 另一種情況是刪錯了,可以直接使用git checkout – code2.txt,這樣檔案code2.txt又回來了

小結

​ 命令git rm用於刪除一個檔案。如果一個檔案已經被提交到版本庫,那麼你永遠不用擔心誤刪,但是要小心,你只能恢復檔案到最新版本,你會丟失最近一次提交後你修改的內容

5、分支管理

5.1、概念

​ 分支就是科幻電影裡面的平行宇宙,當你正在電腦前努力學習Git的時候,另一個你正在另一個平行宇宙裡努力學習SVN。

​ 如果兩個平行宇宙互不干擾,那對現在的你也沒啥影響。不過,在某個時間點,兩個平行宇宙合併了,結果,你既學會了git又學會了SVN!

Git實戰

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

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

5.2、建立與合併分支

​ git把我們之前每次提交的版本串成一條時間線,這條時間線就是一個分支。截止到目前只有一條時間線,在git裡,這個分支叫主分支,即master分支。HEAD嚴格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當前分支。

5.2.1、原理理解

​ (1) 一開始的時候,master分支是一條線,git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點:

Git實戰

​ 每次提交,master分支都會向前移動一步,這樣,隨著你不斷提交,master分支的線也越來越長

​ (2)當我們建立新的分支,例如dev時,git新建了一個指標叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:

Git實戰

​ git建立一個分支很快,因為除了增加一個dev指標,改變HEAD的指向,工作區的檔案都沒有任何變化。

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

Git實戰

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

Git實戰

​ git合併分支也很快,就改改指標,工作區內容也不變。

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

Git實戰

5.2.2、案例:

5.2.2.1、執行如下命令可以檢視當前有幾個分支並且看到在哪個分支下工作

Git實戰

5.2.2.2、下面建立一個分支dev並切換到其上進行工作

Git實戰

Git實戰

5.2.2.3、下面我們修改code.txt內容,在裡面新增一行,並進行提交

Git實戰

Git實戰

5.2.2.4、dev分支的工作完成,我們就可以切換回master分支

Git實戰

Git實戰

檢視code.txt,發現新增的內容沒有了。因為那個提交是在dev分支上,而master分支此刻的提交點並沒有變

5.2.2.5、現在,我們把dev分支的工作成果合併到master分支上

Git實戰

git merge命令用於合併指定分支到當前分支。合併後,再檢視code.txt的內容,就可以看到,和dev分支的最新提交是完全一樣的。

Git實戰

注意到上面的Fast-forward資訊,Git告訴我們,這次合併是“快進模式”,也就是直接把master指向dev的當前提交,所以合併速度非常快。

Git實戰

5.2.2.6、合併完成後,就可以放心地刪除dev分支了,刪除後,檢視branch,就只剩下master分支了

Git實戰

Git實戰

小結

​ 檢視分支:git branch

​ 建立分支:git branch

​ 切換分支:git checkout

​ 建立+切換分支:git checkout -b

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

​ 刪除分支:git branch -d

5.3、解決衝突

合併分支往往也不是一帆風順的

5.3.1、再建立一個新分支dev

Git實戰

5.3.2、修改code.txt內容,並進行提交

Git實戰

5.3.3、切換回master分支

Git實戰

5.3.4、在master的code.txt新增一行內容並進行提交

Git實戰

現在,master分支和dev分支各自都分別有新的提交,變成了這樣:

Git實戰

這種情況下,git無法執行“快速合併”,只能試圖把各自的修改合併起來,但這種合併就可能會有衝突。

5.3.5、執行如下命令嘗試將dev分支合併到master分支上來

Git實戰

git告訴我們,code.txt檔案存在衝突,必須手動解決衝突後再提交。

5.3.6、git status也可以告訴我們衝突的檔案

Git實戰

5.3.7、檢視code.txt的內容

Git實戰

5.3.8、git用<<<<<<<,=======,>>>>>>>標記出不同分支的內容,我們修改如下後儲存

Git實戰

5.3.9、再提交

Git實戰

5.3.10、現在,master分支和dev分支變成了下圖所示

Git實戰

5.3.11、用帶引數的git log也可以看到分支的合併情況

Git實戰

5.3.12、最後工作完成,可以刪除dev分支

Git實戰

5.4、分支管理策略

​ 通常,合併分支時,如果可能,git會用fast forward模式,但是有些快速合併不能成而且合併時沒有衝突,這個時候會合並之後並做一次新的提交。但這種模式下,刪除分支後,會丟掉分支資訊。

5.4.1、建立切換到dev分支下

Git實戰

5.4.2、新建一個檔案code3.txt編輯內容如下,並提交一個commit

Git實戰

5.4.3、切換回master分支,編輯code.txt並進行一個提交

Git實戰

5.4.4、合併dev分支的內容到master分支

Git實戰

5.4.5、出現如下提時,這是因為這次不能進行快速合併,所以git提示輸入合併說明資訊,輸入之後合併內容之後git會自動建立一次新的提交

Git實戰

Git實戰

5.4.6、使用分支命令檢視分支資訊

Git實戰

5.4.7、刪除dev分支

Git實戰

​ 如果要強制禁用fast forward模式,git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支資訊。

5.4.8、建立並切換到dev分支

Git實戰

5.4.9、修改code.txt內容,並提交一個commit

Git實戰

5.4.10、切換回master分支

Git實戰

5.4.11、準備合併dev分支,請注意--no-ff引數,表示禁用Fast forward

Git實戰

因為本次合併要建立一個新的commit,所以加上-m引數,把commit描述寫進去。

5.4.12、合併後,我們用git log看看分支歷史:

可以看到,不使用Fast forward模式,merge後就像這樣:

Git實戰

Git實戰

5.5、Bug分支

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

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

Git實戰

​ 並不是你不想提交,而是工作只進行到一半,還沒法提交,預計完成還需1天時間。但是,必須在兩個小時內修復該bug,怎麼辦?

5.5.2、git還提供了一個stash功能,可以把當前工作現場“儲藏”起來,等以後恢復現場後繼續工作:

Git實戰

5.5.3、首先確定要在哪個分支上修復bug,假定需要在master分支上修復,就從master建立臨時分支:

Git實戰

5.5.4、現在修復bug,把 the new line刪掉,然後提交

Git實戰

5.5.5、修復完成後,切換到master分支,並完成合並,最後刪除bug-001分支

Git實戰

5.5.6、現在bug-001修復完成,是時候接著回到dev分支幹活了!

Git實戰

5.5.7、工作區是乾淨的,剛才的工作現場存到哪去了?用git stash list命令看看:

Git實戰

現場還在,git把stash內容存在某個地方了,但是需要恢復一下

Git實戰

小結:

修復bug時,我們會通過建立新的bug分支進行修復,然後合併,最後刪除;

當手頭工作沒有完成時,先把工作現場git stash一下,然後去修復bug,修復後,再git stash pop,恢復工作現場。

6、使用github

6.1、建立倉庫

6.1.1、註冊github賬戶,登入後,點選"New respository‘’

Git實戰

6.1.2、在新頁面中,輸入專案的名稱,勾選'readme.md',點選'create repository'

Git實戰

6.1.3、新增成功後,轉到檔案列表頁面

Git實戰

6.2、新增ssh賬戶

6.2.1、點選賬戶頭像後的下拉三角,選擇'settings'

如果某臺機器需要與github上的倉庫互動,那麼就要把這臺機器的ssh公鑰新增到這個github賬戶上

Git實戰

點選'SSH and GPG keys',新增ssh公鑰。

Git實戰

6.2.2、在ubuntu的命令列中,回到使用者的主目錄下,編輯檔案.gitconfig,修改某臺機器的git配置

Git實戰

6.2.3、修改為註冊github時的郵箱,填寫使用者名稱

Git實戰

6.2.4、使用如下命令生成ssh金鑰

ssh-keygen -t rsa -C "郵箱地址"

Git實戰

6.2.5、進入主目錄下的.ssh檔案,下面有兩個檔案

公鑰為id_rsa.pub

私鑰為id_rsa

檢視公鑰內容,複製此內容

Git實戰

6.2.6、回到瀏覽器中,填寫標題,貼上公鑰

Git實戰

6.3、克隆專案

6.3.1、在瀏覽器中點選進入github首頁,再進入專案倉庫的頁面

Git實戰

6.3.2、複製git地址

Git實戰

6.3.3、克隆出錯

Git實戰

6.3.4、在命令列中複製倉庫中的內容

Git實戰

6.4、上傳分支

6.4.1、專案克隆到本地之後,執行如下命令建立分支smart

Git實戰

6.4.2、建立一個code.txt並提交一個版本

Git實戰

6.4.3、推送前github上檔案列表如下圖

Git實戰

6.4.4、推送前github上分支列表如下圖

Git實戰

6.4.5/推送分支,就是把該分支上的所有本地提交推送到遠端庫,推送時要指定本地分支,這樣,git就會把該分支推送到遠端庫對應的遠端分支上

git push origin 分支名稱
例:
git push origin smart

Git實戰

6.4.6、再去github網站上去看分支頁面,內容如下

Git實戰

Git實戰

6.5、將本地分支跟蹤伺服器分支

git branch --set-upstream-to=origin/遠端分支名稱 本地分支名稱
例:
git branch --set-upstream-to=origin/smart smart

Git實戰

6.6、從遠端分支上拉取程式碼

git pull orgin 分支名稱
例:
git pull orgin smart

使用上述命令會把遠端分支smart上的程式碼下載併合併到本地所在分支

7、 工作使用git

專案經理:

​ (1) 專案經理搭建專案的框架。

​ (2) 搭建完專案框架之後,專案經理把專案框架程式碼放到伺服器。

普通員工:

​ (1) 在自己的電腦上,生成ssh公鑰,然後把公鑰給專案經理,專案經理把它新增的伺服器上面。

​ (2) 專案經理會給每個組員的專案程式碼的地址,組員把程式碼下載到自己的電腦上。

​ (3) 建立本地的分支dev,在dev分支中進行每天的開發。

​ (4) 每一個員工開發完自己的程式碼之後,都需要將程式碼釋出遠端的dev分支上。

Master:使用者儲存釋出的專案程式碼。V1.0,V2.0

Dev:儲存開發過程中的程式碼。

相關文章