JB的git之旅-git命令列

jb發表於2019-03-02

前言

關於git的介紹,這裡就不在重複了,感興趣的同學可以看下之前寫的文章,有關於git跟svn區別及怎麼配置git;

最近在折騰gitlab ci,想做一些工具,其中涉及到用哪些git命令,來回奔波查詢,所以想寫一篇git命令相關的,當做總結備忘,方便後續自己查詢,同時也想加深印象;

關於工具,有很多git圖形化工具,jb一開始也是使用圖形化工具的,但是隨著時間的流逝,在使用圖形化工具遇到不少問題,
比如提交到緩衝區,不想push,怎麼撤回?push後怎麼回滾等等問題,對工具是有學習成本的,
與其熟悉工具,不如花點時間瞭解下Git命令,何況,手動敲命令,看上去很牛逼啊~

JB的git之旅-git命令列

本地命令

1.配置檔案-git config

一般教程在安裝完git後都會引導配置使用者名稱跟郵箱,此時就需要git config命令了,而使用者名稱跟郵箱,都是本地git客戶端的一個變數,不跟隨git庫而改變的~

區分configlocal
config是代表全域性修改:系統中對所有使用者都普遍使用的配置;對應的檔案是**/etc/gitconfig**,
在使用git config --system,讀取的就是這個檔案
local是代表使用者修改:使用者目錄下的配置檔案,只適用於當前使用者;對應的檔案是**~/.gitconfig**,
在使用git config --global,讀取的就是這個檔案
工作目錄檔案是**.git/config**,這裡的配置僅僅針對當前專案有效

從優先順序的角度來看,local比config要高

git config user.name     #檢視使用者名稱
git config user.email    #檢視郵箱
git config --global user.name "your name"    #設定使用者名稱
git config --global user.email "your email"  #設定郵箱

#其他配置
git config --global --list   #檢視全域性設定相關引數列表
git config --local --list   #檢視本地設定相關引數列表
git config --system --list  #檢視系統設定引數列表
git config --list   #檢視所有git的配置(全域性+本地+系統)
git config --global core.edit 喜歡的編輯器
複製程式碼

2.獲取幫助-git help

git help  #比如,要學習config命令怎麼使用,git help config
複製程式碼

3.初始化倉庫-git init

git init 倉庫名 # 建立一個新的帶Git倉庫的專案
git init # 為已存在的專案生成一個Git倉庫
複製程式碼

4.新增檔案到暫存區-git add

使用git add檔名,把檔案新增到暫存區,支援批量新增

git add 檔名 # 將工作區的某個檔案新增到暫存區   
git add -u # 將已跟蹤檔案中的修改和刪除的檔案新增到暫存區,不包括新增加的檔案
git add -A # 將所有的已跟蹤的檔案的修改與刪除和新增的未跟蹤的檔案都新增到暫存區
git add . # 將當前工作區的所有檔案都加入暫存區
git add -i # 進入互動介面模式,按需新增檔案到快取區
複製程式碼

互動模式長這樣:

JB的git之旅-git命令列

這裡還想介紹一種場景:
假如你修改了檔案 a.txt,然後把它 add 進了暫存區:

git add a.txt
git status
複製程式碼

JB的git之旅-git命令列

然後又往 a.txt 裡寫了幾行東西。這時候你再 status 一下的話:

git status
複製程式碼

JB的git之旅-git命令列

會發現你的 a.txt 既在 "Changes to be commited" 的暫存區,又在 "Changes not staged for commit"。
不用覺得奇怪,這是因為通過 add 新增進暫存區的不是檔名,而是具體的檔案改動內容。
在 add 時的改動都被新增進了暫存區,但在 add 之後的新改動並不會自動被新增進暫存區。在這時如果你提交:

git commit
複製程式碼

那麼你那些新的改動是不會被提交的。

所以需要先重新add檔案,再commit,才能把最新的內容提交進去~

5.將快取區的檔案提交到本地倉庫-git commit

git commit -m "提交說明" # 將暫存區內容提交到本地倉庫
git commit -a -m "提交說明" # 跳過快取區操作,直接把工作區內容提交到本地倉庫
git commit -amend #合併上一次提交,在不增加一個新的commit-id的情況下將新修改的程式碼追加到前一次的commit-id中
複製程式碼

如果不加-m "提交說明",git會讓用你讓預設編輯器(如vi)來編寫提交說明,

6.檢視工作區與緩衝區的狀態-git status

