前端工程化之git篇全解,深入底層命令,遠端庫 -助您輕鬆暢遊git

Jeery_譚金傑發表於2019-03-08

直接上乾貨,git的核心3大知識點


'git是現代前端工程化必備的技能,熟讀本篇文章,你可以輕鬆使用git,不懂的在下面留言,我會一一為你解答'

複製程式碼

1.git的三大區域

1.工作目錄(你的index.html等等這些檔案存放的資料夾)

2.暫存區 (你可以理解成停留在工作目錄和版本中間的一個虛擬空間)

3.版本庫(其實就是一個資料夾,在.git隱藏資料夾裡的objects資料夾,裡面存放了git物件和commit物件以及tree物件)
複製程式碼

2.git的三種物件型別

1.git物件(通過大量優化和演算法壓縮儲存的檔案,每個git物件直接儲存了你所讓git追蹤的那個檔案內容,它git中最基本的物件型別)

2.tree物件(每個tree物件只是一串索引,它指向了git物件,git物件才是真正存放檔案內容的那個單位,一個tree物件可以指向多個git物件)

3.commit物件(每次使用 git commit -m命令提交生成的那個物件,裡面包含了當前提交的暫存區裡所有的樹物件)
 

複製程式碼

3.git 一次完整的提交過程(深入底層命令,最詳細的git提交過程)

1.檔案未加入git追蹤(沒有把檔案加入到git版本庫中) 

2.檔案已經加入到git版本庫中,但是沒有給檔案對應的git物件開啟暫存區的狀態

3.檔案已經加入到git版本庫中,並且給其檔案對應的git物件開啟了暫存區,給git物件開啟暫存區後,使用write tree命令便會生成tree物件,這個tree物件的引用指向那個git物件,這裡就很好理解為什麼說git效能高,存放檔案內容的都是git物件,但是拿去提交的都是樹物件,這些樹物件頻繁的使用,但是他們僅僅是一串數字,指向了最終的基層檔案git物件,最終的git物件一直躺在版本庫的資料夾中沒有動。

4.生成樹物件後,提交到版本庫,生成commit物件。這句話逼格聽起來很高,實質就是將暫存區裡所有的樹物件打包,生成另外一串數字,塞到一個資料夾(版本庫objects資料夾中),這串數字就是commit物件,它指向了這些樹物件,這些樹物件指向了他們對應的git物件,這樣,一個commit物件就儲存了你當前提交的所有檔案的內容,並且存放在版本庫中。 


由上到下對應的關係   一個commit物件  => 所有被git追蹤並開啟暫存區的檔案的tree物件 =>這些tree物件對應的git物件(git物件是最基本的物件,存放著檔案的實質內容)

複製程式碼

上面這三大git知識點一定要吃透,然後開始看下面的執行邏輯


開啟git第一件事git init -y

我們首先 

echo   '需要輸入的內容' > test.txt ,  為檔案寫入內容,會覆蓋操作,沒有這個檔案則新建


git hash-object -w test.txt 

將test.txt加入到git的版本庫中,在版本庫將生成對應的git物件,這個git物件儲存了test.txt檔案的全部內容,
但是此時還不保險,他只是對應了當前一個test.txt檔案,我們必須保證專案其他檔案的完整性,這只是第一步。


 在加入到版本庫後,我們通過 find .git/objects -type f命令檢視版本庫中的所有檔案,他會返回下面這段程式碼
 83baae61804e65cc73a7201a7252750c76066a30 test.txt 
 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a demo.txt ....
 
