git-從入門到熟悉

2020-08-10 16:11:48


TortoiseGit資料夾和檔案圖示不顯示解決方法

Git歷史

同生活中的許多偉大事件一樣,Git 誕生於一個極富紛爭大舉創新的年代。Linux 內核開源專案有着爲數衆廣的參與者。絕大多數的 Linux 內核維護工作都花在了提交修補程式和儲存歸檔的繁瑣事務上(1991-2002年間)。到 2002 年,整個專案組開始啓用分佈式版本控制系統 BitKeeper 來管理和維護程式碼。

到 2005 年的時候,開發 BitKeeper 的商業公司同 Linux 內核開源社羣的合作關係結束,他們收回了免費使用 BitKeeper 的權力。這就迫使 Linux 開源社羣(特別是 Linux的締造者 Linus Torvalds )不得不吸取教訓,只有開發一套屬於自己的版本控制系統纔不至於重蹈覆轍。他們對新的系統訂了若幹目標:

• 速度

• 簡單的設計

• 對非線性開發模式的強力支援(允許上千個並行開發的分支)

• 完全分佈式

• 有能力高效管理類似 Linux 內核一樣的超大規模專案(速度和數據量)

image-20200809173109964

Git與svn對比

Svn

SVN是集中式版本控制系統,版本庫是集中放在中央伺服器的,而幹活的時候,用的都是自己的電腦,所以首先要從中央伺服器哪裏得到最新的版本,然後幹活,幹完後,需要把自己做完的活推播到中央伺服器。集中式版本控制系統是必須聯網才能 纔能工作,如果在區域網還可以,頻寬夠大,速度夠快,如果在網際網路下,如果網速慢的話,就鬱悶了。

下圖就是標準的集中式版本控制工具管理方式:

img

集中管理方式在一定程度上看到其他開發人員在幹什麼,而管理員也可以很輕鬆掌握每個人的開發許可權。

但是相較於其優點而言,集中式版本控制工具缺點很明顯:

  • 伺服器單點故障

  • 容錯性差

Git

Git是分佈式版本控制系統,那麼它就沒有中央伺服器的,每個人的電腦就是一個完整的版本庫,這樣,工作的時候就不需要聯網了,因爲版本都是在自己的電腦上。既然每個人的電腦都有一個完整的版本庫,那多個人如何共同作業呢?比如說自己在電腦上改了檔案A,其他人也在電腦上改了檔案A,這時,你們兩之間只需把各自的修改推播給對方,就可以互相看到對方的修改了。

下圖就是分佈式版本控制工具管理方式:

image-20200809173231400

git工作流程

一般工作流程如下:

  1. 從遠端倉庫中克隆 Git 資源作爲本地倉庫。

  2. 從本地倉庫中checkout程式碼然後進行程式碼修改

  3. 在提交前先將程式碼提交到暫存區。

  4. 提交修改。提交到本地倉庫。本地倉庫中儲存修改的各個歷史版本。

  5. 在修改完成後,需要和團隊成員共用程式碼時,可以將程式碼push到遠端倉庫。

下圖展示了 Git 的工作流程:

img

Git的安裝

最早Git是在Linux上開發的,很長一段時間內,Git也只能在Linux和Unix系統上跑。不過,慢慢地有人把它移植到了Windows上。現在,Git可以在Linux、Unix、Mac和Windows這幾大平臺上正常執行了。由於開發機大多數情況都是windows,所以本教學只講解windows下的git的安裝及使用。

軟體下載

下載地址:https://git-scm.com/download

image-20200809173928854

image-20200809173934257

參考資料中安裝包已經下載完畢,根據不同的操作系統選擇對應的安裝包。

軟體安裝

安裝git for windows

image-20200809173941703

image-20200809173946981

一路"下一步"使用預設選項即可。

安裝TortoiseGit

image-20200809173953817

image-20200809173957701

一路"下一步"使用預設選項即可。

預設選項下會啓動設定畫面:

image-20200809174035523

由於目前只有英文語言套件,預設即可繼續下一步。

設定git.exe,在4.2.1中已經安裝過git-for-windows了所以在此找到git.exe所在的目錄。

