Git 的 100 個情境應用


  1. 使用的情境
    1. 情境@ 啟用 Git
    2. 情境@ 常用的 Git alias 設定 (git config alias)
    3. 情境@ Git Status UTF-8 檔案名稱被編碼的調整
    4. 情境@ 忽略特定檔案、資料夾 (gitignore)
    5. 情境@ 存入暫存區 (staged) 與遞交至檔案庫 (respository)
    6. 情境@ 補充上一個 commit (amend)
    7. 情境@ 切換到上一個 commit (checkout)
    8. 情境@ 取回上一個版本的特定檔案 (checkout)
    9. 情境@ 比對 Head 與 Unstaged 差異 (diff)
    10. 情境@ 比對 Head 與 Staged 差異 (diff)
    11. 情境@ 比對 Head 與指定 Commit 差異 (diff)
    12. 情境@ 檢查目前的檔案歷次 commit 的異動情形 (blame)
    13. 情境@ 檢視 Commit 紀錄 - 搜尋關鍵字
    14. 情境@ 檢視 Commit 紀錄 - 最近一筆
    15. 情境@ 檢視 Commit 紀錄 - 特定日期
    16. 情境@ 檢視 Commit 紀錄 - 這筆紀錄做了什麼
    17. 情境@ 檢視 Commit 紀錄 - 自定義顯示 format
    18. 情境@ 比較兩筆 Commit 差異
    19. 情境@ 移除檔案與重新命名檔案 (rm, mv)
    20. 情境@ 僅移除 stged 狀態,但保持檔案 (rm –cached)
    21. 情境@ 從特定版本延伸開發 (branch)
    22. 情境@ 放棄目前的所有異動 (reset)
    23. 情境@ 移除特定異動,保留部分異動 (reset)
    24. 情境@ 刪除所有未追蹤的檔案 (clean)
    25. 情境@ 刪除已追蹤,但被 .gitignore 排除的檔案 (clean)
    26. 情境@ 拆除掉目前 Commit (reset)
    27. 情境@ 復原被拆除掉的 Commit (reset)
    28. 情境@ 保存 staged 的檔案,回到正式區修正一些事情 (stash)
    29. 情境@ 保存未 commit 所有檔案,回到正式區修正一些事情 (stash)
    30. 情境@ 取回 Stash 暫存的內容 (stash -u)
    31. 情境@ 取回 Stash 暫存的內容 (stash pop)
    32. 情境@ 取回特定 Stash 暫存的內容 (stash pop)
    33. 情境@ 取回 Stash 但保存在 Stash list (stash apply)
    34. 情境@ 清除 Stash list (stash clear)
    35. 情境@ 用標籤標註歷次發行版本 (tag)
    36. 情境@ 用標籤標註歷次發行版本 (tag -a)
    37. 情境@ 列出所有標籤 (tag)
    38. 情境@ 強制 branch 改指向 commit (git branch -f)
    39. 情境@ 合併分支 (merge)
    40. 情境@ 合併分支,但不啟用 fast-forward (merge –no-ff)
    41. 情境@ Git Commit 的符號參照、相對參照及別名
    42. 情境@ 解析 Git 參照的絕對參照 Sha-1 值
    43. 情境@ reglog 立即 expire (reflog expire)
    44. 情境@ 將檔案庫推送至伺服器 (push)
    45. 情境@ 複製遠端的檔案庫 (clone)
    46. 情境@ 多個推送伺服器目標 (remote add)
    47. 情境@ 推送至指定伺服器目標 (push)
    48. 情境@ 強制覆寫遠端伺服器的 Commit History
    49. 情境@ 確認遠端 (remote show)
    50. 情境@ 同步遠端檔案庫 (pull, fetch)
    51. 情境@ 發送 Pull Requst
    52. 情境@ What is Github flow
    53. 情境@ 使用 Rebase 的情境 (rebase)
    54. 情境@ 使用 Revert 的情境 (revert)
    55. 情境@ 使用 Cherry-pick 的情境 (cherry-pick)
    56. 情境@ 使用 Filter-branch 的情境 (filter-branch)
    57. 情境@ 使用 Filter-branch 的情境 (filter-branch)
    58. 情境@ 關閉自動轉換 CRLF
    59. 情境@ 解決衝突,使用來對方的資料取代自己的
    60. 情境@ Remote Commits is messy 清空遠端 Commits

使用的情境

如同學習 Gulp 的經驗,直接用需求情境的方式學習新工具是最有效率的,因為情境的需求是與自己切身相關的,而非代入生冷的範例。

  1. 創造屬於自己的情境
  2. 跟著情境實際操作
  3. 將技能融入自己的日常作業流程

情境@ 啟用 Git

Git 博大精深卻十分精簡,有關該專案的版本控制一切相關資訊都只關乎於專案下的 .git 資料夾,而要另一個專案開始啟用 Git 的版本控制機制,僅需要輸入下列指令:

cd folder
git init