,我們將為test.txt開啟暫存區


 我們找到對應的test.txt檔案的那串字元,然後使用 
 git update-index --add --cacheinfo 100644 83baae61804e65cc73a7201a7252750c76066a30 test.txt
 (上面這一步是讓版本庫中的test.txt的git物件,開啟暫存區)
 然後我們
 git write-tree
 
 此時生成樹物件 ,這個樹物件的內容,我們可以通過 git cat-file -p 命令檢視
 他會返回一串  *****bf3dd9643fd615f6da*****...   test.txt  的git物件  
 這意味著,這個樹物件,指向git物件。 
 
 此時我們可以提交了  使用git commit -m '這是我們的第一次提交'  
 
 這時候版本庫中多了一個commit物件,我們可再次使用find .git/objects -type f命令檢視,這時候發現多了兩個檔案,
 一個是test.txt對應的tree物件,一個是剛提交的commit物件,有趣的是,這個commit物件,對應了之前最後一次提交的所有tree物件,這樣我們只新增了一個test.txt檔案,但是卻重新儲存了一個版本,這個版本就是commit物件的那串索引,
 怎麼樣,到這裡應該領會到了git的厲害之處了吧。,每次git儲存的都是一個所有檔案完整的版本。
 
 提交後使用  git status  命令,檢視當前git的狀態 ,每當你有感覺不對的時候,應該使用git status命令,後面我會詳細講解
 
複製程式碼

git的高層命令 (實際開發的使用命令)

在git使用中,我們基本不會使用上面的底層命令,上面的底層命令只是為了讓我們熟悉git的工作機制,讓我們更好的使用git已經封裝好的高層命令,出了問題能更好的解決。

1.git status 命令    ---git 最重要的命令
每次我們git init -y 後, 先輸入git status  命令檢視,如果有紅色的字型顯示,該檔案沒有加入到版本庫,需要我們新增,如果是綠色的字型顯示的檔案,那麼意味著我們需要提交了,如果沒有檔案顯示,那麼萬事大吉,我們目前沒有需要提交的物件,感覺不對勁,馬上使用git status 命令檢視當前git狀態。 

2.git add 檔案的url | 資料夾url   ---這條命令是將檔案從工作目錄中找到,然後新增到版本庫中生成git物件,並給其開啟對應的暫存區

3. git commit  -m '此處是你這次提交需要寫的註釋'   提交命令,生成對應的樹物件,並且生成commit物件,儲存在版本庫資料夾中,一個test.txt檔案在版本中對應了三個檔案,一個git物件用來儲存檔案內容,一個tree物件指向這個git物件,一個commit物件指向最新的提交版本的所有tree物件,也包括這個檔案的tree物件。


本地的不考慮分支的提交工作已經做完   熟練操作這些命令很有必要,接下來將要學習git的分支操作
複製程式碼

git的分支操作(最重要的地方)

'這邊先說本地的操作'


git的預設的主分支叫master 它的名字可以修改,但是我們不建議修改,這裡方法不推薦  

這條master分支我們一般認為他上面的程式碼,都是正式版本的,都是能跑的程式碼,只要不是確定能跑的程式碼,那麼堅決不上主分支,在其他次分支測試穩定後再跳回到主分支合併那條穩定的次分支,這樣做是為了保證主分支的穩定性。

下面,我們預設一開始是在master主分支上


git branch demo1  -- 這條命令可以讓我們在當前所在的主分支上建立一個demo1的分支 ,這條新建的demo1分支,他的版本跟當前所在的master主分支的一樣,他們通過git獲取恢復的工作目錄的檔案內容都完全一致,相當於克隆了一份程式碼,拿到demo1這個分支上

使用git status命令檢視,如果沒有需要提交的物件(每次切換分支都要git status檢視狀態)

那麼我們就使用 git checkout demo1 的命令跳到demo1的分支上,我們可以開始放心的修改我們的檔案,一般開發都是一個人負責一個模組,你只要在你所在的這條demo1分支上修改檔案,然後每個小階段commit提交一下,就是安全的,等你的功能寫完,跟專案的負責人通報,你的模組已經寫完,需要合併,這時候專案負責人會告訴你,沒問題,那麼你再次使用 git checkout master 命令,切換到master的主分支上,此時切換過去的,肯定是最新的master主分支版本,然後使用git merge demo1命令,合併分支, 再次使用git status檢視,此時如果有需要手動修改的衝突,那麼手動處理一下,一般一個人負責一個模組是不會出現衝突的。