git status # 檢視工作區與暫存區的當前情況
git status -s # 讓結果以更簡短的形式輸出
複製程式碼

JB的git之旅-git命令列

7.差異對比-git diff

git diff # 工作區與快取區的差異
git diff 分支名 #工作區與某分支的差異,遠端分支這樣寫:remotes/origin/分支名
git diff HEAD  # 工作區與HEAD指標指向的內容差異
git diff 提交id 檔案路徑 # 工作區某檔案當前版本與歷史版本的差異
git diff --stage # 工作區檔案與上次提交的差異(1.6 版本前用 --cached)
git diff 版本TAG # 檢視從某個版本後都改動內容
git diff 分支A 分支B # 比較從分支A和分支B的差異(也支援比較兩個TAG)
git diff 分支A...分支B # 比較兩分支在分開後各自的改動
git diff --cached  #顯示所有已新增快取區但還未提交的變更
複製程式碼

8.檢視歷史提交記錄-git log

git log # 檢視所有commit記錄(SHA-A校驗和作者名稱,郵箱,提交時間,提交說明)
git log -p -次數 # 檢視最近多少次的提交記錄
git log --stat # 顯示提交日誌及相關變動檔案
git log --name-only # 僅顯示已修改的檔案清單
git log --name-status # 顯示新增,修改,刪除的檔案清單
git log --oneline # 讓提交記錄以精簡的一行輸出
git log –graph –all --online # 圖形展示分支的合併歷史
git log --author=作者  # 查詢作者的提交記錄(和grep同時使用要加一個--all--match引數)
git log --grep=過濾資訊 # 列出提交資訊中包含過濾資訊的提交記錄
git log -S查詢內容 # 和--grep類似,S和查詢內容間沒有空格
git log fileName # 檢視某檔案的修改記錄
複製程式碼

如果想定製化顯示提交記錄資訊,也是支援的,使用-pretty進行定製:

git log --pretty=format:\"%an-%h-%s-%H\" -1
複製程式碼

JB的git之旅-git命令列

format是一個佔位符,可以定製要顯示的記錄格式,方便後期提取分析;

以下為常用的格式佔位符寫法以及代表的意義:

選項 說明 選項 說明
%H 提交物件(commit)的完整雜湊字串 %h 提交物件的簡短雜湊字串
%T 樹物件(tree)的完整雜湊字串 %t 樹物件的簡短雜湊字串
%P 父物件(parent)的完整雜湊字串 %p 父物件的簡短雜湊字串
%an 作者(author)的名字 %ae 作者的電子郵件地址
%ad 作者修訂日期(可以用 -date= 選項定製格式) %ar 作者修訂日期,按多久以前的方式顯示
%cn 提交者(committer)的名字 %ce 提交者的電子郵件地址
%cd 提交日期 %cr 提交日期,按多久以前的方式顯示
%s 提交說明

用 oneline 或 format 時結合 --graph 選項,可以看到開頭多出一些 ASCII 字串表示的簡單圖形,形象地展示了每個提交所在的分支及其分化衍合情況。

JB的git之旅-git命令列

以上只是簡單介紹了一些 git log 命令支援的選項,下面還有一些其他常用的選項及其釋義;

選項 說明
-p 按補丁格式顯示每個更新之間的差異。
--word-diff 按 word diff 格式顯示差異。
--stat 顯示每次更新的檔案修改統計資訊。
--shortstat 只顯示 --stat 中最後的行數修改新增移除統計。
--name-only 僅在提交資訊後顯示已修改的檔案清單。
--name-status 顯示新增、修改、刪除的檔案清單。
--abbrev-commit 僅顯示 SHA-1 的前幾個字元,而非所有的 40 個字元。
--relative-date 使用較短的相對時間顯示(比如,“2 weeks ago”)。
--graph 顯示 ASCII 圖形表示的分支合併歷史。
--pretty 使用其他格式顯示歷史提交資訊。可用的選項包括 oneline,short,full,fuller 和 format(後跟指定格式)。
--oneline --pretty=oneline --abbrev-commit 的簡化用法。

還有一些限制輸出長度的方案,比如只想看最近1天或者最新一條的日誌等等;

git log --since=2.weeks  #最近兩週內的提交
複製程式碼
選項 說明
-(n) 僅顯示最近的 n 條提交
--since, --after 僅顯示指定時間之後的提交。
--until, --before 僅顯示指定時間之前的提交。
--author 僅顯示指定作者相關的提交。
--committer 僅顯示指定提交者相關的提交。
–grep 僅顯示含指定關鍵字的提交
-S 僅顯示新增或移除了某個關鍵字的提交