image-20200809174046695

設定開發者姓名及郵箱,每次提交程式碼時都會把此資訊包含到提交的資訊中。

image-20200809174053408

使用預設設定,點選"完成"按鈕完成設定。

完整完畢後在系統右鍵選單中會出現git的選單項。

image-20200809174623558

安裝中文語言套件

安裝中文語言套件並不是必選項。可以根據個人情況來選擇安裝。

image-20200809174652013

image-20200809174657294

直接"下一步"完整完畢。

語言套件安裝完畢後可以在TortoiseGit的設定中調整語言

image-20200809174703190

使用git管理檔案版本

建立版本庫

什麼是版本庫呢?版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄裏面的所有檔案都可以被Git管理起來,每個檔案的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以"還原"。由於git是分佈式版本管理工具,所以git在不需要聯網的情況下也具有完整的版本管理能力。

建立一個版本庫非常簡單,可以使用git bash也可以使用tortoiseGit。首先,選擇一個合適的地方,建立一個空目錄(D:\temp\git\repository)。

使用GitBash

在當前目錄中點選右鍵中選擇Git Bash來啓動。

image-20200809180003530

或者在開始選單中啓動。注意如果是從開始選單啓動的gitbash需要切換目錄到倉庫所在的目錄。

image-20200809180214512

建立倉庫執行命令:

$ git init

使用TortoiseGit

使用TortoiseGit時只需要在目錄中點選右鍵選單選擇"在這裏建立版本庫"

image-20200809180225228

image-20200809180231482

image-20200809180237156

版本庫建立成功,會在此目錄下建立一個.git的隱藏目錄,如下所示:

image-20200809180243217

在windows中如何顯示隱藏目錄隱藏目錄請自行百度o(╯□╰)o

概念:

版本庫:".git"目錄就是版本庫,將來檔案都需要儲存到版本庫中。

工作目錄:包含".git"目錄的目錄,也就是.git目錄的上一級目錄就是工作目錄。只有工作目錄中的檔案才能 纔能儲存到版本庫中。

新增檔案

新增檔案過程

在D:\temp\git\repository目錄下建立一個mytest.txt檔案

image-20200809180943952

image-20200809181027600

image-20200809181033401

文字檔案變爲帶"+"號的圖示:

image-20200809181714210

提交檔案:在mytest.txt上再次點選右鍵選擇"提交",此時將檔案儲存至版本庫中。

image-20200809181723209

image-20200809181730529

image-20200809181736733

工作區和暫存區

Git和其他版本控制系統如SVN的一個不同之處就是有暫存區的概念。

什麼是工作區(Working Directory)?

工作區就是你在電腦裡能看到的目錄,比如我的reporstory資料夾就是一個工作區。

有的同學可能會說repository不是版本庫嗎怎麼是工作區了?其實repository目錄是工作區,在這個目錄中的".git"隱藏資料夾纔是版本庫。這回概念清晰了吧。

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

如下圖所示:

img

分支和HEAD的概念我們稍後再講。前面講了我們把檔案往Git版本庫裡新增的時候,是分兩步執行的:

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

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

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

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

修改檔案

提交修改

被版本庫管理的檔案不可避免的要發生修改,此時只需要直接對檔案修改即可。修改完畢後需要將檔案的修改提交到版本庫。

在mytest.txt檔案上點選右鍵,然後選擇"提交"
image-20200809181947675

image-20200809182046885

image-20200809182042573

檢視修改歷史

在開發過程中可能會經常檢視程式碼的修改歷史,或者叫做修改日誌。來檢視某個版本是誰修改的,什麼時間修改的,修改了哪些內容。

可以在檔案上點選右鍵選擇"顯示日誌"來檢視檔案的修改歷史。

image-20200809182058481

image-20200809182103836

差異比較

當檔案內容修改後,需要和修改之前對比一下修改了哪些內容此時可以使用"比較差異功能"

image-20200809182112674

image-20200809182117305

還原修改

當檔案修改後不想把修改的內容提交,還想還原到未修改之前的狀態。此時可以使用"還原"功能

image-20200809182521697

image-20200809182527433

image-20200809182532814