如果沒有,那麼萬事大吉,一切完成!


'接下來是遠端倉庫的操作 ,請注意看好這裡的每一句話'

依賴於 github

'專案經理建立遠端倉庫 '
 

專案經理為遠端倉庫配置別名
git remote add <shortname> <url> 
新增一個新的遠端 Git 倉庫,同時指定一個你可以輕鬆引用的簡寫
git remote –v
顯示遠端倉庫使用的 Git 別名與其對應的 URL
git remote show [remote-name]
檢視某一個遠端倉庫的更多資訊
git remote rename pb paul
重新命名
git remote rm [remote-name]
如果因為一些原因想要移除一個遠端倉庫 你已經從伺服器上搬走了或不再想使用某一個特定的映象了,又或者某一個貢獻者不再貢獻了
專案經理推送本地專案到遠端倉庫
初始化一個本地倉庫然後:
git push [remote-name] [branch-name]
將本地專案的master 分支推送到 origin (別名)伺服器


'成員克隆遠端倉庫到本地'

git clone url (克隆時不需要 git init)
預設克隆時為遠端倉庫起的別名為origin


'成員推送提交到遠端倉庫'

git push [remote-name] [branch-name]
只有當你有所克隆伺服器的寫入許可權,並且之前沒有人推送過時,這條命令才能生效。 當你和其他人在同一時間克隆,他們先推送到上游然後你再推送到上游,你的推送就會毫無疑問地被拒絕。 你必須先將他們的工作拉取下來並將其合併進你的工作後才能推送


'專案經理更新成員提交的內容'
git fetch [remote-name]
這個命令會訪問遠端倉庫,從中拉取所有你還沒有的資料。 執行完成後,你將會擁有那個遠端倉庫中所有分支的引用,可以隨時合併或檢視
必須注意 git fetch 命令會將資料拉取到你的本地倉庫 - 它並不會自動合併或修改你當前的工作。 當準備好時你必須手動將其合併入你的工作。



'僅僅理解上面的,還是不能夠在git隨意遨遊,下面我們來深入理解遠端庫'


遠端跟蹤分支是遠端分支狀態的引用。它們是你不能移動的本地分支。當你做任何網路通訊操作時,它們會自動移動。 
它們以 (remote)/(branch) 形式命名,例如,如果你想要看你最後一次與遠端倉庫 origin 通訊時 master分支的狀態,你可以檢視 origin/master 分支
當克隆一個倉庫時,它通常會自動地建立一個跟蹤 origin/master 的 master 分支
假設你的網路裡有一個在 git.ourcompany.com 的 Git 伺服器。 如果你從這裡克隆,Git 的 clone 命令會為你自動將其命名為 origin,拉取它的所有資料,建立一個指向它的 master 分支的指標,並且在本地將其命名為 origin/master。 Git 也會給你一個與 origin/master 分支在指向同一個地方的本地 master 分支,這樣你就有工作的基礎


他人推送提交到 git.ourcompany.com 並更新了它的 master 分支,那麼你們的提交歷史將向不同的方向前進。 只要你不與 origin 伺服器連線,你的 origin/master 指標就不會移動 
如果要同步你的工作,執行 git fetch origin 命令。 這個命令查詢 “origin” 是哪一個伺服器(在本例中,它是 git.ourcompany.com),從中抓取本地沒有的資料,並且更新本地資料庫,移動 origin/master指標指向新的、更新後的位置。


