命令列玩轉 Git

語言: CN / TW / HK

引言

本文介紹常用的命令列工具以及常用的 Git 命令。本文適合使用過 Git,在命令列下使用不熟悉的讀者,其次熟悉 vim 簡單操作會有較大幫助。閱讀完本文,讀者應該熟悉命令列下 Git 操作流程,能處理常見的 Git 問題,經過練習之後可以提升自己的工作效率。

軟體安裝

Iterm2

iTerm2 - macOS Terminal Replacement是一個 Mac 下的終端工具。進入官網下載安裝即可,下面是官網介紹。

iTerm2 is a replacement for Terminal and the successor to iTerm. It works on Macs with macOS 10.14 or newer. iTerm2 brings the terminal into the modern age with features you never knew you always wanted.

Oh My ZSH

Oh My Zsh 是一個輕量的、開源的、社群驅動管理 zsh 配置的工具。下面是官網介紹。

Oh My Zsh is a delightful, open source, community-driven framework for managing your Zsh configuration

在命令列中執行下面的命令安裝 Oh My ZSH,其他安裝方式見 oh my zsh github 或者 Oh My Zsh

shell sh -c "$(curl -fsSL http://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Oh My ZSH 外掛

安裝好 Oh My ZSH 之後當前使用者目錄下會有一個配置檔案叫做 .zshrc

image.png

其中一行是我們的外掛配置,使用的 oh my zsh 外掛都必須新增進去,如下:

image.png

git 外掛

預設開啟,無需配置,git 外掛是後面的重要主題。

Z 外掛

Z 目錄跳轉外掛。注意安裝外掛後,只有再次訪問過的目錄才會被 Z 識別。新增到 oh my zsh 的配置檔案 ~/.zshrc 中,見外掛配置。

image.png

如圖,我們第一次使用 z mytest 沒有進入 mytest 目錄,當我們使用 cd mytest 以後再次嘗試成功進入 mytest 。事實上我們使用 z myz test 都是可以的。

zsh-autosuggestions

zsh-autosuggestions 是一款命令列提示外掛。使用下面的命令安裝,並且新增到 oh my zsh 的配置檔案 ~/.zshrc 中,見外掛配置。

git clone http://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

下圖中用紅色標出的灰色部分是提示部分。

image.png

git-open

git-open git-open 是一款快速在命令用瀏覽器快速開啟當前 git 專案的的外掛。使用下面命令進行安裝,並且新增到 oh my zsh 的配置檔案 ~/.zshrc 中,見外掛配置。

shell git clone http://github.com/paulirish/git-open.git $ZSH_CUSTOM/plugins/git-open 在倉庫目錄執行 git-open 瀏覽器就能幫你開啟當前專案。

Git 命令列 gui

extrawurst/gitui 是一款命令列 ui 工具。不是本文重點,作為推薦工具,感興趣的朋友參見官網學習。效果圖如下:

image.png

Git

基本設定

git config

git config 命令用於設定 Git 倉庫的配置。全域性配置檔案在 ~/.gitconfig,倉庫的配置檔案在 you-repo/.git/config。通常將自己的個人配置設定為全域性的,公司的配置按照倉庫設定。

配置使用者名稱和郵箱

```shell

倉庫配置

git config user.name "your name" git config user.email '[email protected]'

全域性配置

git config --global user.name "your name" git config --global user.email '[email protected]' ```

配置拉取程式碼的合併模式

Git 預設使用 merge 模式,當前本地和遠端都有修改時,這種模式會生成新的不必要的提交,如下為原來 commit:

image.png

執行 git pull 之後的 commit:

image.png

可以看到我們多了一個合併程式碼的提交。在同一個分支,這個合併提交不是我們需要的。為此我們可以用下面的命令設定,建議設定為全域性:

shell git config --global pull.rebase true

重要命令

