初學git,commit了多次才push到remote,怎麼刪除不想要的commit歷史,或是刪除之前的commit記錄?
在學習指令的時候commit了多次,push之後所有commit都跟著上去,但其中有幾次是不需要的,怎麼把他們撤銷或是刪掉?
如圖,注釋是med和test2那兩個本地沒有撤銷就發上去了。現在想去掉這些commit。請問該怎麼做?
核心命令:
git rebase -i &
以及:
git push -f
首先是要在本地把這兩個提交刪除:
- 用 git rebase -i 928582641a 指定 base 為你需要刪除的提交的前一個提交, 進入 Interactive Rebase
- 刪除 pick med 和 pick test2 那兩行, 保存退出. 之後可能 git 會提示出現 conflict, 根據提示完成處理.
接著就是把本地內容 Force Push 到遠端.
- 執行 git push -f
由於你現在本地的歷史已經和遠端的歷史出現分歧, 要推送到遠端時, 必須要 Force Push 才行, 也就是 -f 參數的用意.
如果你所謂的 "撤銷" 是說修改保留, 但提交取消, 步驟也是一樣的, 只是把 pick med 和 pick test2 這兩行的 pick 改成 squash, 保存退出後根據提示, 重新編輯一下 commit message, 並完成剩下的操作. 這裡其實就是把 med 和 test2 這兩個提交合併到前一個提交中.
建議在操作的時候花點時間, 仔細閱讀一下 Interactive Rebase 時的提示, 理解 pick/squash, 以及更多的 fixup/edit 等的命令的功能和用法.
- - -
2013.11.30 更新:
因為評論無法插入格式, 所以更新在這裡了.
之前的回答中已經建議去看下面的提示了, 裡面對 squash 的意義進行了解釋: meld into previous commit,
也就是"熔入前一個提交中", 所以是先 pick a, 使用 a 提交, 然後 squash b, 把 b 熔入前一個提交中.
# This is a combination of 2 commits.
# The first commits message is:
Change default page to welcome.php
# This is the 2nd commit message:
Accept seller_nick instead of uid
# Please enter the commit message for your changes. Lines starting
# with # will be ignored, and an empty message aborts the commit.
# rebase in progress; onto 01c128a
# You are currently editing a commit while rebasing branch tmp on 01c128a.
已經能夠解決了,回來自答一下,也向給我解答的樓上@黃鋆 反饋下。
我的問題也就是@黃鋆 提到的修改保留提交取消,去除中間無謂的commit(也就是把提交合併)。
昨晚沒搞清楚方法,最後用了git reset --hard^ 直接刪除commit再重導入文件,不太合理。今天進一步學習了一下git rebase -i,之前跟@黃鋆 回復的輸入git rebase -i 時出現的需要--set-upstream-to提示也理解了一點, 另外參照了stackoverflow的一篇解答:How can I merge two commits into one?
例如我現在要將最近a,b(a先b後)兩個提交合併,我可以使用git rebase -i HEAD~2進入後到如下內容
pick b76d157 a
pick a931ac7 b# Rebase df23917..a931ac7 onto df23917
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commits log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
將b的pick替換為squash, 然後保存退出,再經提示信息也保存退出後查看git log就可以看到a,b已經合併到一塊了,可以通過git commit -amend把注釋修改掉,然後再git push -f到遠端,就把不需要的a提交「去掉「了。
我理解因為是squash的b,所以是新的蓋舊的,文件修改都不變。不知道理解的對不對。而且這裡如果改a的pick為squash的話是不行的。有的細節還不了解。需要繼續學習~我的方法是,git commit之前,先review自己本地的代碼,合適的commit做reset然後合併
推薦閱讀:
※git clone和 git pull 操作都正常,但是不能push,這是為什麼?
※git是什麼?github又是什麼?他們都有什麼用啊?
※一入前端深似海,從此紅塵是路人系列第十彈之如何合理利用Git進行團隊協作(一)
※【開源必備】常用git命令