導航
Git 基本原理
哈希算法
- 一種加密算法,將
明文
加密爲密文
哈希算法特點
- 不管輸入數據量多大,輸入同一個哈希算法,得到的加密結果長度固定
- 哈希算法確定,輸入數據確定,輸出數據就保持不變
- 哈希算法確定,輸入數據有變化,哪怕變化很小,輸出結果頁會有變化,且通常變化很大
- 哈希算法不可逆(根據密文沒辦法反推出明文)
Git保證數據完整性的機制
- Git底層採用
SHA-1
算法 - 當原始文件經過網絡傳輸到目標服務器時,如果有文件的丟失,則會產生錯誤,那麼就可以用哈希算法驗證文件。
- 原始文件經過
SHA-1
生成一個結果,在網絡傳輸後,將目標文件也採用SHA-1
生成一個結果,兩個結果互相比對,如果一致,則說明文件傳輸未發生變化,否則說明文件在傳輸過程中發生了變化。
Git保存版本的機制
-
集中式版本控制工具的文件管理機制
- 以文件變更列表的方式存儲信息。這類系統將他們保存的信息看做是一組基本文件和每個文件隨時間逐步累積的差異
- 當文件有其他版本後,將文件中改變了的地方保存下來,當你要使用某個版本的時候,就將改版本保存的信息和初始版本相結合生成當前版本的文件
-
Git 的文件管理機制
Git把數據看做是小型文件系統的一組快照。每次提交更新時Git都會對當前的全部文件製作一個快照並保存這個快照的索引。爲了高效,如果文件沒有修改,Git將不再重新存儲該文件,而是隻保留一個鏈接(類似於指針)指向之前存儲的文件。所以Git 的工作方式可以稱之爲快照流。
-
Git的提交對象
Git的每一次提交都會創建提交對象,每個文件都會經過哈希算法得到一個哈希值,所有目錄內的文件的哈希值會得到一個樹對象(tree),樹對象就會包含每一個具體的文件及其哈希值,並且樹對象本身也會有一個哈希值,提交對象中就包含着樹對象的哈希值、當前提交的作者、當前提交的提交者、commit的信息,並且提交對象也會有一個自己的哈希值
-
提交對象及其父對象形成的鏈條
每一個快照都會包含一個父節點,保存父對象的哈希值指向該結點的父節點,形成鏈條(類似於鏈表)
Git分支管理的機制
root commit
根提交 —— 從未提交過的默認提交,當提交後,父對象即爲根提交- 創建分支:也就是新建一個指針,指向某個提交對象
- 切換分支:
HEAD
指針指向某個分支,切換分支也就是移動HEAD
指針
使用步驟
初始化
- 進入目錄,右鍵
git Bash here
mkdir
新建目錄git init
初始化倉庫- 設置簽名
git config
項目級別的簽名,即git config user.name/user.email
信息保存的是當前目錄/.git/config文件
如果是系統級別,則git config --global user.name/user.email
信息保存在根目錄 cd ~ 的.gitconfig目錄下,需要用ls -lA查看隱藏文件 - 查看狀態
git status
在本地倉庫內git status
使用vim 文件名
編輯文件
按 ESC +:+wq 退出
第一次提交
-
第一次提交完成後查看狀態
- git會檢測到修改過的文件,會顯示
modified
修改過的文件 - 提示:未準備提交的更改:
- 可以使用
git add
來更新,對暫存區做的是update
的操作,不再是之前的include
; - 用
git checkout
可以在工作目錄內取消這次修改
- 可以使用
- git會檢測到修改過的文件,會顯示
-
修改後再第二次提交之後查看狀態:
Git 結構
- 暫存區內容可在
add
後撤銷,當然也可以不 add 直接commit
,只是 commit 後不可撤銷 - 工作區中新建的文件必須
add
查看版本歷史記錄
-
git log
-
每個記錄會帶上提交的簽名和提交的日期
-
當做版本控制前進後退的時候就是通過移動Head指針來控制
-
空格向下翻頁,b向上翻頁,q退出,當記錄很多需要多屏顯示時的控制方法
-
查看歷史記錄的幾種不同的方式
-
git log --pretty=oneline
-
git log --oneline
-
git reflog
-
版本控制
本質
- 本質就是移動Head指針
三個方法
- 基於索引值【推薦】
git reset --hard 索引值
常與git reflog
搭配使用【能顯示出局部索引值,可直接複製粘貼使用】 - 使用
^
符號
git reset --hard HEAD^
有幾個^
就後退幾步
常與git log --oneline
使用【只顯示當前版本之後的】 - 使用
~
符號
git reset --hard HEAD~n
【n爲後退的步數】
推薦直接使用索引值,短移動可使用後兩種方法。
reset命令
--soft
僅在本地庫移動HEAD指針本地庫回退了,相對應的暫存區和工作區就提前了,status查看後會顯示綠色。
--mixed
在本地庫移動,並重置暫存區本地庫和暫存區都後退了,那麼工作區就會相對提前了
--hard
【常用】
本地庫移動,重置暫存區和工作區
三者一起回退,保持一致
刪除文件後找回
- 刪除文件
rm filename.file
- 找回文件的前提
刪除前,文件存在時的狀態提交到了版本庫 - 刪除操作已經提交到本地庫
使用git reset --hard [指針位置]
當操作已經提交到本地庫後,一旦本地庫記錄了,就不會被抹去,Git在操作的時候,只會增加版本,不會刪除版本,即使是前進後退,都不會刪除版本。因此,由於版本記錄的存在,只要後退到刪除文件那個版本記錄的之前的版本記錄,就能找回刪除的文件 - 刪除操作尚未提交到本地庫
使用git reset --hard HEAD
利用本地庫當前的版本刷新工作區和暫存區
比較文件差異
git diff filename.file
是將工作區中的文件和暫存區中的文件比較git diff HEAD|Head^ filename.file
將工作區中的文件和當前本地庫|本地庫歷史中的文件比較git diff HEAD
不帶文件名比較多個文件
分支操作
常用分支操作
git branch name
創建分支git branch -v
查看分支列表git checkout name
切換分支git status
查看當前所在分支git merge name
合併分支【需先切換到被修改的分支,例:A修復了Bug,但B沒有,於是B想跟A合併,那麼就要先切換到B,再用merge命令合併】
合併分支後產生的衝突
- 當自動合併產生衝突後 git 會自動轉爲手動合併
(anotherMaster|MERGING)
CONFLICT (content): Merge conflict in filename.file
Automatic merge failed;fix conflicts and then commit the result.
- 產生衝突的原因
合併的兩個分支各有更新,git 拿不定需要刪除哪些,保留哪些,於是產生衝突,git 就會展示分支間的衝突,由人自行決定。<<<<<<< HEAD 此處爲當前分支的衝突內容 ======= 此處爲另一分支的衝突內容 >>>>>>> master
- 解決方法
當解決完畢後,查看狀態git status
,根據提示使用git add filename.file
標記爲已解決,但是仍處於合併過程中,再用git commit -m "日誌信息"
完成合並過程
GitHub與本地Git交互
- 推薦使用碼雲,GitHub延遲比較大
GitHub
- 一個代碼託管中心
- 交互過程:有A和B,B是A的下屬;A先創建一個本地庫,再在GItHub上面創建一個遠程庫,創建好後,A先在本地搭建好環境,並
push
上託管中心,然後B就從託管中心clone
下來,生成本地庫,B修改更新後需要先加入團隊纔可以push
內容,緊接着A再將託管中心的內容pull
下來。
本地git倉庫連接GitHub
- 先保存GitHub的倉庫的連接(HTTPS/SSH)
git remote -v
查看源git remote add origin httpsLink
添加源
團隊內協作
- 克隆:
clone
操作:git clone httpsLink
- 克隆的三個效果:完整地把遠程庫下載到本地;創建
origin
遠程地址別名;初始化本地庫。 - 推送:
git push origin master
origin即推送目標,master即推送的分支(必須加上) - 抓取:
git pull origin master
:抓取操作對於遠程庫只是一個讀操作,因此不需要登陸 pull
=fetch
+merge
:fetch
僅抓取 ;merge
合併git fetch link branchName
+git merge link/branchName
- fetch 和 merge操作分開操作的好處就是在文件複雜很多的時候,我們可以先抓取下來不合並本地庫,在比對好後再合併到本地庫。
fetch
下來後,可以通過git checkout origin/master
查看抓取下來的文件- 如果不是基於GitHub遠程庫的最新版所做的修改,則不能推送 ----- 防止版本不一樣導致不同的本地庫推送的版本不同。
- 協作開發時發生衝突:當兩人同時改同一個位置,後推送的人便不可再直接推送,必須先拉取下來纔可以推送,那麼拉取下來時,既有自己的修改,也有先推送的人的修改,就會產生衝突,git便不能替我們決定哪些保留哪些保存;然後就進入到本地庫解決衝突的步驟,最後add標記爲已解決衝突,再commit到本地庫,最後再推送到遠程
跨團隊協作
fork
將對方的遠程庫複製到自己的遠程庫pull request
先把自己的遠程庫中的文件抓取到本地庫,修改了後再推送上自己的遠程庫,然後就可以發起一個pull request
,對方在GitHub上看到該request後會審覈,對方審覈通過後修改的部分便會合併到對方的遠程庫中,至此完成跨團隊協作。
SSH登陸
ssh-keygen -t rsa -C email
生成一個ssh目錄- 進入到
.ssh
目錄(注意日誌信息,裏面會提到你的.ssh
目錄的位置,一般會在C:/Users/Administrator
下,也就是我的文檔下面) - 打開
id_rsa.pub
文件並複製其中的內容 - 去到GitHub添加SSH key
- 回到工作區測試
- 添加origin
git remote add origin_ssh sshLink
- 做push、pull操作時使用
origin_ssh
即可