'推送其他分支'
當你想要公開分享一個分支時,需要將其推送到有寫入許可權的遠端倉庫上。 本地的分支並不會自動與遠端倉庫同步 - 你必須顯式地推送想要分享的分支。 這樣,你就可以把不願意分享的內容放到私人分支上,而將需要和別人協作的內容推送到公開分支
如果希望和別人一起在名為 serverfix 的分支上工作,你可以像推送第一個分支那樣推送它。 
git push origin serverfix
這裡有些工作被簡化了。 Git 自動將 serverfix 分支名字展開為 refs/heads/serverfix:refs/heads/serverfix
你也可以執行 git push origin serverfix:serverfix,它會做同樣的事 - 相當於它說,“推送本地的 serverfix 分支,將其作為遠端倉庫的 serverfix 分支”
git push origin serverfix:awesomebranch
如果並不想讓遠端倉庫上的分支叫做 serverfix,可以執行以上命令將本地的 serverfix 分支推送到遠端倉庫上的 awesomebranch 分支。
git fetch origin
下一次其他協作者從伺服器上抓取資料時,他們會在本地生成一個遠端跟蹤分支 origin/serverfix,指向伺服器的 serverfix 分支的引用。要特別注意的一點是當抓取到新的遠端跟蹤分支時,本地不會自動生成一份可編輯的副本(拷貝)。 換一句話說,這種情況下,不會有一個新的 serverfix 分支 - 只有一個不可以修改的 origin/serverfix 指標。
	git merge origin/serverfix    (其他協作者)
可以執行 git merge origin/serverfix 將這些工作合併到當前所在的分支。 
如果想要在自己的 serverfix 分支上工作,可以將其建立在遠端跟蹤分支之上:
	git checkout -b serverfix origin/serverfix (其他協作者)
跟蹤分支
從一個遠端跟蹤分支(origin/master)檢出一個本地分支會自動建立一個叫做 “跟蹤分支”(有時候也叫做 “上游分支” :master)。 
只有主分支 或者 克隆時才會自動建跟蹤分支.
跟蹤分支是與遠端分支有直接關係的本地分支。 如果在一個跟蹤分支上輸入 git pull,Git 能自動地識別去哪個伺服器上抓取、合併到哪個分支。
如果你願意的話可以設定其他的跟蹤分支,或者不跟蹤 master 分支。
git checkout -b [branch] [remotename]/[branch]
git checkout -b serverfix origin/serverfix
這是一個十分常用的操作所以 Git 提供了 --track 快捷方式
git checkout --track origin/serverfix
如果想要將本地分支與遠端分支設定為不同名字
git checkout -b sf origin/serverfix
設定已有的本地分支跟蹤一個剛剛拉取下來的遠端分支,或者想要修改正在跟蹤的跟蹤分支,你可以在任意時間使用 -u  選項執行 git branch 來顯式地設定
git branch -u origin/serverfix (--set-upstream-to)

git branch -vv
檢視設定的所有跟蹤分支
git branch -vv
  iss53     7e424c3 [origin/iss53: ahead 2] forgot the brackets
  master    1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
  		testing   5ea463a trying something new
iss53 分支正在跟蹤 origin/iss53 並且 “ahead” 是 2,意味著本地有兩個提交還沒有推送到伺服器上。
master 分支正在跟蹤 origin/master 分支並且是最新的。 
 serverfix 分支正在跟蹤 teamone 伺服器上的 server-fix-good 分支並且領先 3 落後 1,意味著伺服器上有一次提交還沒有合併入同時本地有三次提交還沒有推送。
 testing 分支並沒有跟蹤任何遠端分支。

需要重點注意的一點是這些數字的值來自於你從每個伺服器上最後一次抓取的資料。 這個命令並沒有連線伺服器,它只會告訴你關於本地快取的伺服器資料。 如果想要統計最新的領先與落後數字,需要在執行此命令前抓取所有的遠端倉庫。 可以像這樣做:$ git fetch --all; git branch –vv


'刪除遠端分支'
git push origin --delete serverfix

複製程式碼

第二次在網上分享技術貼,非常喜歡掘金這個平臺,後面我會再就深入頁面層次的效能優化,ES6/7,typeScript,前端面試題,原生javaScript的效能優化等等...寫出更多高質量的帖,為開源社群做出貢獻!

相關文章