Git 博大精深,必須花很多時間去學習,從做中學會更快 因此這篇主要用來記錄 Git 的指令和操作,增加記憶,也方便後續查詢。
區域
- 工作目錄 Working tree
- 暫存準備遞交區 Staging Area (index索引)
- 儲存庫 Repository
狀態
- 沒有被追蹤的檔案 Untracked files
- 有修改、還沒準備要被遞交 Changes not staged for commit
- 有修改、準備要被遞交的檔案(在Staging Area) Changes to be committed
- 已經被遞交的檔案 Committed
符號
- HEAD
- 永遠會指向「工作目錄」中所設定的「分支」當中的「最新版」。
- 所以當你在這個分支執行 git commit 後,這個 HEAD 符號參照也會更新成該分支最新版的那個 commit 物件。
- ORIG_HEAD
- 簡單來說就是 HEAD 這個 commit 物件的「前一版」,經常用來復原上一次的版本變更。
- HEAD and ORIG_HEAD in Git
- FETCH_HEAD
- 使用遠端儲存庫時,可能會使用 git fetch 指令取回所有遠端儲存庫的物件。這個 FETCH_HEAD 符號參考則會記錄遠端儲存庫中每個分支的 HEAD (最新版) 的「絕對名稱」。
- MERGE_HEAD
- 當你執行合併工作時 (關於合併的議題會在日後的文章中會提到),「合併來源」的 commit 物件絕對名稱會被記錄在 MERGE_HEAD 這個符號參照中。
基本設定
git config --global user.name "<使用者名字>"
(個別專案可用 –local)git config --global user.email "<電子信箱>"
(個別專案可用 –local)git config --list
看 Git 設定內容git config --global alias.st status
縮短字串(將 git status 縮寫為 git st)git config --global color.ui true
設定輸出顏色git config --global apply.whitespace nowarn
空白對有些語言是有影響的(像是Ruby),因此我們會希望 Git 去忽略空白的變化git config --global alias.co checkout
設定 aliasgit config --global pager.branch false
git branch 不開啟 edit modegit config --global push.default simple
git branch 不開啟 edit mode
以上皆可直接 vim ~/.gitconfig
去做修正
基本功能
basic
git --version
查看目前版本。git help [指令]
查詢完整的文件。git init
建立 Repository。git clone [url]
複製遠端專案。git mv [filename] [new filename]
更改檔案名稱。(此更改檔案的動作會列入版本控制中)git show [SHA1]
查出該版本的相關資訊。(可搭配git log
找出有問題的版本)
add
git add .
將當前目錄所有
檔案加入到 Staging Area。(雖然方便但很容易會不小心加入一些其他不必要的檔案)git add [filename]
將檔案加入到 Staging Area。git add -u
,只註冊已提交過的檔案到索引。git add -i
,會以互動方式詢問要加入到Staging Area裡的檔案。git add -p
,可以選擇只加入檔案中修改的其中一部分。
Commit only part of a file in Git
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
rm
git rm [filename]
刪除檔案,包括實體檔案。(此刪除檔案的動作會列入版本控制中)git rm --cached a.txt
只想刪除索引檔中的該檔,又要保留工作目錄下的實體檔案。
commit
git commit
將 Staging Area 檔案 commit。git commit -m [commit 訊息]
直接寫入 commit 訊息。git commit -am [commit 訊息]
等於git add .
+git commit -m
。git commit --amend
合併到上一個 commit 訊息。git commit --amend --no-edit
合併到上一個 commit 訊息,並且不需要更改訊息
status
git status
檢視檔案的狀態。git status -s
顯示精簡的狀態。git status -b
顯示分支的名稱。
分支
branch
git branch
列出所有本地端的 branch。git branch -r
列出所有遠端的 branch。git branch -a
列出所有本地及遠端的 branch。git branch [branch]
建立一個新的 branch。git branch -m [oldbranch] [newbranch]
修改分支的名稱,-M
強制。git branch -d [branchname]
刪除 branch,未合併的無法刪除,必須改用-D
強制刪除。git branch --merged maste
lists branches merged into mastergit branch --merged
lists branches merged into HEAD (i.e. tip of current branch)git branch --no-merged
lists branches that have not been merged
checkout
git checkout [branch]
切換到該 branch。git checkout -b [branch]
建立一個新的 branch 並切換到該 branch。
切換 working tree 的 branch 時,如果有檔案,在 staging area 或是 modified,會無法切換。可以先 commit,只要不 push 出去,再
reset
回來即可。或是用stash
的方式
合併
merge
git merge [branch]
將指定 branch 合併到目前的 branchgit merge [branch] --no-ff
不使用 fast-forward 合併。可以保留分支合併的紀錄。
修正
reset
git reset
將所有檔案從 Staging Area 到 Working tree。git reset HEAD [filename]
將檔案從 Staging Area 取消到 Working tree。git reset --hard HEAD
放棄目前所有修改,返回到最新的commit。git reset HEAD^
刪除最近一次的版本紀錄,但保留修改過的檔案。(回到working tree)git reset --soft HEAD^
刪除最近一次的版本紀錄,但保留修改過的檔案。(回到staging area)git reset --hard HEAD^
刪除最近一次的版本紀錄,清除修改過的檔案。(完全消失)
HEAD 後面可接
^
表示回到上個版本,^^
回到上兩個版本,以此類推 也可以用~
,或是^2
or~2
,都不加就是回到目前最新的版本
git reset --hard ORIG_HEAD
刪除最近一次的版本,但保留最後一次的變更。
revert
revert是新增一個commit來做還原,
git revert
會用一個新的 commit 來回復所有的變更。(適合已經push出去給別人的情境)
rebase
git rebase
重新修改特定分支的「基礎版本」,把另外一個分支的變更,當成這個分支的基礎。(如果接著直接 merge,則是會直接 fast-forward ,若想保留資訊則加上--no-ff
)- Git-rebase 小筆記
git rebase -i [SHA1]
可以只接更改某個 commit 之後所有的紀錄。- rebase -i 修正 commit 過的版本歷史紀錄1.markdown)
- rebase -i 修正 commit 過的版本歷史紀錄2.markdown)
git rebase --onto <new base-commit> <current base-commit>
指定要從哪裡開始接枝- 有 conflict 修改好後,
git rebase --continue
- 直接從 rebase 狀態離開
git rebase --abort
1 2 3 4 5 6 |
|
cherry-pick
git cherry-pick
手動挑出其他 branch 中的 commit,合併進來。git cherry-pick [SHA1] -e
建立版本前先編輯訊息。git cherry-pick [SHA1] -n
不建立版本,僅套用其變更。
checkout
git checkout [filename]
取消 Working tree 檔案。git checkout master [filename]
把 master 分支中最新版的檔案給還原。
暫存
git stash
會將所有已列入追蹤(tracked)的檔案建立暫存版。git stash -u
會包括所有已追蹤或未追蹤的檔案,全部都建立成暫存版。git stash list
顯示出所有的暫存清單。git stash clear
清除所有暫存。git stash pop
復原最新的操作並將他從暫存清單中移除。git stash apply
復原最新的操作,與pop
唯一差別則是取回該版本 (其實是執行合併動作) 後,該暫存版還會留在 stash 清單上。(取出最新的一筆 stash 暫存資料. 但是 stash 資料不移除)git stash drop
刪除最新的暫存操作。git stash show stash@{0}
看暫存陣列裡的第一個
指定stash ID(如:stash@{1}),則可以復原特定的操作
遠端
git remote add origin [url]
註冊遠端儲存庫。git clone [url]
將遠端儲存庫複製到本地,並建立工作目錄與本地儲存庫。git push -u origin master
將本地儲存庫中目前分支的所有相關物件推送到遠端儲存庫中。git fetch
將遠端儲存庫的最新版下載回來,下載的內容包含完整的物件儲存庫(object storage)。 這個命令不包含「合併」分支的動作。git pull -u origin master
將遠端資料庫拉下來,並且合併,相當於git fetch
+git merge
。
加上
-u
後續就只要git push
和git pull
即可。-u
相當於--set-upstream
用來追蹤遠端的分支,因此要取消追蹤為--unset-upstream
git push --force
可將 github 上的commit
全部覆蓋掉。git pull --rebase origin [brance]
pull 遠端用 rebase 的方式。- Git 更安全的強制推送,–force-with-lease
差異
git diff
比對「Working tree」與「Staging Area」之間的差異。git diff commit
比對「Working tree」與「指定 commit 物件裡的那個 tree 物件」之間的差異。git diff HEAD
比對「Working tree」與「HEAD」之間的差異。git diff --cached
比對「Staging Area」與「HEAD」之間的差異。(可改成 –staged)git diff commit1(SHA1) commit2(SHA1)
比較兩個 commit 差異。git diff HEAD^ HEAD
比較 HEAD 和 HEAD^ 差異。git diff BRANCH
比較當下 branch 和指定 branch 的差異。
記錄
log
git log
查詢歷史紀錄。git log -10
限定輸出最近幾筆紀錄。git log --oneline --graph --all --decorate
圖像化 log。git log --oneline --author="leon"
找出 leon 所有的 commit(多個名稱 --author="leon1\|leon2"
)git log --oneline --grep="rails"
找出 commit 訊息有 rails 的字眼git log -S "Ruby"
找出 commit 的內容有包括Ruby
的字git log --oneline --since="9am" --until="12am"
今天早上 9 點到 12 點之間所有的 Commitgit log --oneline --since="9am" --until="12am" --after="2017-01"
2017 年 1 月之後,每天早上 9 點到 12 點的 Commit
reflog
git reflog
可列印出所有「歷史紀錄」的版本變化。git log -g
顯示 reflog 的詳細版本記錄。git reflog delete HEAD@{1}
刪除特定幾個版本的歷史紀錄。
【狀況題】不小心使用 hard 模式 Reset 了某個 Commit,救得回來嗎?
rev-parse
git rev-parse
可以把任意「參考名稱」或「相對名稱」解析出「絕對名稱」sha1
git rev-parse master
看 master 的 sha1git rev-parse HEAD
看 HEAD 的 sha1git rev-parse ORIG_HEAD
git rev-parse HEAD^
git rev-parse HEAD~5
git rev-parse --abbrev-ref HEAD
看 HEAD 的 sha1 對應的 branch 名稱
標籤
git tag
列出所有標籤。git tag -n
顯示標籤的列表和註解。git tag [tagname]
建立輕量標籤。git tag [tagname] -d
刪除輕量標籤。git tag [tagname] -am [版本訊息]
建立標示標籤
- 輕量標籤 (lightweight tag)
- 不可變更的暫時標籤
- 可以添加名稱
- 標示標籤 (annotated tag)
- 可以添加打標簽者的名稱、email及日期
- 可以添加名稱
- 可以添加註解
- 可以添加簽名
push 標籤
git push origin v1.5
git push 並不會把標籤上傳到遠端,所以必須透過底下才行git push origin --tags
用 –tags 一次上傳上去
刪除標籤
git push origin :refs/tags/my_tag
git tag -d <tagname></tagname>
commit 順序
1 2 3 4 5 |
|
Blame
git blame [filename]
可以看最後一個 commit 的人是誰git blame -L [開始行數],[結束行數] [filename]
submodule
git-bisect
利用 git 的 二分找法,來找出當初錯誤的版本是從哪個開始
1 2 3 4 5 6 7 8 9 10 11 |
|
git format-patch
git 製作成 patch 檔 然後 merge
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
- 【Git】使用 format-patch 將 commit 打包成檔案 Use format-patch to carry commit
- 5.3 分散式 Git - 專案的管理
- Create patch or diff file from git repository and apply it to another different git repository
其他
gitkeep
.gitkeep
空目錄不會被 commit,必要時在目錄裡放.gitkeep
。
.gitignore
vi .gitignore
編輯不要 commit 的檔案 此檔案也要 commit,通常是比較敏感的檔案,像是密碼之類的。
.gitignore ⼤集合 .gitignore not working
1 2 3 |
|
移除已經上 github 的敏感檔案
1 2 3 4 5 |
|
開乾淨的 branch
How to create a new empty branch for a new project
1
|
|
複製遠端的 branch 到本地新的 branch
- 先
git checkout
到遠端的 branch,在遠端的 branchgit checkout branch
複製切到本地
1 2 |
|
- 直接 fetch 遠端 branch 下來到新的 branch
1
|
|
移除 untracked file
1 2 3 4 5 |
|
How do I remove local (untracked) files from my current Git branch?
針對每個節點刪除特定檔案
1
|
|
移除local 遠端 branch
clear any remote-tracking branch which is no longer exist on the remote.
1
|
|
git 垃圾回收
1
|
|
拯救已被刪除的 branch
1 2 3 4 5 6 7 8 |
|
拯救已被 hard reset 的節點
1 2 3 4 5 |
|
拯救已刪除的檔案
1 2 3 4 |
|
取的 remote git 資訊
1 2 |
|
找出 log 裡面的關鍵字
How to search a Git repository by commit message?
1 2 3 4 5 6 7 8 |
|
同時開多個工作目錄
1 2 3 4 5 6 7 8 |
|
Reset 所有的 commit 的 author
How to change the commit author for one specific commit?
1 2 3 |
|
找出某個 commit 什麼時候被 merge 和 branch 名稱
alias
自己設定的一些 alias
可以建立在 ~/.gitconfig
裡面,但是前面 git
就無法縮寫成 g
1 2 3 4 5 6 |
|
也可以建立新的檔案 .aliases
, 並在 .zshrc
加上 source ~/.aliases
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
|
官方文件:
參考資料:
- Git 版本控制系統
- 30 天精通 Git 版本控管
- 連猴子都能懂的git入門
- 好麻煩部落格
- Commit only part of a file in Git
- Git 風格指南
- How to Write a Git Commit Message
- 你知道 Git 是怎麼一回事嗎
- 為你自己學 Git
- Git 小說連載系列
練習:
其他技巧: