Git 常見指令筆記和Q&A

Git 常見指令筆記和Q&A
git flow
  • HEAD: HEAD 是一個 reference,它是指向目前所 checkout 的 commit,其實就是你目前所在的 commit。在 commit tree 中,HEAD 總是指向最近的一次commit。

git log

用於查看最新 commit 紀錄,可指定顯示的筆數。

git log --oneline -<number>

# 能顯示多少條就顯示多少條
git log --oneline
# 只顯示最新五條
git log --oneline -5

顯示結果:

# $git log --oneline -5
e295702 (HEAD -> main) A
21582f6 B
79e280f C 
b51ec3b D
ad7f577 E

q 離開 git log

基本指令

# 查看 remote 
git remote -v
# 新增 remote repo
git remote add origin <repo>
# 查看當前 working tree
git status
# 新增全部 changes 到暫存區
git add .
# 將暫存區的 changes 提交
git commit -m "msg"
# 將 commit 推上 remote repo,分支名稱為 <branch_name>
git push origin <branch_name>

git branch

# 列出分支列表
git branch -a
# 新增
git branch A
# 刪除本地分支
git branch -d A
# 刪除遠程分支
git push origin --delete A
# 切換
git checkout A

git merge

git merge 用於將 A 分支上的修改合併到 B 分支。

假設要將分支 A 的修改合併到分支 develop 可以這麼操作:

git checkout A
git add .
git commit -m "test"

git checkout develop
git merge A

快轉模式(Fast-forward)

快轉模式合併是 Git 中的一種合併策略(也是預設的模式),它通常發生在以下情況:

  • 你在一個分支上進行了一些提交。
  • 在進行合併操作之前,目標分支(通常是 main 分支)沒有新的提交。

在這種情況下,Git可以簡單地將目標分支 HEAD 前進到與您目前分支的最新提交相同的地方,而不需要建立一個新的 commit。

特性包括:

  1. 不會建立新的合併提交,因為沒有衝突需要解決。
  2. 歷史記錄看起來非常線性,就好像沒有進行合併操作一樣。
  3. 通常用於將特性分支的變更合併到主分支,以保持主分支的更新。
%E8%9E%A2%E5%B9%95%E6%88%AA%E5%9C%96 2019 11 19 13.22.42oh0ud

舉例來說,現在 dev 分支 HEAD 在 c4,而 master 分支的 HEAD 在 C2。
此時我們可以透過 git merge 的方式將 master 的 HEAD 前進到 C4,並且不需要新增額外的合併 commit。

%E8%9E%A2%E5%B9%95%E6%88%AA%E5%9C%96 2019 11 19 13.50.16pdwyt
git checkout master
git merge dev

git rebase

和 git merge 類似都是合併操作,但 git rebase 會修改歷史 commit,它會使分支移動到不同的 Commit 重新定義基準點。

合併版本

git checkout branch1

# 將 mater 當成基準點
git rebase master
git rebase

當基準點改變就需要重新生成 commit 的 SHA-1 值,所以原本的 e3475, 76d12 在修改基準點後變成了 3a2e2, e45ch

修改歷史 commit

$ git rebase -i HEAD~3
git rebase i

取消 rebase 操作

git rebase 指令會導致 Commit 的 SHA-1 值改變,因此不能直接使用 git reset HEAD^–hard 的方式回到合併前的狀態。

需要先使用 git reflog 找回 rebase 操作時 commit 的 SHA-1 值,找到後再使用 git reset <commit> --hard 回到 rebase 前的狀態。

# $git reflog
...
153ab21 (master) HEAD@{3}: rebase: checkout master
b274b5a HEAD@{4}: checkout: moving from master to branch1
...

# $git reset b274b5a --hard
HEAD is now at b274b5a

或者也可以直接使用 git reset ORIG_HEAD --hard 回到 rebase 前的狀態。

ORIG_HEAD 會記錄「危險操作」之前 HEAD 的位置。例如分支合併或是 Reset 之類的都算是所謂的「危險操作」。

git revert & git reset

  • revert: 是在「不破壞歷史紀錄」的前提下撤回指定 commit,並新增一個 revert 的 commit。
  • reset --hard: 此種模式完全不保留原始 commit 結點的任何資訊,會連同資料夾中實體檔案內容都進行重置,也就是直接將工作區、暫緩區及 git 目錄都重置成目標Reset結點的資料內容。
  • reset --soft: 此模式下會保留工作區資料內容,不會異動到目前所有的實體檔案內容;也會保留暫緩區資料內容,讓暫緩區與 git 目錄資料內容是一致的。

revert

revert 是在「不破壞歷史紀錄」的前提下撤回指定 commit。

以下方 commit 紀錄為例,指令 git revert HEAD~2 會撤回 study 的這個 commit 紀錄,並新增一個 commit Revert "study"

# git log --oneline
c0479f5 (HEAD -> main) day
0199749 study
0a38bea third
1ae88ed second
fa3d5af first

