# Git 常用指令備忘: checkut / reset / stash ## checkout 用來移動 HEAD 指標的指向,並且變更工作目錄( working tree files )的內容。 checkout 只會修改 HEAD 指標的位置與工作目錄內容,而不會異動到 branch 指標、 commit 和暫存區(staging area)的內容。 - `git checkout <branch name>` 切換分支。將 HEAD 指向指定的 branch,即把工作目錄內容替換為 branch 中的最新檔案 - `git checkout <commit id>` 將 HEAD 指向特定 commit,並將工作目錄替換為該 commit 內容 - `git checkout <file name>` 將指定檔案回復為未修改,即暫存區內或是最後一次提交的版本 - `git checkout .` 將工作目錄整個回復為未修改,即暫存區內或是最後一次提交的版本 :::info `git checkout <file name>`、`git checkout .` 會把工作目錄內未提交的修改都清除掉,使用上要三思! ::: 當我們將 HEAD 指向某個 commit,而不是 branch 時,如果我們再提交 commit 時,這些 commit 將不會被連在任何 branch 上,而是處在斷頭的狀態( detached HEAD )。 斷頭狀態下建立的 commit 會比較難在被指向,必需使用 `git checkout <commit id>` 才能找到他。 ### 解決 commit 斷頭的方法: 為他建立一個新的 branch 指向他,再將這個 branch 合併到工作分支上: ```bash // 建立指向斷頭的 commit 的新分支 temp,如果正在該 commit 上,<commit id> 可以省略 $ git branch temp <commit id> // 先回到工作分支 $ git checkout develop // 將 temp 合併回工作分支 $ git merge temp // 將 temp 分支刪除 $ git branch -d temp ``` :::info 要尋找 commit id,可以使用 `git reflog` 列出一個月內下過的 git 指令紀錄。 ::: ## reset 移動 branch、HEAD 指標,並替換暫存區、工作目錄的內容。 `git reset <commit id>` 將目前 branch 指標指向特定 commit,並將拆出來的檔案丟回工作目錄。 `git reset HEAD^` 將目前分支指標退到 HEAD 所指向的前一個 commit,並將 commit 拆出來的檔案丟回工作目錄。其中,`HEAD^` 代表的是往前一個 commit,也可以用 `HEAD~1`; `HEAD^^` 往前兩個 commit,也可用 `HEAD~2` 如果目前正在 master 分支上,`git reset HEAD^` 與 `git reset master^` 的效果是一樣的。 :::info 如果對剛做完的 reset 反悔了,可以用這個指令回到 reset 前的 commit。 ```bash $ git reset ORIG_HEAD ``` ::: reset 有三種模式:mixed、soft、hard,沒有加參數時預設就是 mixed mode。三個模式都會移動 branch 指標,但其中差異是: - `--mixed` 將 commit 拆出來的檔案放在工作目錄 - `--soft` 將 commit 拆出來的檔案放在暫存區 - `--hard` 將 commit 拆出來的檔案丟掉 例: `$git reset master^` 將 master 往前回到上一個 commit,並將 commit 拆出來的檔案丟到工作目錄 `$git reset master^ --soft` 將 master 往前回到上一個 commit,並將 commit 拆出來的檔案移至暫存區 `$git reset master^ --hard` 將 master 往前回到上一個 commit,並將工作目錄及暫存區的變更刪除。 :::info 口語上使用"拆" commit 較好理解,但實際上 commit 並沒有被拆掉,只是移動了 branch 指標,並將工作目錄或暫存區的檔案替換。 ::: #### `git reset HEAD <file name>` 將暫存區內的檔案移回工作目錄。如果沒有指定檔案,就是將整個暫存區退回工作目錄。 ## stash 儲存檔案修改的快照 #### `git stash` 將目前修改過的被追蹤檔和暫存的變更的快照保存到一個 stack 中。使用 `git stash` 儲存變更後,working tree files 會回到未修改的狀態。 當我們開發到一半尚未 commit,但希望可以 checkout 到其他位置時,可以用 `git stash` 將未 commit 的修改先暫存起來,待之後 checkut 回來在回存之前的進度。 > 如果沒有變更的狀態下,使用 `git stash` 會出現 `No local changes to save` :::info 要 stash untracked 的檔案,要加上參數 -u ::: #### `git stash list` 列出 stash 中保存的快照 ```htmlmixed= stash@{0}: WIP on develop-kris: c5fe7cc uBike 改版型 & 新增搜尋功能 / 天氣資訊日期顯示優化修改 stash@{1}: WIP on develop-kris: c5fe7cc uBike 改版型 & 新增搜尋功能 / 天氣資訊日期顯示優化修改 stash@{2}: WIP on develop: 6142006 [修改] 減少不必要的調整 (END) ``` #### `git stash apply <stash name>` 將 stash 回存到 working tree files。如果沒有指定 stash name,預設使用最新的。回存的 branch 沒有限定要跟儲存時是同一個,例如在 branch develop 下儲存的 stash,可以在 branch master 回存。 #### `git stash pop <stash name>` 套用 stash 並將它從 stash list 中移除。沒有指定 stash name,預設使用最新的。 #### `git stash drop <stash name>` 刪除某一筆 stash --- ## Get Branches that contain specific commit ```bash= $ git branch --contains <sha1-commit-hash> ``` - 沒有加上參數,僅會列出本地分支 - 加上 -r 僅列遠端分支 - 加上 -a 本地遠端皆列出
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up