git命令背後原理學習

最近做銀聯項目,多人開發,需求比較雜,有的需求先開發的卻後上,有的相反,之前是用svn管理的,對於分支管理這塊不太好用,故而轉向git,使用git分支管理來做,下面記錄git的學習,

一:概念

  • 工作區:就是你在電腦裏能看到的目錄。隨着分支的切換,裏面的文件會發生相應的改變。
  • 暫存區:一般存放在 ".git目錄下" 下的index文件(.git/index)中,所以我們把暫存區有時也叫作索引(index)。
  • 版本庫:工作區有一個隱藏目錄.git,這個不算工作區,而是Git的版本庫。和svn不同,svn的版本庫在服務器,git的在本地,所以git在沒有網絡的情況下也可以commit。

二:安裝

https://gitforwindows.org/下載exe文件直接一路下去就可以了

安裝完之後,可以通過,右鍵菜單“Git Bash Here”打開命令窗口,來執行git的命令,例如git commit等;

三:配置

如果用 --global 選項,所有的項目都會默認使用這裏配置的用戶信息。

若使用 --system 選項,所有的用戶都會默認使用這裏配置的用戶信息。

1.配置用戶名和電子郵件,標識個人信息

$ git config --global user.name "guoyang"
$ git config --global user.email [email protected]@163.com

2.列出所有的配置

$ git config -l
...
[email protected]
user.name=guoyang
...

其他的配置不太常用,遇到時可以自行百度

四:本地操作

可以這樣理解,基本所有的命令的作用都是操作提交記錄樹

1.git init

把當前執行命令的目錄,創建爲git倉庫,完全是本地化,.git隱藏目錄保存所有元數據

$ mkdir gy
$ cd gy
$ git init
Initialized empty Git repository in C:/Users/Service01/Desktop/test/gy/.git/
$ ls -alrt
total 4
drwxr-xr-x 1 Service01 197121 0 Mar 30 15:00 ../
drwxr-xr-x 1 Service01 197121 0 Mar 30 15:00 ./
drwxr-xr-x 1 Service01 197121 0 Mar 30 15:00 .git/

2.git add 

把工作區的內容提交到暫存區

3.git commit

把暫存區的內容提交到版本庫,並記錄提交記錄。

Git 倉庫中的提交記錄保存的是你的目錄下所有文件的快照,就像是把整個目錄複製,然後再粘貼一樣,但比複製粘貼優雅許多!

Git 希望提交記錄儘可能地輕量,因此在你每次進行提交時,它並不會盲目地複製整個目錄。條件允許的情況下,它會將當前版本與倉庫中的上一個版本進行對比,並把所有的差異打包到一起作爲一個提交記錄。

Git 還保存了提交的歷史記錄。這也是爲什麼大多數提交記錄的上面都有父節點的原因 —— 我們會在圖示中用箭頭來表示這種關係。對於項目組的成員來說,維護提交歷史對大家都有好處。

關於提交記錄太深入的東西咱們就不再繼續探討了,現在你可以把提交記錄看作是項目的快照。提交記錄非常輕量,可以快速地在這些提交記錄之間切換!C0,C1,C2是提交記錄,master是默認分支名稱,*代表HEAD位置(後面細說)

git commit

4.git branch

Git 的分支非常輕量。它們只是簡單地指向某個提交紀錄 —— 僅此而已。所以許多 Git 愛好者傳頌:

早建分支!多用分支!

這是因爲即使創建再多分的支也不會造成儲存或內存上的開銷,並且按邏輯分解工作到不同的分支要比維護那些特別臃腫的分支簡單多了。

在將分支和提交記錄結合起來後,我們會看到兩者如何協作。現在只要記住使用分支其實就相當於在說:“我想基於這個提交以及它所有的父提交進行新的工作。

新建分支git branch newImage

再來個提交git commit

切換到newImage分支,並提交

git checkout newImage;git commit

5.git merge

在 Git 中合併兩個分支時會產生一個特殊的提交記錄,它有兩個父節點。翻譯成自然語言相當於:“我要把這兩個父節點本身及它們所有的祖先都包含進來。”

git merge bugFix

咱們再把 master 分支合併到 bugFix

git checkout bugFix;git merge master

因爲 master 繼承自 bugFix,Git 什麼都不用做,只是簡單地把 bugFix 移動到 master 所指向的那個提交記錄。

6.git rebase

第二種合併分支的方法是 git rebase。Rebase 實際上就是取出一系列的提交記錄,“複製”它們,然後在另外一個地方逐個的放下去。

Rebase 的優勢就是可以創造更線性的提交歷史,這聽上去有些難以理解。如果只允許使用 Rebase 的話,代碼庫的提交歷史將會變得異常清晰。

git rebase master

現在我們切換到了 master 上。把它 rebase 到 bugFix分支上

git rebase bugFix

由於 bugFix 繼承自 master,所以 Git 只是簡單的把 master 分支的引用向前移動了一下而已。

7.在提交樹上移動

HEAD:當前操作位置,一個倉庫只有一個

HEAD 總是指向當前分支上最近一次提交記錄。大多數修改提交樹的 Git 命令都是從改變 HEAD 的指向開始的。

HEAD 通常情況下是指向分支名的(如 bugFix)。在你提交時,改變了 bugFix 的狀態,這一變化通過 HEAD 變得可見。

分離的HEAD:HEAD不再指向分支名

8.相對引用