情境@ 常用的 Git alias 設定 (git config alias)

git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.sts "status -s"
git config --global alias.br branch
git config --global alias.re remote
git config --global alias.di diff

情境@ Git Status UTF-8 檔案名稱被編碼的調整

git config --global core.quotepath false

情境@ 忽略特定檔案、資料夾 (gitignore)

一旦啟用 git init 後,專案下的任何新增檔案都會被視為 untracked,這個時候可以藉由設定 gitignore 來告訴 git 忽略掉某些特定的檔案,不要管其異動差別,並且不要放置檔案庫中。通常是編譯過程中產生的檔案或者 npm modules 資料夾等。

使用的方式就是在專案目錄下加入一個 .gitignore 檔案,檔案內所羅列的檔案、資料夾路徑、檔案類型就會自動被 git 所排除。

# 忽略所有 txt 副檔名的檔案
*.txt

# 忽略 node_modules 資料夾
mode_modules/

# 忽略目前目錄下的 dir 資料夾,但不忽略子資料夾中的 dir 資料夾
/dir

# 忽略所有 dir 資料夾下的 txt 檔案
/dir/**/*.txt

情境@ 存入暫存區 (staged) 與遞交至檔案庫 (respository)

# 加入暫存區 (staged)
git add .
# 送入檔案庫 (respository)
git commit -m "備註訊息"

情境@ 補充上一個 commit (amend)

echo "new file" > file.txt
git commit --amend "訊息"

情境@ 切換到上一個 commit (checkout)

git checkout head~

但這樣會出現 Head detached 的情形,正確的方式應該是建立分支,並且切換至分支。

情境@ 取回上一個版本的特定檔案 (checkout)

git checkout 9ee1a27 app.js 

情境@ 比對 Head 與 Unstaged 差異 (diff)

git diff

情境@ 比對 Head 與 Staged 差異 (diff)

git diff --cached

情境@ 比對 Head 與指定 Commit 差異 (diff)

git diff commitId

情境@ 檢查目前的檔案歷次 commit 的異動情形 (blame)

git blame app.js

情境@ 檢視 Commit 紀錄 - 搜尋關鍵字

git log -S "keyword in comment"

情境@ 檢視 Commit 紀錄 - 最近一筆

git log -1

情境@ 檢視 Commit 紀錄 - 特定日期

git log --since="2020-05-27" --until="2020-05-28"

情境@ 檢視 Commit 紀錄 - 這筆紀錄做了什麼

git show 0ba3a74 --stat

情境@ 檢視 Commit 紀錄 - 自定義顯示 format

git log --pretty="%h - %cr - %s" 
選項 輸出說明
%H 該提交 SHA-1 雜湊值
%h 該提交簡短的 SHA-1 雜湊值
%T 「樹(tree)」物件的 SHA-1 雜湊值
%t 「樹」物件簡短的 SHA-1 雜湊值
%P 親代(parent)提交的 SHA-1 雜湊值
%p 親代提交簡短的 SHA-1 雜湊值
%an 作者名字
%ae 作者電子郵件
%ad 作者日期(依據 –date 選項值而有不同的格式)
%ar 作者日期,相對時間格式。
%cn 提交者名字
%ce 提交者電子郵件
%cd 提交者日期
%cr 提交者日期,相對時間格式。
%s 標題

資料參考

情境@ 比較兩筆 Commit 差異

git diff 0ba3b74 a379a71 

情境@ 移除檔案與重新命名檔案 (rm, mv)

已經加入 staged 的話可以透過 git rm 移除 staged並刪除檔案,如果仍在 untracted 階段直接 rm 即可。

echo "untrackted" > untracked.js
rm untrackted.js
echo "unwnated" > untracked.js
git add .
git rm unwanted.js

情境@ 僅移除 stged 狀態,但保持檔案 (rm –cached)

echo "unwnated" > unwanted.js
git add .
git rm unwanted.js --cached
# unwanted.js is untracked

情境@ 從特定版本延伸開發 (branch)

git checkout 9ee1a27 -b dev-branch
echo dev > dev.txt
git add .
git commit -m "dev-branch new commit"

情境@ 放棄目前的所有異動 (reset)

echo "隔著不回頭看的時間 回憶積雪 疊成冬天" > regret.txt
git add .
# oops, I don't need regret.txt anymore
git reset head --hard

情境@ 移除特定異動,保留部分異動 (reset)

echo "隔著不回頭看的時間 回憶積雪 疊成冬天" > regret.txt
echo "I really need this" > keep.txt
git add .
# oops, I don't need regret.txt anymore, but keep keep.txt
git reset head
# regret.txt and keep.txt is untracked now
rm regret.txt

情境@ 刪除所有未追蹤的檔案 (clean)

echo "unwanted" > unwanted.txt
# unwanted.txt is untracked
git clean -f
# unwanted is removed

情境@ 刪除已追蹤,但被 .gitignore 排除的檔案 (clean)

