0 前言
最近開始使用GitHub來管理自己的代碼,但是一直對Git系統的工作原理一直比較懵逼,除了無腦記了一些指令和GUI操作方法外,對內部的工作原理,完全一竅不通。終於抽個時間來吧Git系統的工作原理給梳理一遍了,學到了很多東西。我不是很喜歡直接轉載別人的帖子,更不喜歡直接抄襲,我比較喜歡吸收消化之後,再以自己的形式展現出來,這樣能夠督促自己去學習和掌握,因此,這裏總結了一下幾位大神的帖子,權當做自己的學習筆記吧。
1 Git 系統
1.1 什麼是Git?
git是一個開源的分佈式版本控制系統,用以有效、高速的處理從很小到非常大的項目版本管理。git是個工具,在Linux裏面也就類似gcc這樣的工具一樣,是一個shell命令。git是 Linus Torvalds爲了幫助管理Linux內核開發而開發的一個開放源碼的版本控制軟件。
1.2 基本概念和原理
工作區(WorkSpace)
工作區就是我們調試代碼的地方,比如各種IDE和編輯器,是我們更新代碼的“第一現場”。我們在自己的IDE上調試代碼,然後把自己寫好的代碼提交(commit)到本地或遠程Git系統上,這個調試代碼的過程就是對工作區的操作。比如我們的Visual Studio就可以看做一個工作區,這裏我新建了一個項目CppLearning,方便下面舉例。
暫存區(Index/Stage)
每個配置了git系統的項目或者工程當中,都會有一個
.git
文件夾,該文件夾中存放了git系統對於該項目的所有相關文件。 (舉個栗子,嗯)
.git
目錄下的index
文件,暫存區會記錄git add
指令添加的相關信息(文件名、大小等),而不保存文件實體,通過id指向每個文件實體,可以用git status
指令查看暫存區的狀態。暫存區標記了當前的工作區中,哪些內容是被git
管理的。這也標誌着,我們的代碼開始步入管理。
(嗯,還是以這個CppLearning的Demo進行舉例,我寫了一個快速排序算法,然後提交更新,提示Source.cpp文件被修改)
代碼倉(Repository)
在執行了
git commit
指令之後,最新的代碼會更新到本地代碼倉,本地代碼倉對這次提交的修改進行記錄,記錄“一個新的版本”。而沒有被提交的代碼,則意味着在暫存區中“待命”,可能最終並沒有被真正的記錄。 遠程庫(Remote)
如果整個項目的開發者,只有你一個人的話,或許你的代碼管理,並不需要什麼遠程庫。但一旦你需要和其他開發者協作開發,尤其是當你需要代碼交互的時候,遠程庫的存在就顯得至關重要。總的來說,遠程庫是整個分佈式系統的核心,在執行了
git push
指令之後,它把位於不同地點的代碼進行記錄和同步。
Git基本操作流程
下面以一張時序圖重新描述一下上述過程,基本上涵蓋了我們常用的git系統的基本操作。
2 GitHub以及常用術語
2.1 什麼是GitHub?
GitHub是一個面向開源及私有軟件項目的託管平臺,因爲只支持git作爲唯一的版本庫格式進行託管,故名GitHub。其實說白了,就是一個在線的git系統,或者說,目前世界上做的最好的、影響力最大的、開源的、git在線託管系統。
2.2 常用術語
記得第一次用GitHub的時候,被一堆名詞搞暈了,不知道是什麼意思,但永久了之後,懂了這些“行話”,發現其實也沒有這麼難理解。下面結合自己的理解,記錄一下GitHub的一些常見名詞。
Repository,即“代碼倉”,我們所管理的代碼就位於代碼倉中,但這裏的代碼倉是遠程的,而不是本地的。GitHub系統中,以代碼倉爲單位進行管理。注意,這裏所有的代碼都是公開的(GitHub還有代碼社交網站之稱),私有代碼倉需要額外付費。
Issues,即“問題”,我們的代碼開源之後,別人可能會覺得哪裏有問題,這裏就可以提出一個Issue,問題解決之後,可以把這些Issue關閉。
Star,即“點贊”,此外,所有點過讚的代碼倉,都會記錄在你自己的Star中,以便查閱。“Star”數量過高,說明這是一個十分有影響力的項目(比如Qt、OpenCV這些大佬)
Fork,即“拉取(分支)”,如果我們對別人的項目感興趣,想基於此進行開發,就可以Fork到自己的系統上來進行代碼管理,此時,拉取到自己賬號上的版本是獨立於源版本的,不會相互影響。本質上,Fork到自己賬戶上的代碼倉,即表明這個項目“不是我的”,又方便自己能夠對別人的項目進行開發。
Pull Request,即“提交請求”,上面說過,拉取到自己系統的代碼是獨立的,但如果自己開發出了更好的功能,想改變原始代碼倉的代碼,就需要提交請求了,發起請求之後,對方會收到提示,以及詳盡的代碼更新細節。
Merge,即“合併”,當有人對你的項目發起了“Pull Request”,如果你覺得還不錯,想更新原始代碼倉,那麼就需要這個merge的功能了。
Watch,即“關注”,當我們Watch了一個項目之後,該項目如果有更新,會收到相關通知。可以給自己喜歡的項目進行“追蹤”。
3 常用指令
add
最常用指令之一,把工作區修改的內容提交到暫存區,交由git管理。
指令 | 備註 |
---|---|
git add . |
添加當前目錄所有文件到暫存區(注意add後面有個.) |
git add [dir] |
添加指定目錄到暫存區,包括子目錄 |
git add [file] |
添加指定文件到暫存區 |
commit
最常用指令之一,把暫存區的內容提交到本地倉,並使得當前分支的HEAD指向當前提交的分支點
指令 | 備註 |
---|---|
git commit -m [message] |
提交暫存區到本地倉,message表示提交說明 |
git commit --amend -m [message] |
使用一次新的commit,替代上一次提交 |
branch
分支操作,包括分支的查詢、切換、創建、刪除等操作。
指令 | 備註 |
---|---|
git branch |
列出所有本地分支 |
git branch -r |
列出所有遠程分支 |
git branch -a |
列出所有本地分支和遠程分支 |
git branch [branch-name] |
新建一個分支,但依然停留在當前分支 |
git checkout -b [branch-name] |
新建一個分支,並切換到該分支 |
git branch --track [branch][remote-branch] |
新建一個分支,與指定的遠程分支建立追蹤關係 |
git checkout [branch-name] |
切換到指定分支,並更新工作區 |
git branch -d [branch-name] |
刪除分支 |
git push origin --delete [branch-name] |
刪除遠程分支 |
提到了分支,就不得不補充一個概念——HEAD,它始終指向當前追星的提交點,如果分支發生變化,或者產生了新的提交,那麼HEAD會隨之而變,有點類似於鏈表的當前指針。
push
最常用指令之一,上傳本地倉分支到遠程倉分支,實現同步。
指令 | 備註 |
---|---|
git push [remote][branch] |
上傳本地指定分支到遠程倉庫 |
git push [remote] --force |
強行推送當前分支到遠程倉庫,即使有衝突 |
git push [remote] --all |
推送所有分支到遠程倉庫 |
merge
最常用指令之一,merge命令把不同的分支合併起來。
指令 | 備註 |
---|---|
git fetch [remote] |
merge之前先拉一下遠程倉庫最新代碼,減少代碼衝突的可能性 |
git merge [branch] |
合併指定分支到當前分支 |
參考鏈接
[1] . 一篇文章,教你學會Git
[2]. 使用原理視角看 Git
[3]. GitHub 術語解釋
[4]. git概念、原理、使用
[5]. git官方文檔