詳細的,可以看看git官網的介紹,點選這裡~

9.檢視某行程式碼誰提交的-get blame

git blame 檔名 # 檢視某檔案的每一行程式碼的作者,最新commit和提交時間
複製程式碼

JB的git之旅-git命令列

10.設定Git命令別名-git config –global alias

每次都要輸入完整的命令,挺麻煩的,比如checkout,那有沒有辦法直接輸入co就可以達到checkout呢?

git config --global alias.st status #此處設定st為別名,作用就是status
複製程式碼

11.給重要的commit打標籤-git tag

一般重要的提交,比如版本釋出的,都需要打上一個標記,以便後續做回滾處理~
列出標籤:

git tag # 在控制檯列印出當前倉庫的所有標籤
git tag -l ‘v0.1.*’ # 搜尋符合模式的標籤
複製程式碼

打標籤:
git標籤分為兩種型別:輕量標籤和附註標籤
輕量標籤是指向提交物件的引用,附註標籤則是倉庫中的一個獨立物件
簡單說,前者只是在提交上加個TAG,指向提交的Hash值;
後者還會儲存打標籤者的資訊,時間和附加資訊;
建議使用附註標籤。

git tag 標記內容 # 輕量標籤
git tag -a 標記內容 -m "附加資訊" # 附加標籤
複製程式碼

建立輕量標籤不需要傳遞引數,直接指定標籤名稱即可。
建立附註標籤時,引數a即annotated的縮寫,指定標籤型別,後附標籤名。
引數m指定標籤說明,說明資訊會儲存在標籤物件中。
如果想為之前的某次commit打TAG的話,可以先找出SHA1值,設定調下述命令:

git tag -a 標記內容 版本id # 比如:git tag -a v1.1 9202ff53
複製程式碼

切換標籤
與切換分支命令相同:

git checkout [tagname]
複製程式碼

新建分支的時候也加上TAG:

git checkout -b 分支名 標記內容
複製程式碼

用show命令檢視標籤對應的資訊:

git show 標記內容
複製程式碼

刪除本地Tag:

git tag -d 標記內容
複製程式碼

刪除遠端Tag:

git push origin --delete tag 標記內容
複製程式碼

預設情況,git push不會把標籤推送TAG到遠端倉庫,如果想推送到伺服器,可以:

git push origin 標記內容 # 推送某標籤到

# 刪除所有本地倉庫中不存在的TAG:
git push origin --tags 
複製程式碼

補打標籤:

git tag -a v0.1.1 9fbc3d0
複製程式碼

12.Git命令自動補全-輸命令的時候按兩次tab鍵

JB的git之旅-git命令列

13.臨時存放工作目錄的改動-git stash

日常生活中,總會遇到需要救火的事情,比如當你在一個分支上編碼時,隔壁同學說,jb,你那個模組有BUG,趕緊修復提交下,當然,也可以commit所有檔案,然後等處理完事情後再commit撤銷回來,但這裡要介紹的是更好用的命令-git stash;

在 Git 中,stash 指令可以幫你把工作目錄的內容全部放在你本地的一個獨立的地方,它不會被提交,也不會被刪除,你把東西放起來之後就可以去做你的臨時工作了,做完以後再來取走,就可以繼續之前手頭的事了。

具體說來,stash 的用法很簡單。當你手頭有一件臨時工作要做,需要把工作目錄暫時清理乾淨,那麼你可以:

git stash
複製程式碼

就這麼簡單,你的工作目錄的改動就被清空了,所有改動都被存了起來。

當你忙完的時候,切回你的分支,然後:

git stash pop
複製程式碼

之前儲存的東西就都回來了。很方便吧?

注意:沒有被 add 過的檔案不會被 stash 起來,因為 Git 會忽略它們。如果想把這些檔案也一起 stash,可以加上 -u 引數,它是 --include-untracked 的簡寫。就像這樣:

git stash -u
複製程式碼

檔案恢復/版本回滾

1.檔案恢復-已經add到暫存區,但未commit-get checkout

假如說,一個檔案被add到暫存區,但是未commit,此時不小心被刪除了,怎麼恢復?

JB的git之旅-git命令列

JB的git之旅-git命令列