注意:此操作會復原所有未提交的修改,所以當做還原操作是需要慎重慎重!!!

刪除檔案

需要刪除無用的檔案時可以使用git提供的刪除功能直接將檔案從版本庫中刪除。

image-20200809182620316

案例:將java工程提交到版本庫

第一步:將參考資料中的java工程project-test複製到工作目錄中

image-20200809185038741

第二步:將工程新增到暫存區。

image-20200809185044007

image-20200809185056729

image-20200809185103255

點選確定完成暫存區新增。

三、忽略檔案或資料夾

在此工程中,並不是所有檔案都需要儲存到版本庫中的例如"bin"目錄及目錄下的檔案就可以忽略。好在Git考慮到了大家的感受,這個問題解決起來也很簡單,在Git工作區的根目錄下建立一個特殊的.gitignore檔案,然後把要忽略的檔名填進去,Git就會自動忽略這些檔案。

如果使用TortoiseGit的話可以使用選單項直接進行忽略。

image-20200809185138998

image-20200809185145939

選擇保留本地檔案。完成後在此資料夾內會多出一個.gitignore檔案,這個檔案就是檔案忽略檔案,當然也可以手工編輯。其中的內容就是把bin目錄忽略掉。

image-20200809185303288

  1. 提交程式碼

    將程式碼新增到master分支上,其中.gitignore檔案也需要新增到暫存區,然後提交到版本庫。

忽略檔案語法規範

空行或是以 # 開頭的行即註釋行將被忽略。

可以在前面新增正斜槓 / 來避免遞回,下面 下麪的例子中可以很明白的看出來與下一條的區別。

可以在後面新增正斜槓 / 來忽略資料夾,例如 build/ 即忽略build資料夾。

可以使用 ! 來否定忽略,即比如在前面用了 *.apk ,然後使用 !a.apk ,則這個a.apk不會被忽略。

* 用來匹配零個或多個字元,如 *.[oa] 忽略所有以".o"或".a"結尾, *~ 忽略所有以 ~ 結尾的檔案(這種檔案通常被許多編輯器標記爲臨時檔案); [] 用來匹配括號內的任一字元,如 [abc] ,也可以在括號內加連線符,如 [0-9] 匹配0至9的數; ? 用來匹配單個字元。

看了這麼多,還是應該來個栗子:

# 忽略 .a 檔案

*.a

# 但否定忽略 lib.a, 儘管已經在前面忽略了 .a 檔案

!lib.a

# 僅在當前目錄下忽略 TODO 檔案, 但不包括子目錄下的 subdir/TODO

/TODO

# 忽略 build/ 資料夾下的所有檔案

build/

# 忽略 doc/notes.txt, 不包括 doc/server/arch.txt

doc/*.txt

# 忽略所有的 .pdf 檔案 在 doc/ directory 下的

doc/**/*.pdf

遠端倉庫

新增遠端庫

現在我們已經在本地建立了一個Git倉庫,又想讓其他人來共同作業開發,此時就可以把本地倉庫同步到遠端倉庫,同時還增加了本地倉庫的一個備份。

常用的遠端倉庫就是github:https://github.com/,接下來我們演示如何將原生代碼同步到github。

在github上建立倉庫

首先你得在github上建立一個賬號,這個就不演示了。然後在github上建立一個倉庫:

[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-zGGCEPQ7-1597047026418)(git%E6%95%99%E6%A1%88-v2.assets/20200809222234.png)]

image-20200809222339810

點選"create repository"按鈕倉庫就建立成功了。

Github支援兩種同步方式"https"和"ssh"。如果使用https很簡單基本不需要設定就可以使用,但是每次提交程式碼和下載程式碼時都需要輸入使用者名稱和密碼。如果使用ssh方式就需要用戶端先生成一個金鑰對,即一個公鑰一個私鑰。然後還需要把公鑰放到githib的伺服器上。這兩種方式在實際開發中都用應用,所以我們都需要掌握。接下來我們先看ssh方式。

ssh協定

什麼是ssh?

