git 常用命令
分散式
git是分散式版本控制系統,這麼一來,任何一處協同工作用的伺服器發生故障,事後都可以用任何一個映象出來的本地倉庫恢復。 因為每一次的克隆操作,實際上都是一次對程式碼倉庫的完整備份。
直接記錄快照,而非差異比較
每次你提交更新,或在 Git 中儲存專案狀態時,它主要對當時的全部檔案製作一個快照並儲存這個快照的索引。 為了高效,如果檔案沒有修改,Git 不再重新儲存該檔案,而是隻保留一個連結指向之前儲存的檔案。
Git 中所有資料在儲存前都計算校驗和,然後以校驗和來引用。
三種狀態
配置 git config
$ git config --global user.name "John Doe" $ git config --global user.email [email protected] $ git config --global core.editor emacs //配置文字編輯器,可選 $ git config --list // 檢視
當你想針對特定專案使用不同的使用者名稱稱與郵件地址時,可以在那個專案目錄下執行沒有 --global
選項的命令來配置。
常用命令
$ git init $ git add 檔名|. $ git commit這種方式會啟動文字編輯器以便輸入本次提交的說明 $ git commit -m 'message' $ git commit -a -m 'added new benchmarks'跳過使用暫存區域的方式 $ git clone url [name] $ git status
檢視差異
$ git diff比較的是工作目錄中當前檔案和暫存區域快照之間的差異, 也就是修改之後還沒有暫存起來的變化內容。 $ git diff --cached檢視已經暫存起來的變化
刪除檔案
$ git rm [filename]從已跟蹤檔案清單中移除(確切地說,是從暫存區域移除)並從工作目錄中刪除指定的檔案 $ git rm -f [filename]刪除之前修改過並且已經放到暫存區域的檔案 $ git rm --cached [filename]把檔案從 Git 倉庫中刪除(亦即從暫存區域移除),但保留在當前工作目錄中 $ git mv file_from file_to重新命名
檢視提交歷史
$ git log --pretty=format以指定格式輸出
format
如下:
選項說明 %H 提交物件(commit)的完整雜湊字串 %h 提交物件的簡短雜湊字串 %T 樹物件(tree)的完整雜湊字串 %t 樹物件的簡短雜湊字串 %P 父物件(parent)的完整雜湊字串 %p 父物件的簡短雜湊字串 %an 作者(author)的名字 %ae 作者的電子郵件地址 %ad 作者修訂日期(可以用 --date= 選項定製格式) %ar 作者修訂日期,按多久以前的方式顯示 %cn 提交者(committer)的名字 %ce 提交者的電子郵件地址 %cd 提交日期 %cr 提交日期,按多久以前的方式顯示 %s 提交說明
其他選項如下:
-p 用來顯示每次提交的內容差異 --stat 每次提交的簡略的統計資訊 --graph 顯示 ASCII 圖形表示的分支合併歷史。 --pretty=xxx 使用其他格式顯示歷史提交資訊。可用的選項包括 oneline,short,full,fuller 和 format(後跟指定格式)。
撤銷操作
$ git commit --amend有時候我們提交完了才發現漏掉了幾個檔案沒有新增,這個命令會將暫存區中的檔案提交。 如果自上次提交以來你還未做任何修改(例如,在上次提交後馬上執行了此命令),那麼快照會保持不變,而你所修改的只是提交資訊 $ git reset HEAD <file>取消暫存 $ git checkout -- [file]撤消對檔案的修改
遠端倉庫
$ git remote檢視遠端倉庫 $ git remote -v檢視遠端倉庫 $ git remote show [remote-name]檢視遠端倉庫 $ git remote add <shortname> <url>新增遠端倉庫 $ git remote rename 舊名 新名重新命名遠端倉庫 $ git remote rm [remote-name]刪除遠端倉庫 $ git fetch [remote-name]將資料拉取到你的本地倉庫 - 它並不會自動合併或修改你當前的工作 $ git pull抓取資料並自動嘗試合併到當前所在的分支。 $ git push [remote-name] [branch-name]推送到遠端倉庫,只有當你有所克隆伺服器的寫入許可權,並且之前沒有人推送過時,這條命令才能生效
打標籤
$ git tag列出已有的標籤 $ git tag -a 標籤 -m 備註打附註標籤 $ git show 標籤檢視標籤的資訊 $ git push origin 標籤將標籤推送到遠端倉庫伺服器上 $ git push origin --tags將所有的標籤推送到遠端倉庫 $ git tag -d 標籤刪除本地標籤 $ git push <remote>:refs/tags/<tagname>刪除遠端標籤
分支
Git 儲存的不是檔案的變化或者差異,而是一系列不同時刻的檔案快照
假設現在有一個工作目錄,裡面包含了三個將要被暫存和提交的檔案,暫存操作( git add
)會為每一個檔案計算校驗和,然後會把當前版本的檔案快照儲存到 Git 倉庫中(Git 使用 blob 物件來儲存它們),最終將校驗和加入到暫存區域等待提交。
當使用 git commit 進行提交操作時,Git 會先計算每一個子目錄(本例中只有專案根目錄)的校驗和,然後在 Git 倉庫中這些校驗和儲存為樹物件。 隨後,Git 便會建立一個提交物件,它除了包含上面提到的那些資訊外,還包含指向這個樹物件(專案根目錄)的指標。如此一來,Git 就可以在需要的時候重現此次儲存的快照。
現在,Git 倉庫中有五個物件:三個 blob 物件(儲存著檔案快照)、一個樹物件(記錄著目錄結構和 blob 物件索引)以及一個提交物件(包含著指向前述樹物件的指標和所有提交資訊)。
做些修改後再次提交,那麼這次產生的提交物件會包含一個指向上次提交物件(父物件)的指標。
Git 的分支,其實本質上僅僅是指向提交物件的可變指標
它有一個名為 HEAD 的特殊指標,指向當前所在的本地分支
$ git branch [branch-name]這會在當前所在的提交物件上建立一個指標(分支)。 $ git branch -d [branch-name]刪除指定分支 $ git branch -D [branch-name]強制刪除 $ git branch -v檢視每一個分支的最後一次提交 $ git checkout[branch-name]切換分支 $ git checkout -b [branch-name]建立並切換分支 $ git log --oneline --decorate --graph --all輸出提交歷史、各個分支以及專案的分支分叉情況 $ git merge[branch-name]合併指定分支到當前分支,當你試圖合併兩個分支時,如果順著一個分支走下去能夠到達另一個分支,那麼 Git 在合併兩者的時候,只會簡單的將指標向前推進(指標右移),因為這種情況下的合併操作沒有需要解決的分歧——這就叫做 “快進(fast-forward)”。如果有分叉,出現這種情況的時候,Git 會使用兩個分支的末端所指的快照(C4 和 C5)以及這兩個分支的工作祖先(C2),做一個新的快照並且自動建立一個新的提交指向它。 這個被稱作一次合併提交,它的特別之處在於他有不止一個父提交。
看一個例子:
首先建立並切換到 testing
分支
在 testing
分支上進行修改, 並提交
接著切換回 master
分支, 並修改提交
合併的例子:
合併後如下
出現衝突
合併它們的時候產生合併衝突, Git 會暫停下來,等待你去解決合併產生的衝突。 你可以在合併衝突後的任意時刻使用 git status 命令來檢視那些因包含合併衝突而處於未合併(unmerged)狀態的檔案, 在你解決了所有檔案裡的衝突之後,對每個檔案使用 git add
命令來將其標記為衝突已解決。 一旦暫存這些原本有衝突的檔案,Git 就會將它們標記為衝突已解決。這時你可以輸入 git commit
來完成合並提交
遠端分支
遠端引用是對遠端倉庫的引用(指標),包括分支、標籤等等
$ git ls-remote[remote]某個遠端引用的完整列表 $ git remote show [remote]獲得遠端分支的更多資訊 $ git checkout -b [branch] [remote-ranch]建立並跟蹤分支 $ git branch -u|--set-upstream-to 遠端分支將已有分支跟蹤到指定的遠端分支 $ git branch -vv檢視已有的所有跟蹤分支 $ git push [remote] --delete branch刪除遠端分支
如果有人對遠端倉庫進行了修改,你也對你本地倉庫進行了修改,此時進行
fetch
分支-變基
在 Git 中整合來自不同分支的修改主要有兩種方法: merge
以及 rebase
merge
它會把兩個分支的最新快照(C3 和 C4)以及二者最近的共同祖先(C2)進行三方合併,合併的結果是生成一個新的快照(並提交)。
合併之後
rebase
你可以使用 rebase 命令將提交到某一分支上的所有修改都移至另一分支上,就好像“重新播放”一樣。
$ git rebase [branch]將當前分支的修改提取,並移動到[branch]上 $ git rebase 被提取的分支 目標分支將被提取分支的修改移動到目標分支 $ git merge [branch]一般在變基後,需要進行一次快進合併 $ git pull --rebase 將當前分支的修改提取,併合併到目標分支, 等同於執行git fetch origin/branch然後再執行git rebase origin/branch
提取修改:
合併後:
不要對在你的倉庫外有副本的分支執行變基。 如你已經將提交推送至某個倉庫,而其他人也已經從該倉庫拉取提交併進行了後續工作