上面的截圖是從一個新建檔案到add到再到刪除,可以看的出,工作區的jb.txt被刪除了,但是暫存區裡的jb.txt還未刪除;

# 刪除暫存區中的檔案:
git rm 檔名

#同時刪除工作區和暫存區中的檔案
git rm -f 檔名

#刪除暫存區的檔案,不刪除工作區的檔案
git rm -cached 檔名

# 誤刪恢復檔案
git checkout -- 檔名
複製程式碼

2,撤銷操作

撤銷操作一般有兩種情況:

  • 檔案修改後還沒有提交到暫存區,進行撤銷操作之後,檔案恢復到和版本庫中一模一樣

  • 檔案修改後提交到了暫存區,進行撤銷之後,檔案恢復到在提交到暫存區之前的狀態

      git checkout --檔名
    複製程式碼

3.

1.撤銷操作-git checkout

撤銷操作一般有兩種情況:

  • 檔案修改後還沒有提交到暫存區,進行撤銷操作之後,檔案恢復到和版本庫中一模一樣
  • 檔案修改後提交到了暫存區,進行撤銷之後,檔案恢復到在提交到暫存區之前的狀態

檔案未提交到暫存區

git checkout --檔名
複製程式碼

檔案提交到了暫存區,但未提交到本地倉庫
如果某個檔案寫錯了,想要修改,但是已經add到了暫存區,那需要先撤銷到工作區

git reset HEAD 檔名
複製程式碼

此時檔案已經撤銷到工作區,但是檔案內容是沒變化,如果想要恢復到修改之前的狀態,就要使用:

git checkout -- 檔名
複製程式碼

2.刪除檔案-git rm

# 刪除暫存區中的檔案:
git rm 檔名
    
#同時刪除工作區和暫存區中的檔案
git rm -f 檔名
    
#刪除暫存區的檔案,不刪除工作區的檔案
git rm -cached 檔名
複製程式碼

3.恢復檔案-git reset

如果想要將某個檔案恢復到某個版本時的狀態,可以使用以下的命令:

git checkout id 檔名
複製程式碼

id就是使用git log時的commit id,取前7位即可~

JB的git之旅-git命令列

如果要將所有我呢見都恢復到某個版本,可以用下面的命令:

git checkout id 檔名
複製程式碼

除了用id恢復到某個版本庫時的狀態,還有別的寫法:

//恢復到上一個版本
git reset --hard HEAD^ 
// 恢復到前兩個版本
git reset --hard HEAD~2   或者  git reset --hard HEAD^^
# git log檢視到的commit值,取前七位即可
git reset --hard 版本號 
複製程式碼

4.檢視輸入指令記錄-git reflog

git reflog 可以檢視所有分支的所有操作記錄(包括commit和reset的操作),包括已經被刪除的commit記錄,git log則不能察看已經刪除了的commit記錄,

JB的git之旅-git命令列

5.撤銷某次提交-git revert

有時可能想撤銷某次提交所做的更改,可以使用revert命令

git revert HEAD # 撤銷最近的一個提交
git revert 版本號 # 撤銷某次commit
複製程式碼

特別注意,這裡的撤銷不是真的撤銷,而且生成一個新的提交覆蓋舊的提交,而提交的內容是之前的內容而已,所以,提交記錄還是會存在的,別僥倖哦~

6.檢視某次提交修改記憶體-git slow

git show 提交id # 檢視某次commit的修改內容
複製程式碼

7.檢視某個分支的版本號-git rev-parse

git rev-parse 分支名 # 檢視分支commit的版本號,可以寫HEAD
複製程式碼

8.找回檔案象-git fsck

git fsck --lost-found  #可以查到丟失的記錄
複製程式碼

本地分支

1.分支建立與切換-git branch

git branch 分支名 # 建立分支
git branch # 檢視本地分支

git checkout 分支名 # 切換分支
git checkout -b 分支名 # 建立分支同時切換到這個分支
複製程式碼

2.合併分支-git merge

git merge <name> #合併某分支到當前分支
複製程式碼

3.衝突處理

當在提交一個檔案或者merge的時候,如果也有對應修改的地方,就會出現衝突,與svn不同的是,git就算衝突,內容也是被合併的,此時就需要處理衝突檔案;

開啟檔案後會發現,程式碼中會被<<<<<<< 、=======、>>>>>>>包圍,這是衝突標記:
衝突標記<<<<<<< 與=======之間的內容是我的修改,=======與>>>>>>>之間的內容是別人的修改。

