標籤:

初學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 熔入前一個提交中.

在 rebase 保存退出後, 隨後的提示信息是由 squash 命令觸發的, 此時你可以對熔合後的 commit message 進行編輯, 而不需要在結束後 git commit --amend.

下面是我剛用自己的一個倉庫, 在最新的 git 1.8.5 版本下, 使用 squash 後的提示, 可以看到有非常詳細的提示說明. 隨著版本的演進, git 在文檔和提示方面已經日益完善了, 絕大部分命令都可以在使用過程中得到詳細的指導, 請務必不要錯過.

# 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命令

TAG:Git | GitHub |