# git revert HEAD~

# git log --oneline
fd5db43 (HEAD -> main) Revert "study"
c0479f5 day
0199749 study
0a38bea third
1ae88ed second
fa3d5af first

如果想回到撤回 study 之前,直接 git reset --hard c0479f5,這樣 study 就回來了

reset –hard

git reset --hard

# 回到 HEAD 的前 1 個版本 commit 
git reset --hard HEAD~
# 回到 HEAD 的前 2 個版本 commit 
git reset --hard HEAD~2
# 回到 HEAD 的前 3 個版本 commit 
git reset --hard HEAD~3
...

以下面的 commit 紀錄為例:

  • HEAD~21582f6
  • HEAD~279e280f
  • HEAD~3ad7f577
# $git log --oneline -5
e295702 (HEAD -> main) A
21582f6 B
79e280f C
b51ec3b D
ad7f577  E

不小心使用 hard 模式 Reset 了某個 Commit,救得回來嗎?

  1. git log --oneline 查看 commit 紀錄
c0479f5 (HEAD -> main) day
0199749 study
0a38bea third
1ae88ed second
fa3d5af first
  1. git reset --hard HEAD~2 回到前 2 個版本,log紀錄少了 0199749, c0479f5
0a38bea (HEAD -> main) third
1ae88ed second
fa3d5af first
  1. git reset --hard <commit id> 就可以恢復被 reset 過的 commit
c0479f5 (HEAD -> main) day
0199749 study
0a38bea third
1ae88ed second
fa3d5af first

只需要記住 commit SHA-1 就可以將 HEAD 重新設回被 reset 過的 commit,完整流程如下:

# $git log --oneline
c0479f5 (HEAD -> main) day
0199749 study
0a38bea third
1ae88ed second
fa3d5af first

# $git reset --hard HEAD~2
HEAD is now at 0a38bea third

# $git log --oneline
0a38bea (HEAD -> main) third
1ae88ed second
fa3d5af first

# $git reset --hard c0479f5
HEAD is now at c0479f5 day

# $git log --online
c0479f5 (HEAD -> main) day
0199749 study
0a38bea third
1ae88ed second
fa3d5af first

找回 commit SHA-1 值

可以使用 git reflog

HEAD 有移動的時候就會紀錄(切分支或者reset都會移動HEAD),可以在這裡查看 reset 之前的 commit SHA-1:

0a38bea HEAD@{1}: reset: moving to HEAD~2
c0479f5 (HEAD -> main) HEAD@{2}: commit: day
0199749 HEAD@{3}: commit: study
0a38bea HEAD@{4}: commit: third
1ae88ed HEAD@{5}: commit: second
fa3d5af HEAD@{6}: commit (initial): first

git reset --hard c0479f5 就可以回到 reset HEAD~2 前的 HEAD

git cherry-pick

可以選擇並將指定的 commit 從一個分支應用到另一個分支。

git cherry-pick <commit-hash>

git cherry-pick 對於以下情況很有用:

  1. 合併特定的 commit:選擇合併一個或多個 commit,而不是將整個分支合併到目前分支。
  2. 修復錯誤:如果在一個分支上發現了錯誤,而這個錯誤在另一個分支上已經修復就可以用 git cherry-pick 來將修復的 commit 引入到當前分支,而無需合併整個分支。

Q&A

正在重訂基底

這表示 Git 正在進行 rebase 操作(git rebase)。

image 2

解決方式

  1. 強制退出:執行 git rebase --abort 終止 rebase,這將會復原分支到 rebase 開始前的狀態。
  2. 完成rebase:解完 conflicts -> git add & git rebase --continue -> 繼續解直到沒有 conflicts -> git push

fatal: not a valid object name: ‘main’

可能是因為新 repo 沒有文件所導致的。

解決方式

# 新增文件
git add .
git commit -m "log"

git branch -a 
# 這時候就會出現 main 分支了

You have divergent branches and need to specify how to reconcile them

git push 失敗

image

git pull 失敗

image 1

這是因為 pull 分支之前進行過 merge 合併更新分支操作,而其他人在你之前已經 push 過一個版本,導致版本不一致。

解決方式git config pull.rebase false

skipped previously applied commit xxx

skipped previously applied commit xxx
hint: use --reapply-cherry-picks to include skipped commits. 
hint: Disable this message with "git config advice.skippedCherryPicks false"

解決方式git rebase --reapply-cherry-picks

git rebase –continue: Please enter the commit message for your changes

git rebase --continue 出現:

feat: A

# Please enter the commit messagefor your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# interactive rebase in progress; onto 16832f7
# Last command done (1 command done):
#    pick 7b45117 feat: A
# Next commands to do (5 remaining commands):
#    pick 474bdfd B
#    pick 58b9193 C
# You are currently rebasing branch 'feat/demo' on '16832f7'.
#
# Changes to be committed:
#       ....

解決方式::wq 退出

Reference

留言

目前沒有留言。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *