指令 | 說明 |
---|---|
git add <file> |
打包檔案變更 |
git branch |
顯示本地分支列表 |
git commit -m "message" |
提交改變,製作 commmit |
git checkout <commit-SHA> |
提取某個 commit 版本 worktree |
git checkout -b <branch> |
新增 branch |
git clone <url> |
複製 remote repo 至 local |
git config |
進行.git 工具設定 |
git diff <commit1> <commit2> |
比較版本差異 |
git fetch |
取得遠端最新變更但不合併 |
git fetch --prune |
清除已刪除的遠端分支 |
git init |
git 環境初始化 |
git ls-files |
列出所有追蹤中的檔案 |
git log |
查看 commit log, file log |
git merge <commit-SHA> |
將指定 commit 合併至 HEAD |
git push |
推送變更到遠端分支 |
git pull |
拉取遠端分支並合併 |
git remote |
查看 remote 設定 |
git reset |
讓分支回到某個 commit |
git rebase <commit-SHA> |
重新整理當前分支並套用變更 |
git reflog |
查看 HEAD 的變更歷史 |
git restore |
恢復 stage area 或者 worktree 的變更 |
git rm --cached <file> |
讓 Git 保留檔案但停止追蹤 |
git status |
查看目前 Git 的狀態 |
git show <commit> |
可以看基本資訊,以及檔案差異 |
git stash |
暫存當前變更 |
git tag <tag_name> |
在當前 commit 打 tag 標籤 |
指令 | 說明 |
---|---|
git revert HEAD |
新增反向 commit,用於取消最新的 commit,但保留取消歷史 |
git cat-file -p <commit-SHA> |
還原 Git 物件的內容 |
git cat-file -t <commit-SHA> |
查看物件類型 |
git ls-files -s |
列出當前目錄下包含子目錄底下的 blobs |
git clone --recurse-submodules <URL> |
一併下載相依的 submodules |
git cherry-pick |
可以從 commit tree 的任何地方拿一個 commit 來放在 HEAD 上(只要那個 commit 不是 HEAD 的 parent) |
git rebase -i <commit-SHA> |
互動式 rebase,若 rebase 之中有許多 commits 要剪下貼上,可以選擇只 rebase 那些 commits,甚至可以排序 |
檔案變動狀態
git ls-files
列出所有追蹤中的檔案。git rm --cached <file>
讓 Git 停止追蹤檔案。.gitignore
用來設定 Git 忽略檔案的規則,其中列出的檔案 Git 會予以忽略,不會追蹤其改變。
.gitignore
檔案影響,必須先停止追蹤 (git rm --cached <file>
),再加入 .gitignore
,之後該檔案的變動才不會被追蹤。指令 | 說明 |
---|---|
git add . |
打包所有檔案變更。 |
git add filename |
打包指定檔案變更。 |
git add -p filename |
選擇性地新增某檔案的部分變更。 |
所謂打包就是將 worktree 變更(Changes)儲存至 staging area(Staged Changes)。用意是將需要提交的變更先整理起來,再發一個 commit 提交出去。 比如你可能會想要將較不相關的變動分次提交,所以你會先打包相關的一部分儲存至 staging area,進行 commit 提交時,只有 staging area 的變更會被提交出去。沒有被 staged 的部分還維持在 “Changes"的狀態。
指令 | 說明 |
---|---|
git commit -m "message" |
提交改變,製作 commit |
git commit --amend -m "message" |
拆掉最新的 commit 連同新提交到 staging area 的部分,重新製作 commit |
指令 | 說明 |
---|---|
git restore -W . |
就會恢復 Worktree 所有修改(預設選項) |
git restore -S . |
就會恢復 Stage area 所有修改 (staged changes —> changes) |
指令 | 說明 |
---|---|
git checkout <commit-SHA> |
切換至指定 commit 版本 |
git checkout <commit> <file> |
指定檔案回復到某個 commit 版本 |
git checkout . |
切換至當前版本,相當於還原當前工作區所有修改,建議以 git restore . 指令取代 |
checkout 切換至某個版本、提取某個版本資料,均會更新工作目錄。
整個 worktree 切換至指定 commit 版本
git checkout <commit-SHA>
指切換單一檔案至特定 commit 之版本
git checkout <commit> <file>
在本地 repo 的 branch 稱為 local branch; 在 remote repo 的 branch 稱為 remote branch; 而在本地 repo 用來追蹤 remote branch 的稱作 remote-tracking branch。
指令 | 說明 |
---|---|
git branch |
顯示本地分支列表。 |
git branch -a |
顯示所有分支(包含遠端) |
git branch -vv |
顯示所有分支的詳細訊息,包含 upstream 對應 |
git branch -d <branch_name> |
刪除本地分支 |
git branch -rd <remote>/<branch_name> |
刪除追蹤分支 (-r 代表 remote) |
git branch <branch_name> |
新增 branch 於目前 HEAD 上 |
git branch <branch_name> <commit-SHA> |
新增 branch 於指定 commit 上 |
git branch -f <branch_name> <commit-SHA> |
強制將現有 branch 改貼到指定 commit 上,但不可以是 HEAD 正指向之 branch |
git checkout -b <branch_name> |
新增 branch 於目前 HEAD 上並切換到該分支 |
git checkout <commit-SHA> -b <branch_name> |
新增 branch 於指定 commit 上並切換到該分支 |
其他相關:
git fetch --prune
若遠端已沒有該分支但本地端還有其追蹤分支的話,予以刪除。指令 | 說明 |
---|---|
git tag <tag_name> |
新增 tag |
git tag <tag_name> <commit> |
新增 tag 於指定 commit 上 |
git tag -d <tag_name> |
刪除 tag |
git tag <tag_name> -a -m "message" |
新增帶有註解(annotated)的 tag |
指令 | 說明 |
---|---|
git log |
查看 commit 記錄 (預設為 HEAD 指向) |
git log --oneline |
單行簡潔查看 commit 記錄 |
git log -- <path/to/file> |
只查看某個檔案的 commit 記錄 |
git log -p |
-p 顯示變更內容 |
git reflog |
查看 HEAD 的變更歷史 |
指令 | 說明 |
---|---|
git reset <commit-SHA> |
拆掉當前 commit,分支回到指定 commit(預設為 –mixed) |
git reset --soft <commit-SHA> |
拆掉當前 commit,分支回到指定 commit,拆除之變更保留在 staged 狀態 |
git reset --mixed <commit-SHA> |
拆掉當前 commit,分支回到指定 commit,拆除之變更保留在 changes 狀態 |
git reset --hard <commit-SHA> |
拆掉當前 commit,分支回到指定 commit,刪除所有變更 |
想像 commit1 到 commit2 的過程: commit1 -> changes -> staged changes -> commit2
指令 | 說明 |
---|---|
git fetch <remote> |
取得遠端最新變更但不合併 |
git pull <remote> <branch> |
拉取遠端分支並合併到 HEAD |
git pull --rebase |
表示要使用 rebase 的方式合併 fetch 下來的 commit |
git push |
推送當前分支到對應的 upstream 分支 |
git push <remote> <branch> |
推送指定分支同步至遠端 |
git push <remote> <branch> --force |
強制推送 |
git push -u <remote> <branch> |
推送時一併設定 branch upstream |
git branch -vv |
可以使用此指令 查看 branch 是否設置 upstream |
git remote |
查看 remote repo |
git remote -v |
-v for verbos 提供更多訊息 |
git remote add <remote> <remote repository URL> |
建立 remote repository 指標 |
upstream 就是 <local_branch> 預設進行 push/pull/fetch 等指令的 <remote_branch> 分支。 設定好 upstream 使得進行 push/pull/fetch 等指令時,不用每次都詳細指定 <local_branch> 是要跟哪個 <remote_branch> 互動,會比較方便。 若設定 <remote_branch> 為 <local_branch> 之 upstream,當然也可以反過來說 <local_branch> 是 <remote_branch> 之 downstream。
當 remote 端已有該 branch 時,我們可以這樣建立 upstream。
git fetch <remote> <branch>
。git branch -u <remote>/<branch>
或 git branch --set-upstream-to=<remote>/<branch>
。git branch -u <remote>/<branch> <branch>
git checkout <remote>/<branch> -b <branch>
,就會自動設立 upstream 關係。而若是遠端沒有該 branch,我們可以推送 <local_branch> 上去建立 <remote_branch> 同時建立 upstream 關係。
git push -u <remote> <local_branch>:<remote_branch>
或者 local 跟 remote 同名的話 git push -u <remote> <branch>
。
git branch --unset-upstream
git branch -vv
可以看到所有 branch 的詳細訊息,包含該 branch 是否有 upstream branch。git remote show <remote>
會顯示 <remote> 的詳細訊息,包含 <local_branch> 對應到的 <remote_branch>,即 upstream。git branch -a
可以看到其他 remote 分支,若你想要建立該 <remote_branch> 的 downstream 可以 git branch <branch> <remote_branch>
。一定要知道來源與目標,來源可以是 commit 但目標一定是 branch,目標不存在也沒關係,會自動創建。 push 前,須保證不會 conflict,所以會被檢查 remote_branch 的 history,local commit 是否都有,若沒有要先 fetch 更新,merge 後在 local 解決衝突才能重新 push。
git push <remote> <commit>:<remote_branch>
git push <remote> <branch>
git push
特別技: 如何在 local 端刪除 remote 端的分支? 就是讓 <local_branch> 的地方留空,git push <remote> :<remote_branch>
,push 一個空 branch 到 remote 代表刪除。
主要是更新遠端分支的狀態(所以 tracking-branch 會改變),若有需要會自動創建 remote-tracking branch。
git fetch
git fetch <remote> <branch>
git fetch <remote> <src>:<dst>
git pull = git fetch + git merge,也就是 fetch 遠端分支的更新,並嘗試 merge。
記得 merge 是針對 HEAD 位置的操作。
git pull <remote> <remote_commit>:<local_branch>
= git fetch <remote> <remote_commit>:<local_branch>
+ git merge <local_branch>
git pull origin bar:bugFix 相當於:
git fetch origin bar:bugFix;
git merge bugFix
git pull <remote> <branch>
= git fetch <remote> <branch>
+ git merge <branch>
git pull origin foo 相當於:
git fetch origin foo;
git merge origin/foo
git pull
= git fetch <remote> <branch>
+ git merge <remote_branch>
git fetch <remote> <branch>
只會取得 upstream 更新,並不是 git fetch
取得所有更新。git pull 相當於:
git fetch <remote> <upstream>
git merge <upstream>
指令 | 說明 |
---|---|
git merge <commit-SHA> |
當前分支嘗試合併某 commit 內容 (fast forward 優先) |
git merge <commit-SHA> --no-ff -m “merge message” |
使用 –no-ff 禁用 fast forward,必會產生 merge 訊息 |
git merge --squash <commit-SHA> |
??? |
git merge --abort |
當 merge conflict 時,若想放棄這次 merge 回復 merge 前狀態時使用 |
git merge 一定是對 HEAD 位置 merge,HEAD 不一定要指向 branch(但通常是),merge 完 HEAD 會移動,若HEAD 指向 branch 則 branch 也會移動。
Fast Forward(快速前進)是一種 合併(merge)策略,當 當前分支的 HEAD 沒有與目標分支產生分歧,而目標分支只是在 HEAD 之後新增了 commit 時,Git 會直接把 HEAD 指向最新的 commit,而不產生新的 merge commit。
Fast Forward 合併的條件:只要 commits 鍊是可以溯源,那必定可以 Fast Forward。 比如當前分支 A 是目標分支 B 的祖先之一,那從 B commits 溯源並訂可以找到 A commits,則必可以 Fast Forward。
當兩分枝執行合併,但兩個分支都修改了一樣的內容,導致讓 git 不知怎麼合併,這就是 merge conflict。
此時,merge 會被暫停並且 git 會把衝突的檔案以及兩分枝的差異標示給你看,讓你自行選擇怎麼修正。
不管你怎麼修正,修完之後再次 git add
、git commit
提交,就算是解決 conflict 了。
指令 | 說明 |
---|---|
git rebase <commit-SHA> |
把自己跟別人不同的 commit 都剪下重新長在別人身上。 |
git rebase --continue |
當 rebase 遇到 conflict 時,待解決後以此指令繼續 rebase 過程。 |
git rebase <on-commit> <from-commit> |
比對 commits 差異,將 不同的 commits 剪下貼在 上 |
git rebase -i <commit-SHA> |
互動式 rebase,自由決定要剪下哪些 commits,還可以調整順序,按照指定順序重新長在指定之 commit 上! |
git pull --rebase |
使用 rebase 的方式處理 fetch 到的 commit |
Rebase 與 merge 之差別:
比如說有兩個 branches branch_A,branch_B 共同的 parent 是基於 commit_parent,此時若要用 rebase 方式合併,假設說要 let branch_A rebased on branch_B,則會發現她會把從 commit_parent 之後 branch_A 長出的 commit 一個個剪下,且重新插枝在 branch_B 現在的 commit 上。假設從 commit_parent 之後 branch_A 長出 2 個 commits,那就會將這兩個 commits 剪下,然後 rebased on branch_B,重新製作兩個 commits 插到 branch_B 之後。所以這時候,會看到 branch_A 與 branch_B 在同一條路上了,而且 branch_A 領先 branch_B 2 個 commits。
rebase 完會 branch 會前進,移動到新 commit 上。
注意: rebase 是修改 commit 歷史的行為。
git cherry-pick <commit1> <commit2> <commit3>...
就是去複製某些 commit 重新製作嘗試將改變貼自己身上(HEAD)。
這是一個非常強大的工具,甚至讓你可以重新整理你的整個 branches 之 commits 排列順序等等。
cherry-pick 沒有改變歷史,他是造新的一條 branch 出來。cherry-pick 也會讓 HEAD 以及 branch 移動。
指令 | 說明 |
---|---|
git stash |
暫存當前變更 |
git stash -m "<message>" |
-m 可以註解提供說明訊息 |
git stash list |
列出所有 stash |
git stash pop |
取回最近一次的 stash,並從列表中移除 |
git stash pop "stash@{<num>"} |
取回編號 num 的 stash,並從列表中移除 |
git stash apply |
取回最近一次的 stash,但不從列表中移除 |
git stash drop |
刪除最近一次的 stash |
git stash clear |
清除所有 stash |
指令 | 說明 |
---|---|
git diff |
比較 a.暫存區 與 b.工作區 |
git diff HEAD |
比較 a.當前 commit 與 b.工作區 |
git diff --staged |
比較 a.當前 commit 與 b.暫存區 |
git diff <commit> |
比較 a.某個 commit 與 b.當前 commit |
git diff <commit1>..<commit2> |
比較 a.commit1 與 b.commmit2 |
git diff <commit1>..<commit2> -- <file> |
比較 a.commit1 與 b.commmit2 間指定檔案之變化 |
HEAD 是一個 reference,他可以指向 branch 也可以直接指向 commit,不管是哪種,它最終都可以推論出一個 commit,表示目前所 checkout 的 commit。
cat .git/HEAD
可以查詢 HEAD 指向當 HEAD 不是指向 branch 則稱為斷頭(detached head)。
git checkout <branch>
為 HEAD -> branch -> commit,沒有斷頭。git checkout <commit>
為 HEAD -> commit,就會形成斷頭。git checkout <tag>
為 HEAD -> commit,也會形成斷頭。依照 HEAD 移動紀錄
git reflog
可看到 HEAD 的移動紀錄git checkout "@{1}"
定位 HEAD 的上 1 動之 commit 位址git checkout "@{4}"
定位 HEAD 的前 4 動之 commit 位址依照 commit 指向的第一個父 commit 去回溯。
git checkout "HEAD^"
或者 git checkout "@^"
git checkout "HEAD^^"
則是往前回溯 2 次。^2
則代表指向當前 commit 的第 2 個父 commit。git checkout "HEAD~1"
或者 git checkout "@~1"
或者 git checkout "3bdf7c55~1"
或者 git checkout "main~1"
@^^~^^
@^^2^^~~
main^2~3
Git 有:blob
/ tree
/ commit
/ tag
四大物件。
每個 git 物件之檔名,均是由內容(不確定是壓縮前或後)及一些其他資訊所計算出的 SHA 值,即使內容只有一個字元差異,也會產生一個新的 git 物件。SHA 的算法很好的用作 ID 表示特定的檔案,且每個檔案名稱長度相同,方便物件關聯檔案控管。
而這些物件的檔案內容則都是壓縮過的,可以用工具還原為未經壓縮之內容。
物件檢視
git cat-file -t <commit-SHA>
查看物件類型。git cat-file -p <commit-SHA>
還原 Git 物件壓縮前的內容。SHA 值計算
cat <file> | git hash-object --stdin
計算 git 物件之檔案名稱(SHA 值)。
git add
後產生新的 Blob 物件。
git commit
後產生 Tree、commit 物件,把所有物件串起來。
設定
git config --global user.email <email_addr>
git config --global user.name <username>
查看設定
git config --global --get user.name
設定 remote 以及 upstream
git remote add <remote> <remote repository URL>
git push -u <remote> <branch>