接下來結合 oh my zsh 的 Git 外掛,著重介紹開發最常用 Git 命令。Git 外掛的配置檔案在 ~/.oh-my-zsh/plugins/git/git.plugin.zsh。主要是對常用 git 命令進行別名,我們也可以通過下列命令查詢相關命令的別名:

shell alias | grep "git commit"

image.png

下面主要通過別名介紹相關命令。

git status

檢視當前倉庫的狀態。這個命令非常重要,每次執行操作前後都要看一下狀態,當前狀態是否適合執行命令和是否執行命令成功。

shell gst='git status'

git commit

commit命令記錄改變,主要掌握兩個命令。

命令一:提交一個修改到新的提交 ```shell

別名

gcam='git commit -a -m'

例項

gcam "feat: this is a commit messsage" 命令二:提交當前修改到前一個提交,並且不編輯提交訊息。shell

別名

gcan!='git commit -v -a --no-edit --amend'

例項

gcan! ```

git checkout

命令一:建立分支並切換

```shell

別名

gcb='git checkout -b'

例項

gcb feat/user_module_dev ```

命令二:切換到某個分支或者提交

```shell

別名

gco='git checkout'

例項

gco feat/user_module_dev gco 31c98c8 gco - # 切回上一個分支 gcm #切換到主分支 gcd #切換到開發分支 ```

git log

命令一:檢視當前分支的 log

```shell

別名

glol='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'\'

例項

glol ``` 命令二:檢視當前分支的 log,並且顯示每次修改的檔案。

```shell

別名

glols='git log --graph --pretty='\''%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%ar) %C(bold blue)<%an>%Creset'\'' --stat'

例項

glols ```

git diff

命令一: 檢視工作區的修改

```shell

別名

gd='git diff'

例項

gd ```

命令二: 檢視暫存區的修改

```shell

別名

gds='git diff --staged'

例項

gds ```

git show

檢視每次提交的內容

```shell

別名

gsh='git show'

例項

gsh # 檢視當前最新提交 gsh HEAD # 同上,也可以用 gsh head

gsh HEAD~1 # 檢視次新提交,也可以用 gsh head^ gsh HEAD~2 # 檢視次次新提交,也可以用 gsh head^^ ```

git push

命令一:強制推送程式碼到遠端,有衝突時則拒絕。

```shell

別名

gpf='git push --force-with-lease'

例項

gpf ```

命令二:將本地新分支推送到遠端

```shell

別名

gpsup='git push --set-upstream origin $(git_current_branch)'

例項

gpsup ```

git reset

命令一:git reset --hard 此命令會丟棄修改,慎用。

```shell

別名

grhh='git reset --hard'

例項

grhh # 丟棄工作區和暫存區的改動 grhh head^ # 丟棄最新的提交 grhh head^^ # 丟棄最新的和次新的提交

grhh 31c98 # 刪除比 31c98 新的提交 ```

命令一:git reset --soft

```shell

別名

grh='git reset'

例項

grh --soft 31c98 # 將比 31c98 新的所有改動移動到暫存區,適合將許多個提交合併成一個的場景。 ```

git rebase

前面介紹的命令都比較簡單易學,下面開始介紹 git rebase 命令,它相對複雜,但是也相對重要很多。看看Git - git-rebase Documentation解釋。

git-rebase - Reapply commits on top of another base tip

一句話解釋就是,將某些提交變基。看一個官方的例子。

image.png

topic 是基於 master 切出來的分支,已經有了 ABC 三個新的提交。現在 topic 分支想要更新 master 分支的程式碼,可以在 topic 上使用下面的命令。

```shel

別名

grb='git rebase' grbm='git rebase $(git_main_branch)'

例項

grb master grbm ``` 下面執行完成功之後的樣子。

image.png

git rebase 有衝突的情況

topic 分支有多個領先 master 分支的提交,git rebase 是一個一個分別處理。比如上文所示,先處理 A 提交,沒有衝突或者衝突處理完成以後再處理 B 提交,以此類推。下面介紹有衝突的情況。