SSH 爲 Secure Shell(安全外殼協定)的縮寫,由 IETF 的網路小組(Network Working Group)所制定。SSH 是目前較可靠,專爲遠程登錄對談和其他網路服務提供安全性的協定。利用 SSH 協定可以有效防止遠端管理過程中的資訊泄露問題。

基於密匙的安全驗證

使用ssh協定通訊時,推薦使用基於金鑰的驗證方式。你必須爲自己建立一對密匙,並把公用密匙放在需要存取的伺服器上。如果你要連線到SSH伺服器上,用戶端軟體就會向伺服器發出請求,請求用你的密匙進行安全驗證。伺服器收到請求之後,先在該伺服器上你的主目錄下尋找你的公用密匙,然後把它和你發送過來的公用密匙進行比較。如果兩個密匙一致,伺服器就用公用密匙加密"質詢"(challenge)並把它發送給用戶端軟體。用戶端軟體收到"質詢"之後就可以用你的私人密匙解密再把它發送給伺服器。

ssh金鑰生成

在windows下我們可以使用 Git Bash.exe來生成金鑰,可以通過開始選單或者右鍵選單開啓Git Bash

image-20200809222414632 image-20200809222442272

git bash 執行命令,生命公鑰和私鑰

命令: ssh-keygen -t rsa

image-20200809222713570

執行命令完成後,在window本地使用者.ssh目錄C:\Users\使用者名稱\.ssh下面 下麪生成如下名稱的公鑰和私鑰:

image-20200809222724731

ssh金鑰設定

金鑰生成後需要在github上設定金鑰本地纔可以順利存取。

image-20200809222731388

image-20200809222738567

在key部分將id_rsa.pub檔案內容新增進去,然後點選"Add SSH key"按鈕完成設定。

同步到遠端倉庫

同步到遠端倉庫可以使用git bash也可以使用tortoiseGit

使用git bash

在倉庫所在的目錄(D:\temp\git\repository)點選右鍵選擇"Git Bash Here",啓動git bash程式。

image-20200809223327222

然後在git bash中執行如下語句:

git remote add origin [email protected]:sublun/mytest.git

git push -u origin master

注意:其中黃色字型部分(sublun)需要替換成個人的使用者名稱。

如何出現如下錯誤:

image-20200809223352193

可以先執行如下命令,然後再執行上面的命令

$ git remote rm origin

image-20200809223413735

使用TortoiseGit同步

一、由於TortoiseGit使用的ssh工具是"PuTTY"git Bash使用的ssh工具是"openSSH",如果想讓TortoiseGit也使用剛纔生成的金鑰可以做如下設定:

image-20200809223437674

image-20200809223446832

Url:遠端倉庫的地址

推播URL:也是相同的

Putty金鑰:選擇剛纔生成的金鑰中的私鑰

  1. 同步。在本地倉庫的資料夾中單擊右鍵,選擇"Git同步"

    {width=「5.7625in」 height=「4.354861111111111in」}

    image-20200809225055573

從遠端倉庫克隆

克隆遠端倉庫也就是從遠端把倉庫複製一份到本地,克隆後會建立一個新的本地倉庫。選擇一個任意部署倉庫的目錄,然後克隆遠端倉庫。

使用git bash:

$ git clone [email protected]:sublun/mytest.git

使用TortoiseGit:

在任意目錄點選右鍵:

image-20200810142100256

image-20200810142105025

image-20200810142112078

從遠端倉庫取程式碼

Git中從遠端的分支獲取最新的版本到本地有這樣2個命令:

  1. git fetch:相當於是從遠端獲取最新版本到本地,不會自動merge(合併程式碼)

  2. git pull:相當於是從遠端獲取最新版本並merge到本地

    上述命令其實相當於git fetch 和 git merge

    在實際使用中,git fetch更安全一些

    因爲在merge前,我們可以檢視更新情況,然後再決定是否合併

    如果使用TortoiseGit的話可以從右鍵選單中點選"拉取"(pull)或者"獲取"(fetch)

    image-20200810142142212

建立合併分支

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

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

img

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

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

img

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

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

img

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

img

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

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

img

使用TortoiseGit實現分支管理

使用TortoiseGit管理分支就很簡單了。

建立分支

在本地倉庫資料夾中點選右鍵,然後從選單中選擇"建立分支":

