Git Cheat Sheet
SourceTree 快速鍵
SourceTree 是一款提供 GUI 界面來管理 Git 版本控制內容的軟體。
常用快速鍵:
- Ctrl + 1 切換到 Workspace 下的 File Status 頁面,用於提交變更
- Ctrl + 2 切換到 Workspace 下的 History 頁面,用於查看分支
- Ctrl + 3 切換到 Workspace 下的 Search 頁面,用於搜尋提交相關資訊
- Shift + Ctrl + P Push 推送 Git 提交到遠端
- Shift + Ctrl + L Pull 取得遠端 Git 提交
- Shift + Ctrl + F Fetch 遠端 Git 分支資訊
REF: SourceTree Keyboard Shortcuts
只取得最新的 commit
# 複製儲存庫時,取得指定分支且不包含完整的歷史紀錄
git clone -b ${BRANCH_TO_BUILD} --depth 1 --single-branch ${REPO_URL}
Git Log
在終端機中查看 Git Tree 可參考下列指令:
git log --graph --all --oneline --decorate --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
執行下列指令可建立 alias,直接下 git tree 即可
git config --global alias.tree "log --graph --all --oneline --decorate --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'"
建議搭配 git log -[Length] 參數,只顯示前幾筆紀錄,例如 git tree -20
只顯示前 20 筆紀錄
關於 git log 參數說明,可參考此文件。
Pro Git
此為精進 Git 技巧的書籍,有善心人士幫忙翻譯成中文電子版,幾乎所有的用法和技巧裡面都有交代到。
gitignore 大全
- Github - A collection of useful .gitignore templates:各項專案可參考使用的
.gitignore
- .gitignore for VisualStudio
curl -o .gitignore https://raw.githubusercontent.com/github/gitignore/master/VisualStudio.gitignore
基本指令
建立 Repository
$ git init
$ git add README
$ git status
$ git commit -m "First Commit"
常用指令
$ git status # 查看發生改動的文件列表
$ gitk # 圖形化工具查看文件改動,Git 自帶的圖形化界面
$ git checkout . # 取消所有修改
$ git checkout xxxFile # 取消某個文件的修改
$ git add -A # 新增所有修改
$ git commit -m 'commit message' # 提交修改
$ git push # 提交程式碼到遠程分支, 預設使用 origin 作為名稱
$ git pull # 從遠程倉庫獲取最新程式碼
$ git fetch # 從遠程獲取 branch/tag 訊息
$ git branch # 查看本地分支, -r 查看遠程分支, -a 查看所有
$ git checkout develop # 切換到 develop 分支, -b 新建並切換到分支
$ git merge develop # 將 develop 分支 merge 到當前分支
$ git tag # 查看 tag
$ git tag -a v1.0 -m 'tag message' # 新增 tag
$ git push --tags # 同時推送 tag 到遠程倉庫
$ git help xxxCmd # 查看幫助文件, 會用瀏覽器打開 html 文件
$ git config --global user.name "User-Name" # Git 設定, --global 全局生效
tag 常用指令
$ git tag # 查看本機 tag
$ git tag TAG_NAME # 新增 tag
$ git tag -a TAG_NAME -m 'tag message' # 新增 tag 同時建立提交訊息
$ git tag -d TAG_NAME # 刪除本機 tag
$ git push -d origin TAG_NAME # 刪除遠端 tag
使用 Stash 暫存功能
$ git stash # 暫存本地修改
$ git stash pop # 恢復暫存的修改
進階指令
檔名大小寫的重新命名
Git 對於檔名的處理是大小寫不分的(case-insensitive)
如果只是把 program.cs
改為 Program.cs
,用 git status
會看不到任何改變,請使用下列命令列處理
$ git mv -f program.cs Program.cs
如果是資料夾名稱要做大小寫修改了話,則需要兩個步驟,才能變更成功
$ git mv -f folder temp
$ git mv -f temp FOLDER
修改版控資料夾名稱
使用 rename
或 move
做資料夾更名
git mv <old name> <new name>
Windows 中檔名過長的問題
在 Windows 上使用 SourceTree 做 Git 版控的時候,當有檔案的儲存路徑超過 4096 字元,就會出現下列錯誤訊息 Filename too long
。
解決方案,請使用系統管理員權限開啟命令提示字元,接著輸入以下指令:
git config --system core.longpaths true
還原上一(多)個 Commit
基本上有兩種指令可以用 reset
和 revert
。
reset
比較強烈一點,會把前面的 Commit 移除,因此如果該 Commit 已經提交到遠端上時,搭配 git push -f
才能強制 Commit 給覆蓋到遠端。
另一種 revert
比較溫和,不會把前面的 Commit 移除,而是會建立一個新的 Commit 來記錄你要還原哪個指定的 Commit 內容,而透過下列指令可以還原前面多個 Commit:
git revert --no-commit HEAD HEAD~1 HEAD~2
上面的指令搭配 --no-commit
讓 revert
指令在還原後不要馬上建立一個新的 Commit 點,並且透過指定 Commit 點來還原,而上面的 HEAD HEAD~1 HEAD~2
則是代表當前、前一個、前前一個 Commit 點。
REF: Git - how to revert multiple recent commits
拋棄所有尚未 Commit 的資料
$ git reset --hard #to discard changes made to versioned files
$ git clean -xdf #to erase new (untracked) files, including ignored ones (the x option). d is to also remove untracked directories and f to force.
找尋遺失的 Commit 紀錄
建議只要開發到一定的階段,務必要下一個 Commit 當作記錄,只要 Commit 過 Git 都會有紀錄,即便是”剛剛”被刪掉的!
如果不小心下了 git reset --hard HEAD^
,於是上一個 Commit 就會消失了,可以使用 git reflog
指令然觀看開發者全部 git 的操作記錄,裡面詳細記載你曾經下過的 git 指令,然後透過這個紀錄將剛剛的 Commit 救回來。
$ git reflog
794be8b HEAD@{0}: reset: moving to HEAD^
5e2be6f HEAD@{1}: commit (amend): update
bfa593c HEAD@{2}: cherry-pick: update
794be8b HEAD@{3}: reset: moving to 649c658
794be8b HEAD@{4}: reset: moving to HEAD^
649c658 HEAD@{5}: commit: update
794be8b HEAD@{6}: commit (initial): addd
執行 git reflog
可以看到類似上面的 Commit 的記錄,接著可以透過 git reset --hard xxxxx
,或者是用 git cherry-pick xxxxx
將其中一個 Commit ID 記錄抓回來。
取得版控庫中特定資料夾的內容
版控庫的檔案數量很多,但是只想要取得其中的某個資料夾下的檔案時,可以使用 git sparse-checkout
指令。
https://github.com/dotnet/samples/blob/main/core/nativeaot/NativeLibrary/NativeLibrary.csproj
git clone --depth 1 --single-branch -b main --filter=blob:none --sparse https://github.com/dotnet/samples.git
git sparse-checkout set core/nativeaot/NativeLibrary
git clone --depth 1 --single-branch -b main --filter=blob:none --sparse [GIT_URL]
cd [FOLDER]
git sparse-checkout set [SUBFOLDER_PATH]
簽出 PR 程式碼
參考:How can I check out a GitHub pull request?
Pull Request(PR) 不是 Commit 點也不是分支,要將 PR 程式碼簽出至本機,可以透過下列兩種方式:
# 指定遠端的 PR ID,例如 939
$ git pull origin pull/939/head
# 取得遠端 PR 資訊並建立分支,BRANCHNAME 為自訂的分支名稱
$ git fetch origin pull/ID/head:BRANCHNAME
# 再切換到該分支
$ git checkout BRANCHNAME
以上的動作,是會將 PR 的提交抓下來後,將 HEAD 切到該 PR 的提交點,作為當前的工作目錄。
修改提交的 PR 程式碼
通常 PR 的提交者會允許原始專案的維護者編輯該 PR,在 PR 的頁面右下角會看到下面這樣的圖示:
如果該選項有打勾,則原始專案的維護者可以透過下面的指令,將修改後的程式碼提交到提交 PR 作者的分支中。
git push git@github.com:[USER/REPO] [LOCAL_BRANCH_NAME]:[REMOTE_BRANCH_NAME]
[USER/REPO]
提交 PR 的作者及專案名稱[LOCAL_BRANCH_NAME]
本機要提交的分支名稱[REMOTE_BRANCH_NAME]
遠端要接受提交的分支名稱
REF: Adding commits to another person’s pull request on GitHub
刪除遠端和本地端的分支
http://stackoverflow.com/questions/2003505/delete-a-git-branch-both-locally-and-remotely As of Git v1.7.0, you can delete a remote branch using
$ git push origin --delete <branchName>
刪除遠端和本地端的 Tag
# 刪除本地端的 Tag
git tag -d TagName
# 刪除遠端的 Tag
git push origin :refs/tags/TagName
# 刪除本地端的 Tag 然後使用推送來刪除遠端的 Tag
git tag -d TagName
git push --delete origin TagName
更新成符合 .gitignore 設定的追蹤狀態
只要檔案有被提交過,就會持續被 Git 所追蹤,因此再建立 .gitignore
之前,就已經提交檔案了話,那麼即使再從 .gitignore
內加入新規則,也無法排除已經被追蹤的檔案。
.gitignore
只能忽略那些沒有被追蹤的檔案 (Untracked Files)。
如果想要使更新後的 .gitignore
設定生效,排除已經被追蹤過的檔案時,可以參考以下步驟:
- 清除本機 Git 的快取,相當於將所有檔案移除,但沒有刪除檔案
- 重新加入 Git 追縱,這時會套用
.gitignore
設定 - 提交,這個提交內容會是將排除的檔案刪除
git rm -r --cached .
git add .
git commit -m 'update .gitignore'
下載 .gitignore 設定檔
建立以下 git alias:
# 必須是 Windows 平台執行以下設定
git config --global alias.ignore '!gi() { curl -sL https://www.gitignore.io/api/$@ ;}; gi'
# 必須是 Linux/macOS 平台執行以下設定
git config --global alias.ignore '!'"gi() { curl -sL https://www.gitignore.io/api/\$@ ;}; gi"
就可以使用以下方式,快速建立 .gitignore 設定檔:
# 取得範本清單
git ignore list
# 下載 Visual Studio 範本
git ignore vs > .gitignore
# 下載 Visual Studio Code 範本
git ignore vscode > .gitignore
# 同時下載 Visual Studio 與 ASP NET Core 範本
git ignore visualstudio,aspnetcore > .gitignore
REF: 如何設定 git ignore 命令並自動下載所需的 .gitignore 範本
透過 https 下載套件,取代 git protocol
現在前端套件幾乎都會透過 Bower 來下載,而 Bower 預設使用 git protocol 來下載原始檔案,如果遇到 timeout 逾時,也就是無法透過 git://
方式,就必須要切換成 https://
下載,切換方式很容易,請在 Console 鍵入底下指令:
$ git config --global url."https://".insteadOf git://
SSL 憑證失敗的快速臨時解法
當遇到 SSL 憑證問題時,也就是出現 SSL certificate problem: unable to get local issuer certificate
這個錯誤訊息的時候,可以使用下列指令忽略 SSL 憑證問題,但這只是臨時解法,不建議長期使用。
git config --global http.sslVerify false
建議用完改回原本的設定,以免造成安全性問題。
移除 Git 歷史紀錄
移除前次 commit
git reset
可以砍掉 commit 重來,但修改的程式依然存在:
git reset HEAD^
執行上列指令就會回到前一版本,其中 ^
表示是前一版,可以使用多個 ^
來回到多前 n 版。
此指令常用於發現前一次 commit 有問題時,可以回到前一次 commit,並於修改後再重新 commit。
將檔案加入上一個 commit
REF: How to add a file to the last commit in git?
如果已經 commit 了,但想將再加入檔案時,可以下列指令
git add THE_FILE_YOU_WANT_TO_ADD
git commit --amend --no-edit
--no-edit
參數允許你修改上一個 commit 的內容,而不修改其 commit 訊息
設定 Git 自訂指令
可以使用 git config alias.CUSTOME CUSTOM_COMMAND
來設定自訂指令,之後執行 git CUSTOME
就可以了
推薦執行下列指令,建立 git ll
顯示簡易的命令列線圖
$ git config --global alias.ll "log --pretty=format:'%h %ad | %s%d [%Cgreen%an%Creset]' --graph --date=short"
協作專案時常用指令
- 自訂 push/fetch 不同的來源
_ 透過
git config
設定 _git config --local remote.origin.url <fetchurl>
_git config --local remote.origin.pushurl <pushurl>
_ 透過git remote
設定 _git remote set-url origin <fetchurl>
_git remote set-url origin --push <pushurl>
_ 查看遠端儲存庫設定 _git remote -v
Git 內部細節
.git 資料夾
.git
資料夾包含整個版控的設定及歷史紀錄 * 這也是完整的儲存庫備份
資料結構
整個 Git 的資料結構主要由四種物件組成
- 物件(Object)
_ 執行
git add
,git tag
指令就會產生物件 _ 查看物件的指令git cat-file -t [SHA-1]
_ SHA-1 是使用檔案內容做 HASH 所產生的 _-t
顯示該物件的類別 _-s
內容大小 _-p
顯示內容 _ blob _ 紀錄資料快照,不存檔名 _ tree _ 這裡面會有檔名和 Object 的對照 _ commit _ 裡面的 author 和 committer 可能是不同的 _ 當使用 rebase 的時候,會重新 commit 原作者的內容,這時候 cimmitter 就會是新的人 _ 在 GUI 工具中看到的線圖,就是 commit 物件的資訊 _ tag _ 指向某一個 commit * tag 有兩種樣態,一個是這裡的 Object,另一個是參考的指標,存放在refs/tags
- 索引(Index)
_ 索引檔內會有所有版控中的檔案,保存要進儲存庫之前的所有檔案狀態
_ 當資料要寫入 Git 的時候,會需要索引檔 * 空的資料夾是無法加入版控的,如果硬要加入版控了話,至少要有一個檔案,建議用
.gitkeep
- 分支(Branch)
_ 記錄在
.git\refs\heads
資料夾下,例如 master _ 內容是一個 SHA-1 的指標,指向一個 commit
重置 GitFlow
Those commands remove all the sections of the git config file related to gitflow.
git config --remove-section "gitflow.path"
git config --remove-section "gitflow.prefix"
git config --remove-section "gitflow.branch"
Then you can re-init gitflow as usual.
git flow init
Git Client Tools
指令視作強大的,但畢竟人是視覺動物,有時候看到畫面(線圖)會感覺比較親切。
- SourceTree _ 跨平台,免費,可切換成中文介面 _ 官方教學文件 * 初次使用容易上手
- GitKraken _ 跨平台,社群版免費,可付費使用專業版功能 _ 畫面很像在打電動,感覺帥氣
參考資料: