git pull 命令等同於先做了git fetch ,再做了git merge, 當git merge后有可能會報錯:Your local changes would be overwritten by merge. Commit, stash or revert them to proceed
報錯原因是你對本地的代碼進行了更改,而未對代碼進行提交、存放或還原
解決方法:使用git stash先將更改的代碼暫存起來
什么是stash:stash翻譯為存放、貯藏
git stash命令可以獲取你工作目錄的中間狀態——也就是你修改過的被追蹤的文件和暫存的變更——並將它保存到一個未完結變更的堆棧中,隨時可以重新應用。
使用git stash將未提交的代碼保存之后,現在倉庫的狀態是和上一次提交的內容是完全一樣的
此時再進行git merge temp就不會報錯了
git stash用法詳解:
git stash 工作樹模型:H
是HEAD
提交.I
是存儲單元的提交.W
是工作樹中的提交.
git stash常用命令:
1 git stash等同於git stash save存儲的修改列表. 2 git stash list查看. 3 git stash show用於校驗, 4 git stash apply用於重新存儲.
應用舉例
通過幾個實際的示例來了解一下git stash
的強大.
開發到一半,同步遠端代碼
當你的開發進行到一半,但是代碼還不想進行提交 ,然后需要同步去關聯遠端代碼時.如果你本地的代碼和遠端代碼沒有沖突時,可以直接通過git pull
解決.但是如果可能發生沖突怎么辦.直接git pull
會拒絕覆蓋當前的修改.
遇到這種情況,需要先保存本地的代碼,進行git pull
,然后再pop出本地代碼:
1 git stash 2 git pull 3 git stash pop
工作流被打斷,需要先做別的需求
當開發進行到一半,老板過來跟你說"線上有個bug,你現在給我改好,不然扣你雞腿".當然,你可以開一個新的分支,把當前代碼提交過去,回頭再merge,具體代碼如下
1 繁瑣的工作流示例 2 # ... hack hack hack ... 3 git checkout -b my_wip 4 git commit -a -m "WIP" 5 git checkout master 6 edit emergency fix 7 git commit -a -m "Fix in a hurry" 8 git checkout my_wip 9 git reset --soft HEAD^ 10 # ... continue hacking ...
我們可以通過git stash
來簡化這個流程
1 繁瑣的工作流示例 2 # ... hack hack hack ... 3 git checkout -b my_wip 4 git commit -a -m "WIP" 5 git checkout master 6 edit emergency fix 7 git commit -a -m "Fix in a hurry" 8 git checkout my_wip 9 git reset --soft HEAD^ 10 # ... continue hacking ...
提交特定文件
如果對多個文件做了修改,但是只想提交幾個文件,或者想先暫時保存幾個修改,測試其他文件的執行結果.可以通過git stash save --keep-index
來進行.
1 # ... hack hack hack ... 2 git add --patch foo //只將第一部分加入管理the index 3 git stash save --keep-index //將其余部分保存起來 4 edit/build/test first part 5 git commit -m 'First part' //提交全部的git管理中的代碼 6 git stash pop //繼續進行存儲代碼的工作 7 # ... repeat above five steps until one commit remains ... 8 edit/build/test remaining parts 9 git commit foo -m 'Remaining parts'
恢復被錯誤clear/drop
的存儲
如果因為失誤對存儲倉庫進行了clear
或者drop
操作,在一般機制下是不能恢復的.但是可以通過以下指令來獲取仍在倉庫中的,但是已經不可獲取的存儲列表
1 git fsck --unreachable | 2 grep commit | cut -d\ -f3 | 3 xargs git log --merges --no-walk --grep=WIP
git stash 的具體用法
git stash
通過在指令后添加其他的附件選項,實現復雜的定制化操作,下面我們來對具體用法進行講解.
save, push
1 save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [<message>] 2 3 push [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q|--quiet] [-m|--message <message>] [--] [<pathspec>…]
save
和push
命令都可以用於存儲修改.並且將git
的工作狀態切回到HEAD
也就是上一次合法提交上.后面的<message>
是選填項.
如果給定具體的文件路徑,git stash
只會處理路徑下的文件.其他的文件不會被存儲
--keep-index
(簡寫為-k
)只會存儲為加入git
管理的文件
--include-untracked
為追蹤的文件也會被緩存,當前的工作空間會被恢復為完全清空的狀態.如果不使用--include-untracked
而是用--all
,那么除了未加入管理的文件,被git
忽略(ignore
)的文件也會被緩存.
--patch
命令可以讓我們選擇當前修改和HEAD
提交diff
部分.
list
list [<options>]
展示當前存儲庫中的存儲單元列表.每個元素包含的信息有索引位置,存儲時所在的分支,存儲前的提交的描述.舉例
1 stash@{0}: WIP on submit: 6ebd0e2... Update git-stash documentation 2 stash@{1}: On master: 9cc0589... Add git-stash
show
show [<stash>]
展示存儲單元和最新提交的diff
結果.如果沒有給定<stash>
參數時,會對比最新的存儲單元.
pop
pop [--index] [-q|--quiet] [<stash>]
移除單個存儲單元.和git stash save
的作用相反.