image-20200810142802119

如果想建立完畢後直接切換到新分支可以勾選"切換到新分支"選項或者從選單中選擇"切換/檢出"來切換分支:

image-20200810142808078

合併分支

分支切換到dev後就可以對工作區的檔案進行修改,然後提交到dev分支原理的master分支不受影響。例如我們修改mytest.txt中的內容,然後提交到dev分支。

image-20200810142813874

image-20200810142819718

切換到master分支後還是原理的內容:

image-20200810142825126

將dev分支的內容合併到master分支,當前分支爲master。從右鍵選單中選擇"合併":image-20200810142839202

再檢視mytest.txt的內容就已經更新了:

image-20200810142850381

解決衝突

兩個分支中編輯的內容都是相互獨立互不幹 不乾擾的,那麼如果在兩個分支中都對同一個檔案進行編輯,然後再合併,就有可能會出現衝突。

例如在master分支中對mytest.txt進行編輯:

image-20200810144746993

然後提交到版本庫。

image-20200810144754566

切換到dev分支,對mytest.txt進行編輯:

image-20200810144801473

image-20200810144808300

最後進行分支合併,例如將dev分支合併到master分支。需要先切換到master分支然後進行分支合併。

image-20200810144830819

出現版本衝突。

image-20200810144841498

衝突需要手動解決。

image-20200810144857904

在衝突檔案上單機右鍵選擇「解決衝突」選單項:

image-20200810144915682

image-20200810144921412

把衝突解決完畢的檔案提交到版本庫就可以了。

在IntelliJ IDEA中使用git

在Idea中設定git

安裝好IntelliJ IDEA後,如果Git安裝在預設路徑下,那麼idea會自動找到git的位置,如果更改了Git的安裝位置則需要手動設定下Git的路徑。

選擇File→Settings開啓設定視窗,找到Version Control下的git選項:

image-20200810145212500

選擇git的安裝目錄後可以點選「Test」按鈕測試是否正確設定

image-20200810144952400

將工程新增至git

1)在idea中建立一個工程,例如建立一個java工程,名稱爲idea-git-test,如下圖所示:

image-20200810145022331

  1. 建立本地倉庫

    在選單中選擇"vcs"→Import into Version Control→Create Git Repository…

    image-20200810145344353

    image-20200810145033675選擇工程所在的上級目錄。本例中應該選擇idea-projects目錄,然後點選"OK"按鈕,在工程的上級目錄建立本地倉庫,那麼idea-projects目錄就是本地倉庫的工作目錄,此目錄中的工程就可以新增到本地倉庫中。也就是可以把idea-git-test工程新增到本地倉庫中。

    選擇之後在工具列上就多出了git相關工具按鈕:

  2. 將工程新增至本地倉庫

    直接點選image-20200810145041521

    commit按鈕,將工程提交至本地倉庫。

    image-20200810145602684

    然後點選"commit"按鈕,將工程新增至本地倉庫。

  3. 推播到遠端

    在github上建立一個倉庫然後將本地倉庫推播到遠端。

    在工程上點選右鍵,選擇git→Repository→push,

    或者在選單中選擇vcs→git→push

    image-20200810145110386

    image-20200810145116163

    點選"Define remote"鏈接,設定https形式的URL,git形式的無法通過。然後點選OK

    image-20200810145122232

    image-20200810145128246

    點選"push"按鈕就講本地倉庫推播到遠端,如果是第一次設定推播需要輸入github的使用者名稱和密碼。

一些bug

image-20200810150334243

csdn鏈接

image-20200810150855949

csdn鏈接

image-20200810150734856

csdn鏈接

從遠端倉庫克隆

關閉工程後,在idea的歡迎頁上有"Check out from version control"下拉框,選擇git

image-20200810151321797

image-20200810151329722

此處仍然推薦使用htts形式的url,點選"test"按鈕後顯示連線成功。

點選OK按鈕後根據提示將遠端倉庫克隆下來,然後倒入到idea中。

從伺服器端拉取程式碼

如果需要從伺服器端同步程式碼可以使用工具條中的"update"按鈕

image-20200810151337494