同生活中的許多偉大事件一樣,Git 誕生於一個極富紛爭大舉創新的年代。Linux 內核開源專案有着爲數衆廣的參與者。絕大多數的 Linux 內核維護工作都花在了提交修補程式和儲存歸檔的繁瑣事務上(1991-2002年間)。到 2002 年,整個專案組開始啓用分佈式版本控制系統 BitKeeper 來管理和維護程式碼。
到 2005 年的時候,開發 BitKeeper 的商業公司同 Linux 內核開源社羣的合作關係結束,他們收回了免費使用 BitKeeper 的權力。這就迫使 Linux 開源社羣(特別是 Linux的締造者 Linus Torvalds )不得不吸取教訓,只有開發一套屬於自己的版本控制系統纔不至於重蹈覆轍。他們對新的系統訂了若幹目標:
• 速度
• 簡單的設計
• 對非線性開發模式的強力支援(允許上千個並行開發的分支)
• 完全分佈式
• 有能力高效管理類似 Linux 內核一樣的超大規模專案(速度和數據量)
SVN是集中式版本控制系統,版本庫是集中放在中央伺服器的,而幹活的時候,用的都是自己的電腦,所以首先要從中央伺服器哪裏得到最新的版本,然後幹活,幹完後,需要把自己做完的活推播到中央伺服器。集中式版本控制系統是必須聯網才能 纔能工作,如果在區域網還可以,頻寬夠大,速度夠快,如果在網際網路下,如果網速慢的話,就鬱悶了。
下圖就是標準的集中式版本控制工具管理方式:
集中管理方式在一定程度上看到其他開發人員在幹什麼,而管理員也可以很輕鬆掌握每個人的開發許可權。
但是相較於其優點而言,集中式版本控制工具缺點很明顯:
伺服器單點故障
容錯性差
Git是分佈式版本控制系統,那麼它就沒有中央伺服器的,每個人的電腦就是一個完整的版本庫,這樣,工作的時候就不需要聯網了,因爲版本都是在自己的電腦上。既然每個人的電腦都有一個完整的版本庫,那多個人如何共同作業呢?比如說自己在電腦上改了檔案A,其他人也在電腦上改了檔案A,這時,你們兩之間只需把各自的修改推播給對方,就可以互相看到對方的修改了。
下圖就是分佈式版本控制工具管理方式:
一般工作流程如下:
從遠端倉庫中克隆 Git 資源作爲本地倉庫。
從本地倉庫中checkout程式碼然後進行程式碼修改
在提交前先將程式碼提交到暫存區。
提交修改。提交到本地倉庫。本地倉庫中儲存修改的各個歷史版本。
在修改完成後,需要和團隊成員共用程式碼時,可以將程式碼push到遠端倉庫。
下圖展示了 Git 的工作流程:
最早Git是在Linux上開發的,很長一段時間內,Git也只能在Linux和Unix系統上跑。不過,慢慢地有人把它移植到了Windows上。現在,Git可以在Linux、Unix、Mac和Windows這幾大平臺上正常執行了。由於開發機大多數情況都是windows,所以本教學只講解windows下的git的安裝及使用。
下載地址:https://git-scm.com/download
參考資料中安裝包已經下載完畢,根據不同的操作系統選擇對應的安裝包。
一路"下一步"使用預設選項即可。
一路"下一步"使用預設選項即可。
預設選項下會啓動設定畫面:
由於目前只有英文語言套件,預設即可繼續下一步。
設定git.exe,在4.2.1中已經安裝過git-for-windows了所以在此找到git.exe所在的目錄。
設定開發者姓名及郵箱,每次提交程式碼時都會把此資訊包含到提交的資訊中。
使用預設設定,點選"完成"按鈕完成設定。
完整完畢後在系統右鍵選單中會出現git的選單項。
安裝中文語言套件並不是必選項。可以根據個人情況來選擇安裝。
直接"下一步"完整完畢。
語言套件安裝完畢後可以在TortoiseGit的設定中調整語言
什麼是版本庫呢?版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄裏面的所有檔案都可以被Git管理起來,每個檔案的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以"還原"。由於git是分佈式版本管理工具,所以git在不需要聯網的情況下也具有完整的版本管理能力。
建立一個版本庫非常簡單,可以使用git bash也可以使用tortoiseGit。首先,選擇一個合適的地方,建立一個空目錄(D:\temp\git\repository)。
在當前目錄中點選右鍵中選擇Git Bash來啓動。
或者在開始選單中啓動。注意如果是從開始選單啓動的gitbash需要切換目錄到倉庫所在的目錄。
建立倉庫執行命令:
$ git init
使用TortoiseGit時只需要在目錄中點選右鍵選單選擇"在這裏建立版本庫"
版本庫建立成功,會在此目錄下建立一個.git的隱藏目錄,如下所示:
在windows中如何顯示隱藏目錄隱藏目錄請自行百度o(╯□╰)o
概念:
版本庫:".git"目錄就是版本庫,將來檔案都需要儲存到版本庫中。
工作目錄:包含".git"目錄的目錄,也就是.git目錄的上一級目錄就是工作目錄。只有工作目錄中的檔案才能 纔能儲存到版本庫中。
在D:\temp\git\repository目錄下建立一個mytest.txt檔案
文字檔案變爲帶"+"號的圖示:
提交檔案:在mytest.txt上再次點選右鍵選擇"提交",此時將檔案儲存至版本庫中。
Git和其他版本控制系統如SVN的一個不同之處就是有暫存區的概念。
什麼是工作區(Working Directory)?
工作區就是你在電腦裡能看到的目錄,比如我的reporstory資料夾就是一個工作區。
有的同學可能會說repository不是版本庫嗎怎麼是工作區了?其實repository目錄是工作區,在這個目錄中的".git"隱藏資料夾纔是版本庫。這回概念清晰了吧。
Git的版本庫裡存了很多東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲我們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。
如下圖所示:
分支和HEAD的概念我們稍後再講。前面講了我們把檔案往Git版本庫裡新增的時候,是分兩步執行的:
第一步是用git add把檔案新增進去,實際上就是把檔案修改新增到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的所有內容提交到當前分支。
因爲我們建立Git版本庫時,Git自動爲我們建立了唯一一個master分支,所以,現在,git commit就是往master分支上提交更改。
你可以簡單理解爲,需要提交的檔案修改通通放到暫存區,然後,一次性提交暫存區的所有修改。
被版本庫管理的檔案不可避免的要發生修改,此時只需要直接對檔案修改即可。修改完畢後需要將檔案的修改提交到版本庫。
在mytest.txt檔案上點選右鍵,然後選擇"提交"
在開發過程中可能會經常檢視程式碼的修改歷史,或者叫做修改日誌。來檢視某個版本是誰修改的,什麼時間修改的,修改了哪些內容。
可以在檔案上點選右鍵選擇"顯示日誌"來檢視檔案的修改歷史。
當檔案內容修改後,需要和修改之前對比一下修改了哪些內容此時可以使用"比較差異功能"
當檔案修改後不想把修改的內容提交,還想還原到未修改之前的狀態。此時可以使用"還原"功能
注意:此操作會復原所有未提交的修改,所以當做還原操作是需要慎重慎重!!!
需要刪除無用的檔案時可以使用git提供的刪除功能直接將檔案從版本庫中刪除。
第一步:將參考資料中的java工程project-test複製到工作目錄中
第二步:將工程新增到暫存區。
點選確定完成暫存區新增。
三、忽略檔案或資料夾
在此工程中,並不是所有檔案都需要儲存到版本庫中的例如"bin"目錄及目錄下的檔案就可以忽略。好在Git考慮到了大家的感受,這個問題解決起來也很簡單,在Git工作區的根目錄下建立一個特殊的.gitignore檔案,然後把要忽略的檔名填進去,Git就會自動忽略這些檔案。
如果使用TortoiseGit的話可以使用選單項直接進行忽略。
選擇保留本地檔案。完成後在此資料夾內會多出一個.gitignore檔案,這個檔案就是檔案忽略檔案,當然也可以手工編輯。其中的內容就是把bin目錄忽略掉。
提交程式碼
將程式碼新增到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上建立一個倉庫:
[外連圖片轉存失敗,源站可能有防盜鏈機制 機製,建議將圖片儲存下來直接上傳(img-zGGCEPQ7-1597047026418)(git%E6%95%99%E6%A1%88-v2.assets/20200809222234.png)]
點選"create repository"按鈕倉庫就建立成功了。
Github支援兩種同步方式"https"和"ssh"。如果使用https很簡單基本不需要設定就可以使用,但是每次提交程式碼和下載程式碼時都需要輸入使用者名稱和密碼。如果使用ssh方式就需要用戶端先生成一個金鑰對,即一個公鑰一個私鑰。然後還需要把公鑰放到githib的伺服器上。這兩種方式在實際開發中都用應用,所以我們都需要掌握。接下來我們先看ssh方式。
SSH 爲 Secure Shell(安全外殼協定)的縮寫,由 IETF 的網路小組(Network Working Group)所制定。SSH 是目前較可靠,專爲遠程登錄對談和其他網路服務提供安全性的協定。利用 SSH 協定可以有效防止遠端管理過程中的資訊泄露問題。
使用ssh協定通訊時,推薦使用基於金鑰的驗證方式。你必須爲自己建立一對密匙,並把公用密匙放在需要存取的伺服器上。如果你要連線到SSH伺服器上,用戶端軟體就會向伺服器發出請求,請求用你的密匙進行安全驗證。伺服器收到請求之後,先在該伺服器上你的主目錄下尋找你的公用密匙,然後把它和你發送過來的公用密匙進行比較。如果兩個密匙一致,伺服器就用公用密匙加密"質詢"(challenge)並把它發送給用戶端軟體。用戶端軟體收到"質詢"之後就可以用你的私人密匙解密再把它發送給伺服器。
在windows下我們可以使用 Git Bash.exe來生成金鑰,可以通過開始選單或者右鍵選單開啓Git Bash
git bash 執行命令,生命公鑰和私鑰
命令: ssh-keygen -t rsa
執行命令完成後,在window本地使用者.ssh目錄C:\Users\使用者名稱\.ssh下面 下麪生成如下名稱的公鑰和私鑰:
金鑰生成後需要在github上設定金鑰本地纔可以順利存取。
在key部分將id_rsa.pub檔案內容新增進去,然後點選"Add SSH key"按鈕完成設定。
同步到遠端倉庫可以使用git bash也可以使用tortoiseGit
在倉庫所在的目錄(D:\temp\git\repository)點選右鍵選擇"Git Bash Here",啓動git bash程式。
然後在git bash中執行如下語句:
git remote add origin [email protected]:sublun/mytest.git
git push -u origin master
注意:其中黃色字型部分(sublun)需要替換成個人的使用者名稱。
如何出現如下錯誤:
可以先執行如下命令,然後再執行上面的命令
$ git remote rm origin
一、由於TortoiseGit使用的ssh工具是"PuTTY"git Bash使用的ssh工具是"openSSH",如果想讓TortoiseGit也使用剛纔生成的金鑰可以做如下設定:
Url:遠端倉庫的地址
推播URL:也是相同的
Putty金鑰:選擇剛纔生成的金鑰中的私鑰
同步。在本地倉庫的資料夾中單擊右鍵,選擇"Git同步"
{width=「5.7625in」 height=「4.354861111111111in」}
克隆遠端倉庫也就是從遠端把倉庫複製一份到本地,克隆後會建立一個新的本地倉庫。選擇一個任意部署倉庫的目錄,然後克隆遠端倉庫。
$ git clone [email protected]:sublun/mytest.git
在任意目錄點選右鍵:
Git中從遠端的分支獲取最新的版本到本地有這樣2個命令:
git fetch:相當於是從遠端獲取最新版本到本地,不會自動merge(合併程式碼)
git pull:相當於是從遠端獲取最新版本並merge到本地
上述命令其實相當於git fetch 和 git merge
在實際使用中,git fetch更安全一些
因爲在merge前,我們可以檢視更新情況,然後再決定是否合併
如果使用TortoiseGit的話可以從右鍵選單中點選"拉取"(pull)或者"獲取"(fetch)
在我們每次的提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,只有一條時間線,在Git裡,這個分支叫主分支,即master分支。HEAD指針嚴格來說不是指向提交,而是指向master,master纔是指向提交的,所以,HEAD指向的就是當前分支。
一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當前分支,以及當前分支的提交點:
每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也越來越長。
當我們建立新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上:
你看,Git建立一個分支很快,因爲除了增加一個dev指針,改改HEAD的指向,工作區的檔案都沒有任何變化!
不過,從現在開始,對工作區的修改和提交就是針對dev分支了,比如新提交一次後,dev指針往前移動一步,而master指針不變:
假如我們在dev上的工作完成了,就可以把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合併:
所以Git合併分支也很快!就改改指針,工作區內容也不變!
合併完分支後,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉後,我們就剩下了一條master分支:
使用TortoiseGit管理分支就很簡單了。
在本地倉庫資料夾中點選右鍵,然後從選單中選擇"建立分支":
如果想建立完畢後直接切換到新分支可以勾選"切換到新分支"選項或者從選單中選擇"切換/檢出"來切換分支:
分支切換到dev後就可以對工作區的檔案進行修改,然後提交到dev分支原理的master分支不受影響。例如我們修改mytest.txt中的內容,然後提交到dev分支。
切換到master分支後還是原理的內容:
將dev分支的內容合併到master分支,當前分支爲master。從右鍵選單中選擇"合併":
再檢視mytest.txt的內容就已經更新了:
兩個分支中編輯的內容都是相互獨立互不幹 不乾擾的,那麼如果在兩個分支中都對同一個檔案進行編輯,然後再合併,就有可能會出現衝突。
例如在master分支中對mytest.txt進行編輯:
然後提交到版本庫。
切換到dev分支,對mytest.txt進行編輯:
最後進行分支合併,例如將dev分支合併到master分支。需要先切換到master分支然後進行分支合併。
出現版本衝突。
衝突需要手動解決。
在衝突檔案上單機右鍵選擇「解決衝突」選單項:
把衝突解決完畢的檔案提交到版本庫就可以了。
安裝好IntelliJ IDEA後,如果Git安裝在預設路徑下,那麼idea會自動找到git的位置,如果更改了Git的安裝位置則需要手動設定下Git的路徑。
選擇File→Settings開啓設定視窗,找到Version Control下的git選項:
選擇git的安裝目錄後可以點選「Test」按鈕測試是否正確設定
1)在idea中建立一個工程,例如建立一個java工程,名稱爲idea-git-test,如下圖所示:
建立本地倉庫
在選單中選擇"vcs"→Import into Version Control→Create Git Repository…
選擇工程所在的上級目錄。本例中應該選擇idea-projects目錄,然後點選"OK"按鈕,在工程的上級目錄建立本地倉庫,那麼idea-projects目錄就是本地倉庫的工作目錄,此目錄中的工程就可以新增到本地倉庫中。也就是可以把idea-git-test工程新增到本地倉庫中。
選擇之後在工具列上就多出了git相關工具按鈕:
將工程新增至本地倉庫
直接點選
commit按鈕,將工程提交至本地倉庫。
然後點選"commit"按鈕,將工程新增至本地倉庫。
推播到遠端
在github上建立一個倉庫然後將本地倉庫推播到遠端。
在工程上點選右鍵,選擇git→Repository→push,
或者在選單中選擇vcs→git→push
點選"Define remote"鏈接,設定https形式的URL,git形式的無法通過。然後點選OK
點選"push"按鈕就講本地倉庫推播到遠端,如果是第一次設定推播需要輸入github的使用者名稱和密碼。
關閉工程後,在idea的歡迎頁上有"Check out from version control"下拉框,選擇git
此處仍然推薦使用htts形式的url,點選"test"按鈕後顯示連線成功。
點選OK按鈕後根據提示將遠端倉庫克隆下來,然後倒入到idea中。
如果需要從伺服器端同步程式碼可以使用工具條中的"update"按鈕