2014年4月6日 星期日

[筆記/GitHub] git add -p 及 git stash

  在使用 git 一陣子之後,應該都會遇到「修改 code 到一半,發現之前的 code 有地方需要修改」之類的問題。當遇到這樣的情況往往會選擇連同之前的 code 一起做修改,然後一同 commit 上去,一次提交太多而且不同功能的 code,造成 commit message 混亂。以下介紹兩種實用的 git 指令:git add -pgit stash,來幫助解決這樣的情況。


git add -p

  • 讓 programmer 可以一一檢視被更動的地方,並且可以決定是否要加入這次的 commit。
首先,先看到這次有更動的地方:


在這次修改中新增了兩個函式,可是我一次只想要 commit 一個函式。
這時用上 git add -p~:


可以看到 git add -p 的輸出與 git diff 類似,但是多了一行「Stage this hunk [...]?」的提示。來看看中括號裡字的的功能。
  • y:確認將這個區塊( hunk ) stage 上去
  • n:不要將此 hunk stage 上去
  • q:直接離開對話
  • a:將目前 hunk 所屬檔案裡面的所有 hunk 都 stage 上去
  • d:a 的相反功能
  • /<regex>:搜尋符合給定的 regular expression ( regex ) 的 hunk
  • s:將這個  hunk 分割成更小的 hunk
  • e:手動更改目前的 hunk
  • ?:help
依照目前的情況,我們一次只想要 stage 一個函式,如果有出現 's' 的選項會很方便,但是這理由於 hunk 比較小,所以無法分割。這時我們用另一個指令 'e'。
會出現以下編輯畫面:


將不想 stage 的部分,在這裡是 minus2num() 函式,依照下面的指示,如果不想 stage 的部分開頭為 '+',就把那一行刪除,如果開頭為 '-' ,就用空白來取代 '-' 。

編輯完成後按 "ctrl + x" (也就是 ^X ) 離開編輯,按 y 確認編輯,不更改檔名直接確認後,就可以進行 commit 了。如下:


綠字代表的是剛剛 stage 上去的 add2num() 函式的部分,紅字則是我們剛剛修改掉未被 stage 上去的 minus2num() 的部分。
最後將剩下的部分 stage 然後再 commit,就可以達成分次 commit 的效果囉。此外,git add -p 這個指令後面可以接檔案名稱,來直接指定要 stage 哪個 file 的 hunk。

那如果檔案還處於 untracked 的狀態該怎麼辦? 先用 git add -N <filename> 將檔案加入 tracked 的行列,再使用 git add -p 就可以選擇要 commit 的部分了。

git stash/git stash pop


  • git stash將目前 working directory 所做的更動都放到 stash 裡
  • git stash pop將放置在 stash 裡的更動釋放回來
接續上述的例子:


















假如我們已經先做了一些更動,但是做到中途發現需要新增一個函式或是修正功能的話,而且目前正在開發的功能還未到能夠 commit 的程度,用上 git stash 指令:

可以發現在使用 git stash 之前,更動還存在,但是在使用後,更動就不見了,是不是很好用。


這時候我們就可以選擇先 create 一個 branch 出來(建議!)或是直接新增、修改 code。我們新增了一個 multi2num() 的函式,並 commit:


將之前所存的變更從 stash pop 出來:


可惜天不從人願,有時發現會有衝突 ( conflict ),再來將衝突解決。檔案中有衝突的地方會被標記成:

將其修改成(我們預期的樣子):


你會發現..... 崩潰!?!?!?


了嗎? 完全白做了.... 
別急,首先將剛剛有修正過的含有 conflict 的檔案 unstage 一次


然後,我們在看一下狀態:



ㄟ黑~ 結果就是跟我們預期的一樣:multi2num() 這個函式已經新增完畢了,而且上次未更改完的部分還可以繼續更改。

當然,如果沒有遇到衝突就會很輕鬆拉:
下面是 pop 出來後與原本沒有衝突的情況:


這樣就可以放心的繼續修改還未完成的部分了。

沒有留言:

張貼留言