有一個名稱為 rebase_main 的分支,最新提交如下:

image.png

另外有一個名稱為 rebase_feat 的分支,最新提交如下:

image.png

接下來在 rebase_feat 分支執行 grb rebase_main,結果如下。

image.png

根據 Git 提示,我們知道以下幾點:

  • rebase 操作導致了檔案內容衝突,檔名稱為 README.md。
  • 我們必須手動解決衝突,並且標記衝突已經解決。
  • 解決衝突後,我們要使用 git add 表明已經解決了衝突,然後使用 git rebase --continue 命令告訴 Git 繼續執行 rebase 操作。
  • 使用 git rebase --skip 命令丟棄當前衝突的提交,即 rebase_feat 分支的最新提交。
  • 使用 git rebase --abort 命令放棄本次 rebase 操作,回到之前的狀態。

下面我們開始解決衝突:

第一步:檢視衝突的檔案,刪除或者合併程式碼。

合併之前

image.png

怎麼合併程式碼按照你的需求決定,可以選擇只留下 rebase_main 分支的內容,或者只留下 rebase_feat 分支的內容,或者二者皆留下,或者二者皆丟棄,或者手動修改新增。

合併以後

image.png

第二步:執行 git add,如下圖。

image.png

第三步:執行 git rebase --continue,執行此操作會讓你編輯提交資訊。執行成功後如下圖。

image.png

如果 rebase_feat 分支多個新的提交,每個提交都有衝突,需要按照上述方式一個一個的解決。

git rebase -i

對從某個提交開始到最新的提交進行編輯、合併、改變順序、刪除等操作。有兩種形式。

第一種:grbi 57cebe6,不包含 57cebe6 提交。 第二種:grbi HEAD~3,表示對最新的三個提交進行操作,這是比較常用的形式,下面著重對其進行介紹。

首先檢視一下目前的提交。

image.png

然後執行 grbi HEAD~3 對最新的三個提交進行操作。

image.png

對照列出命令依次說明

  • pick,預設需要此提交,無變化。
  • reword,需要此提交,但是編輯提交資訊。
  • edit,需要此提交,能編輯提交資訊和提交內容,與 reword 差異見 git rebase - what's the difference between 'edit' and 'reword' - Stack Overflow
  • sqush,將當前提交合併到前一個提交,需要編輯提交訊息。
  • fixup,和 sqush 類似,但是不需要編輯提交資訊。
  • drop,刪除此提交
  • 改變提交在檔案中的位置,也即改變了提交在 git 中的位置。比如把提交 150dc6057cebe6 在檔案中的順序就能改變它們在 git 中的順序。

以上是常用的命令,其他命令可以對照官網進行學習,下面以 sqush 為例,演示使用流程。

第一步:編輯 pick -> s,然後儲存。

image.png

第二步:進入資訊重新編輯頁面,編輯資訊,然後儲存。如果過程中發生衝突,按照 rebase 有衝突的情況進行解決。

image.png

下面是最新兩個提交的結果

image.png

git chery-pick

git chery-pick 用於將一個或者多個提交應用到目前分支。如果有衝突,和 git rebase 的處理流程一樣。

主要有三個命令。

```shell

別名

gcp='git cherry-pick' gcpa='git cherry-pick --abort' gcpc='git cherry-pick --continue'

例項

gcp 150dc60 # 將提交 150dc60 應用於當前分支 gcpa # 放棄當前操作 gcpc # 解決衝突後,繼續執行 cherry-pick 操作 ```

總結

  • 所有別名只需要簡單的記憶,忘記了就用 alias | grep 'git commit' 查詢相關的功能。
  • git rebase 命令相對複雜,需要多體會,多實踐。
  • 上述命令基本可以滿足日常開發需要,也可以嘗試 gituitig 等命令列 ui。
  • 最好熟悉一下 vim 編輯檔案的操作。
「其他文章」