那就要處理,最後記得把符號都幹掉即可~

4.取消merge

當在處理衝突的時候,突然不想merge了,怎麼辦?可以用git merge --abort手動取消~

git merge --abort
複製程式碼

輸入這行程式碼,Git 倉庫就會回到 merge 前的狀態

5.刪除分支

git branch -d 分支名 # 刪除分支,分支上有未提交更改是不能刪除的
git branch -D 分支名 # 強行刪除分支,儘管這個分支上有未提交的更改
複製程式碼

這裡說明下,不能直接刪除當前所在的分支,如果要刪除當前所在的分支,必須要先checkout到別的分支,再刪除之前的分支~

6.恢復誤刪分支

git log --branches="被刪除的分支名" # 找到被刪分支最新的commitb版本號
git branch 分支名 版本號(前七位即可) # 恢復被刪分支
複製程式碼

7.分支重新命名

git branch -m 老分支名 新分支名 # 分支重新命名
複製程式碼

遠端倉庫與遠端分支

1.推送本地倉庫到遠端倉庫-git push

    git remote add origin 遠端倉庫地址  #關聯本地與遠端倉庫
    
    git push -u origin master  
    #將本地倉庫推送到遠端倉庫,-u是首次提交需要,後續都不需要
    git remote set-url origin 遠端倉庫地址 #修改遠端倉庫地址
    
    # 也可以先刪除origin後再新增
    git remote rm origin    # 刪除倉庫關聯
    git remote add origin 遠端倉庫地址 # 新增倉庫關聯
複製程式碼

2.克隆遠端倉庫-git clone

git clone 倉庫地址 # 克隆專案到當前資料夾下
git clone 倉庫地址 目錄名 # 克隆專案到特定目錄下
複製程式碼

3.同步遠端倉庫更新-git pull

git pull #在當前分支直接輸入git pull即可
複製程式碼

4.檢視遠端分支

git branch -r # 檢視所有分支
複製程式碼

5.拉取遠端分支到本地倉庫

git checkout -b 本地分支 遠端分支 # 會在本地新建分支,並自動切換到該分支
git fetch origin 遠端分支:本地分支 # 會在本地新建分支,但不會自動切換,還需checkout
git branch --set-upstream 本地分支 遠端分支 # 建立本地分支與遠端分支的連結
複製程式碼

6.刪除遠端分支

git push origin :分支名 
複製程式碼

關於命令列,大致就介紹到這裡吧,詳細點的資訊,就請移步到git官方查詢文吧:
git-scm.com/book/zh/v2

專案遷移

日常工作中,可能會出現專案遷移的情況,簡單說就是把gitlab專案遷移到其他倉庫那;

這裡先假設,原gitlab地址:git.jbold.com,新gitlab地址:git.jbnew.com

遷移步驟

  1. 檢視目前舊倉庫的gitlab地址

     $ git remote -v
     origin  git.jbold.com:jb/jbtest.git (fetch)
     origin  git.jbold.com:jb/jbtest.git (push)
    複製程式碼
  2. 在新gitlab上新建new專案,生成gitlab地址:

     git@git.jbnew.com/jb/jbtest-new.git
    複製程式碼
  3. 設定本地gitlab地址替換成新的gitlab地址

     jb@LAPTOP-2R0431R1 MINGW64 ~/gitprojects/jbtest (master)
     $ git remote set-url origin git@git.jbnew.com/jb/jbtest-new.git
     
     jb@LAPTOP-2R0431R1 MINGW64 ~/gitprojects/jbtest (master)
     $ git remote -v
     origin  git@git.jbnew.com/jb/jbtest-new.git (fetch)
     origin  git@git.jbnew.com/jb/jbtest-new.git (push)
    複製程式碼
  4. 檢視分支情況

      $ git branch -a
     * master
       remotes/origin/HEAD -> origin/master
       remotes/origin/master
     這裡只有一個master,因此直接推送master
    複製程式碼
  5. 把本地指定分支,推送到集團遠端程式碼倉庫

     $ git push origin master:master
    複製程式碼

就這樣,程式碼就從舊的倉庫地址遷移到新的倉庫地址了

小結

本文主要介紹了常見的git命令,覆蓋到檔案操作,本地分支以及遠端分支相關的操作;
感觸最深的就是git log的定製化功能,真的對於提取內容很方便~

JB的git之旅-git命令列

謝謝大家~

JB的git之旅-git命令列

相關文章