git clean -fX

情境@ 拆除掉目前 Commit (reset)

git reset head~ --hard

情境@ 復原被拆除掉的 Commit (reset)

git reflog
git reset commitId --hard

情境@ 保存 staged 的檔案,回到正式區修正一些事情 (stash)

git stash

情境@ 保存未 commit 所有檔案,回到正式區修正一些事情 (stash)

保存 staged 及 untracked 的檔案,原理是創造一個 staged commit 及 untracked commit 並且合併為一個 stash branch。

git stash -u

情境@ 取回 Stash 暫存的內容 (stash -u)

取回的方式預設是後進先出(LIFO),原理是將 stash 分支合併回目前的分支。

git stash pop

情境@ 取回 Stash 暫存的內容 (stash pop)

取回的方式預設是後進先出(LIFO)

git pop

情境@ 取回特定 Stash 暫存的內容 (stash pop)

取回的方式預設是後進先出(LIFO)

git stash list
git stash pop "stash@{1}"

情境@ 取回 Stash 但保存在 Stash list (stash apply)

取回的方式預設是後進先出(LIFO)

git stash list
git stash apply "stash@{1}"

情境@ 清除 Stash list (stash clear)

取回的方式預設是後進先出(LIFO)

git stash clear

情境@ 用標籤標註歷次發行版本 (tag)

輕量標籤 (lightweight tag) Commit 的別名用途;標籤和分支的差別在於分支會隨著 Commit 而移動,但標籤只會保持在同一個 Commit 上。

git tag tagName commitId

情境@ 用標籤標註歷次發行版本 (tag -a)

標示標籤 (annotated tag) tag 物件,能夠另外帶有訊息。

git tag tagName commitId

情境@ 列出所有標籤 (tag)

git tag

情境@ 強制 branch 改指向 commit (git branch -f)

git branch -f master commitId

情境@ 合併分支 (merge)

git merge branchName

情境@ 合併分支,但不啟用 fast-forward (merge –no-ff)

git merge branchName --no-ff

情境@ Git Commit 的符號參照、相對參照及別名

項目 說明
HEAD 指向當前分支的最新 commit
ORIG_HEAD Head Commit 的前一版
@ HEAD 的別名
HEAD~n HEAD 前n代 parent commit
HEAD^n HEAD 有n個 上層 parent commit 時選擇其一

情境@ 解析 Git 參照的絕對參照 Sha-1 值

git rev-parse master
git rev-parse HEAD
git rev-parse @
git rev-parse HEAD^
git rev-parse HEAD~2
git rev-parse ORIG_HEAD

情境@ reglog 立即 expire (reflog expire)

git reflog expire --all --expire=now
git fsck --unreachable
git gc --prune=now

情境@ 將檔案庫推送至伺服器 (push)

git remote -v
git push

情境@ 複製遠端的檔案庫 (clone)

git clone [url|ssh] folderName

情境@ 多個推送伺服器目標 (remote add)

git remote add abbr [url|ssh]

情境@ 推送至指定伺服器目標 (push)

#git push [remote-name] [branch-anme]
git push origin master

情境@ 強制覆寫遠端伺服器的 Commit History

git push -f

情境@ 確認遠端 (remote show)

git remote show origin

情境@ 同步遠端檔案庫 (pull, fetch)

git pull

情境@ 發送 Pull Requst

情境@ What is Github flow

情境@ 使用 Rebase 的情境 (rebase)

剪下分支,並依照指定的基準貼上分支。

Before Rebase
After Rebase

git rebase [new base commitId]

情境@ 使用 Revert 的情境 (revert)

用一個新的 Commit 的還原某個 Commit 的動作,在共用檔案庫的情境尤其適用,避免造成別人的 Commit History 混亂。

git revert commitId

情境@ 使用 Cherry-pick 的情境 (cherry-pick)

揀選特定的 Commit 並依序新增為新的 Commit。

Before Cherry-pick
In Cherry-pick
After Cherry-pick

git cherry-pick commitId1 commitId2 ...

情境@ 使用 Filter-branch 的情境 (filter-branch)

情境@ 使用 Filter-branch 的情境 (filter-branch)

情境@ 關閉自動轉換 CRLF

git config --global core.autocrlf false

情境@ 解決衝突,使用來對方的資料取代自己的

git checkout --theirs conflict.txt
git add .
git commit -m "fix conflict : accept theirs"

合併發生衝突了 | 那如果不是文字檔的衝突怎麼解?

情境@ Remote Commits is messy 清空遠端 Commits

使用的原理是先將最後 Commit 另存為其他 Branch,並將原本的 Master Branch 刪除後,重新創造 Master Branch,並且再 push 到 Github。

git checkout --orphan latest_branch 
&& git add -A 
&& git commit -am "update" 
&& git branch -D master 
&& git branch -m master 
&& git push -f origin master

如果要處理 Hexo Deploy Git Commits 必須切換到:

Github\blog\.deploy_git