通過指定提交記錄哈希值的方式在 Git 中移動不太方便。在實際應用時,並沒有像本程序中這麼漂亮的可視化提交樹供你參考,所以你就不得不用 git log 來查查看提交記錄的哈希值。

並且哈希值在真實的 Git 世界中也會更長(譯者注:基於 SHA-1,共 40 位)。例如前一關的介紹中的提交記錄的哈希值可能是 fed2da64c0efc5293610bdd892f82a58e8cbc5d8。舌頭都快打結了吧...

比較令人欣慰的是,Git 對哈希的處理很智能。你只需要提供能夠唯一標識提交記錄的前幾個字符即可。因此我可以僅輸入fed2 而不是上面的一長串字符。

正如我前面所說,通過哈希值指定提交記錄很不方便,所以 Git 引入了相對引用。這個就很厲害了!

使用相對引用的話,你就可以從一個易於記憶的地方(比如 bugFix 分支或 HEAD)開始計算。

相對引用非常給力,這裏我介紹兩個簡單的用法:

  • 使用 ^ 向上移動 1 個提交記錄
  • 使用 ~<num> 向上移動多個提交記錄,如 ~3

使用相對引用最多的就是移動分支。可以直接使用 -f 選項讓分支指向另一個提交。例如:

git branch -f master HEAD~3

上面的命令會將 master 分支強制指向 HEAD 的第 3 級父提交

9.撤銷變更

git reset

git revert

10.整理提交記錄

1)git cherry-pick

2)git rebase交互式

11.git tag

和分支的區別,分支隨着commit會變動,tag永遠執行某一個提交,可以和分支一樣被引用

五:遠程操作

遠程倉庫只是本地倉庫的一個copy,包括提交記錄

1.git clone

你可能注意到的第一個事就是在我們的本地倉庫多了一個名爲 o/master 的分支, 這種類型的分支就叫遠程分支。由於遠程分支的特性導致其擁有一些特殊屬性。

遠程分支反映了遠程倉庫(在你上次和它通信時)的狀態。這會有助於你理解本地的工作與公共工作的差別 —— 這是你與別人分享工作成果前至關重要的一步.

遠程分支有一個特別的屬性,在你檢出時自動進入分離 HEAD 狀態。Git 這麼做是出於不能直接在這些分支上進行操作的原因, 你必須在別的地方完成你的工作, (更新了遠程分支之後)再用遠程分享你的工作成果。

爲什麼有 o/

你可能想問這些遠程分支的前面的 o/ 是什麼意思呢?好吧, 遠程分支有一個命名規範 —— 它們的格式是:

  • <remote name>/<branch name>

因此,如果你看到一個名爲 o/master 的分支,那麼這個分支就叫 master,遠程倉庫的名稱就是 o

大多數的開發人員會將它們主要的遠程倉庫命名爲 origin,並不是 o。這是因爲當你用 git clone 某個倉庫時,Git 已經幫你把遠程倉庫的名稱設置爲 origin 了

不過 origin 對於我們的 UI 來說太長了,因此不得不使用簡寫 o :) 但是要記住, 當你使用真正的 Git 時, 你的遠程倉庫默認爲 origin!

說了這麼多,讓我們看看實例。

2.git fetch

git fetch 完成了僅有的但是很重要的兩步:

  • 從遠程倉庫下載本地倉庫中缺失的提交記錄
  • 更新遠程分支指針(如 o/master)

git fetch 實際上將本地倉庫中的遠程分支更新成了遠程倉庫相應分支最新的狀態。

git fetch 並不會改變你本地倉庫的狀態。它不會更新你的 master 分支,也不會修改你磁盤上的文件。

2.git pull

git pull = git fetch + git merge o/master

3.git push

git push 負責將你的變更上傳到指定的遠程倉庫,並在遠程倉庫上合併你的新提交記錄。一旦 git push 完成, 你的朋友們就可以從這個遠程倉庫下載你分享的成果了!

你可以將 git push 想象成發佈你成果的命令。它有許多應用技巧,稍後我們會了解到,但是咱們還是先從基礎的開始吧……

注意 —— git push 不帶任何參數時的行爲與 Git 的一個名爲 push.default 的配置有關。它的默認值取決於你正使用的 Git 的版本,但是在教程中我們使用的是 upstream。 這沒什麼太大的影響,但是在你的項目中進行推送之前,最好檢查一下這個配置。

偏離的工作

現在我們已經知道了如何從其它地方 pull 提交記錄,以及如何 push 我們自己的變更。看起來似乎沒什麼難度,但是爲何還會讓人們如此困惑呢?

困難來自於遠程庫提交歷史的偏離。如果在你pull之後,有人向遠程分支提交了新的記錄,那麼你直接push會失敗,失敗是因爲,你的提交不是基於最新的遠程提交開發的,此時需要先把遠程的提交更新到本地,然後merge或rebase,再push

 

之前已經說過git pull = git fetch + git merge

類似的:git pull --rebase = git getch + git rebase

rebase後提交記錄比較清晰,merge反應是真實發生的情況,看個人喜好使用

六:idea中使用

1.git clone

添加忽略的文件(僅僅本地使用,不需要提交到git),如果配置後,commit時還能看到這些文件,可以重啓下工程

2.git add

3.git commit

4.git push

5.git pull

6.git branch

切換分支

7.git merge

8.git log

參考網站

https://www.runoob.com/git/git-tutorial.html

https://learngitbranching.js.org/

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章