git reset --hard <commit_id>
我运行该命令为什么不是删除这个快照而是调到这个快照了。前几个小时实验的,应该不会记错。
1
akatquas 2019-01-27 21:57:58 +08:00 via iPhone
rebase ?
|
2
frylkrttj OP |
3
frylkrttj OP @ akatquas 找过好多教程了,rebase 也试过了总不是删除我指定的那个 commit,我还想同时删除多个 commit 不知道怎么做。
|
4
des 2019-01-27 22:07:47 +08:00 via Android
“彻底回退到某个版本”
是退回到这个版本,不是上一个 你应该这样,不过新手不建议,不然怎么恢复都不知道 git reset --hard hash^ |
5
CRVV 2019-01-27 22:08:30 +08:00 via Android
|
7
xupefei 2019-01-27 22:12:01 +08:00 1
你找的那个教程太坑人了,那不是删单个 commit,而是把那个 commit 之后的全删掉。
正确的办法是 rebase: https://stackoverflow.com/questions/2938301/remove-specific-commit |
8
capric 2019-01-27 22:30:40 +08:00 via Android
使用 rebase 交互模式
rebase -i HEAD~N # 向前 N 个 commit,必须包含你要删除的那些 commit d commit_hash # 把你要删除的的 commit 前面的指令修改成 d(drop,删除、丢弃的意思) 在唤起的编辑器保存退出即可 |
9
xml123 2019-01-27 22:33:29 +08:00 1
lz 相问的可能是 revert ?
|
10
ayase252 2019-01-27 22:53:35 +08:00 1
rebase -i
reset --hard 是将 HEAD (分支的指针),索引(暂存区)以及工作目录全部恢复到指定 commit https://git-scm.com/book/zh/v2/Git-%E5%B7%A5%E5%85%B7-%E9%87%8D%E7%BD%AE%E6%8F%AD%E5%AF%86 |
12
xiri 2019-01-28 08:42:57 +08:00 via Android
求求楼主去把 git book 看完再来提问吧!有中文版的,你的问题基本都能找到答案,,,,,
https://git-scm.com/book/zh/v2 你看不懂 git 的原理没关系,至少把 git book 上的操作过一遍吧,,,,, |
16
frylkrttj OP @Yggdroot #15 每条回复我都看了 ,@akatquas #1 的回复我发帖前也找过教程 试过 rebase 没达到我删除 commit 的目的。
看了大家的回复,感觉删除 commit 比学习 git 入门教程还难。 |
17
youstu 2019-01-28 09:12:08 +08:00
rebase 交互模式可以删除
|
18
frylkrttj OP @youstu #17 看大家的回复跟我的测试结果:删除 commit 是复杂的,因为有不同情况的 commit 不知道我实验的时候是什么情况的 commit 应该用什么样的删除方式。反正 rebase 我试过一次不行。
|
19
thinkmore 2019-01-28 09:30:32 +08:00
一般回退代码使用 reset 或者 revert 更多一些吧.其实就就算是 rebase -i,也只是复制你需要的节点形成新的分支而已,而你不需要的节点仍然是不会被删除的.也不太建议删除某一个 commit object
|
20
SakuraKuma 2019-01-28 09:31:35 +08:00 1
|
21
frylkrttj OP |
22
youstu 2019-01-28 09:41:51 +08:00 1
@frylkrttj
不熟悉当然就觉得复杂。 也就看你要达到什么目的,如果你只是想把某几次提交回退,revert 就好。如果你是想让你的 log 好看,让某个 commit 消失,rebase 交互就可以达到目的。 至于 reset hard,你可以先 checkout 一个分支备份当前分支,然后 reset hard 到你想删除的前一个 commit,然后从备份分支上把之后的提交全部 pick 过来,中间那个 commit 也就看不见了,实际上跟 rebase 是一样的。 |
23
youstu 2019-01-28 09:44:03 +08:00
建议把教程看一遍吧: https://git-scm.com/book/zh/v2
|
24
thinkmore 2019-01-28 09:56:29 +08:00
@frylkrttj 你可以参考下我写的这篇文章,或者这一个系列 https://generalthink.github.io/2019/01/25/understanding-git-move-node/
然后 stackoverflow 上也有这个答案: https://stackoverflow.com/questions/11271263/completely-remove-commit-from-git-database |
25
Hilong 2019-01-28 10:03:28 +08:00 via Android
https://juejin.im/entry/5b0c0dac6fb9a00a2d3970e3 看看我这篇文章?写了怎么删除特定提交,就是通过 rebase,带截图操作的。
|
26
boileryao 2019-01-28 10:05:03 +08:00 via Android
说一个不用 rebase 的方法吧
对于 ABCDE 五个 commit,想删掉 B,可以从 A checkout 新分支然后 cherry-pick C..E,这个新分支就已经把 B 删掉了。 删掉一个 commit 很可能会丢数据,尽量 revert 或者通过新的提交“抵消”掉原来的更改 |
27
justicelove 2019-01-28 10:08:43 +08:00
git revert commit
|
28
itskingname 2019-01-28 10:13:57 +08:00 via iPhone
https://www.kingname.info/2015/01/08/清空 Github 上某个文件的历史 /
|
29
RoshanWu 2019-01-28 10:14:22 +08:00
revert 是正解,但可能会产生冲突。所以简单的建议 revert,复杂的建议 rebase。
|
30
lazyfighter 2019-01-28 10:24:00 +08:00
rebase
|
31
capric 2019-01-28 14:18:02 +08:00
@frylkrttj 退出的时候,自动生成的备注是 commit msg,是可以全部删除,自己编辑的,也可以保留一部分,删除不要的
|
32
lyb11232345688 2019-01-28 18:16:12 +08:00
git revert 取消某次提交。 删除是没有的,除非你重写提交记录
|
33
0xNone 2019-01-28 20:32:06 +08:00
你说的是这个吗?
我们在使用 git 的时候可能会出现提交了错误的版本,这时候我们将代码修改完成了,需要覆盖之前错误的版本,这时候就可以使用一些小技巧。 注意: 操作会覆盖掉错误版本之后其他人提交的 commit,使用需谨慎 使用 git pull 保持代码同步状态 设置 git reset <commit-id> 当前 git 版本指针到错误的版本上 使用 git stash 错误版本之后的修改,以及我们修改的内容 使用 git push --force 强制覆盖当前远程服务器上的 commit 历史 使用 git stash pop,释放暂存的修改,或继续修改代码 接下来就是一套连招,git add . -> git commit -m "message" -> git push |
34
frylkrttj OP |
35
yuikns 2019-01-28 23:16:40 +08:00 1
commit 本质是计算上一个和当前两个版本得到 diff,然后生成的 patch。 第一个 commit 的 diff 是从 orphan 开始算。see https://git-scm.com/docs/git-checkout/1.7.3.1#git-checkout---orphan
因此“删除”最近一个或若干 commit,简单回滚即可。( reset ) “删除”某个中间的 commit,后面其实全部改了,只是用 rebase 可以快速编辑一下某几个 commit,然后后面 replay 一下。但实际上 sha1 全变了。 “删除”第一个 commit,那么就需要重开一个 branch, 从什么都没有开始做。 git checkout --orphan brand-new-branch [first-sha-1, in case you need to edit] replay 也不能用 merge 了,因为它们并没有共同祖先节点。非要用也可以用 cherry-pick ( https://git-scm.com/docs/git-cherry-pick ) |
36
wbswjc 2019-01-29 01:59:44 +08:00 1
# 如果你想要删除该提交及其中内容:
你需要 rebase 中的 drop 操作。 git 仓库中有 a, b, c, d 4 个文件,依次提交,形成以下内容: $ git log > commit f3fe836c34642927f57e8f2e6cc8a62382c93c0c > d > commit 0e4f4862a0ab3256d28ced2f26950e2e4312c5b4 > c > commit a4c409545f056bb6a21f9f82d2749f6faadde70a > b > commit f3134e02ebfe4d5b70999c3dc03c8f31161cf209 > a 以首个提交,即 a 为基准,进入 rebase 模式: $ git rebase -i f313 > pick a4c4095 b > pick 0e4f486 c > pick f3fe836 d 修改 rebase 策略如下,表示删除第 3 次提交,即 c: > pick a4c4095 b > drop 0e4f486 c > pick f3fe836 d :wq 或 :x 退出 vim,开始 rebase: 因为只有一个 drop 操作,且没有影响其后任何一个 commit,所以直接全部成功: > Successfully rebased and updated refs/heads/master. 这时候: $ git log > commit 7eafc41ab349feed33c060e5898278509a71d373 > d > commit a4c409545f056bb6a21f9f82d2749f6faadde70a > b > commit f3134e02ebfe4d5b70999c3dc03c8f31161cf209 > a |
37
wbswjc 2019-01-29 02:01:44 +08:00 1
# 如果你想要删除该提交,不过保留其修改的文件:
你需要 rebase 中的 squash 操作。 git 仓库中有 a, b, c, d 4 个文件,依次提交,形成以下内容: $ git log > commit f3fe836c34642927f57e8f2e6cc8a62382c93c0c > d > commit 0e4f4862a0ab3256d28ced2f26950e2e4312c5b4 > c > commit a4c409545f056bb6a21f9f82d2749f6faadde70a > b > commit f3134e02ebfe4d5b70999c3dc03c8f31161cf209 > a 以首个提交,即 a 为基准,进入 rebase 模式: $ git rebase -i f313 > pick a4c4095 b > pick 0e4f486 c > pick f3fe836 d 修改 rebase 策略如下,表示把 c 并入其前一个 commit,即 b: > pick a4c4095 b > squash 0e4f486 c > pick f3fe836 d :wq 或 :x 退出 vim,开始 rebase: 因为只有一个 squash 操作,所以直接进入该操作: > # This is a combination of 2 commits. > # This is the 1st commit message: > b > # This is the commit message #2: > c 可以修改 b 和 c 合并( squash )后的提交信息,修改完(也可不改)后 :wq 或 :x 退出。 后面没有其他操作,所以成功: > Successfully rebased and updated refs/heads/master. 这时候: $ git log > commit db58ecd2a2cd017a34274781dc8b8c61531147b9 > d > commit 0baa7789a1533c9178874d2ab3b93c44f2adf1b3 > b > c > commit f3134e02ebfe4d5b70999c3dc03c8f31161cf209 > a |
38
fan123199 2019-01-29 07:14:59 +08:00
LZ 到底后续试了之后出现什么问题啊?理论上 rebase -i 是可以解决开头说的问题。
|
39
limuyan44 2019-01-29 08:16:54 +08:00 via Android
revert 呀,干嘛要删除啊....
|
40
frylkrttj OP @fan123199 #38 之前用 rebase -i commit_id 认为是删除该 快照,哪知道它弹出编辑器还带一堆备注我看了就懵了根本不知道怎么回事,以为是没用的废话,就关闭保存了,结果不是我要得结果,根本没有删除该快照。所以就再也没考虑这个命令了。
我一直以为删除一个 commit_id 应该跟 rm 删除一个文件一样,看来不是。 @all 请问你有没有直接删除一个快照的命令。 @wbswjc #37 #38 的回复让我知道那一堆备注是怎么回事了。不这样删除一个快照也太绕了吧,正常人的脑子都不会想到 rebase -i commit_id 选中的这个 commit_id 不是用来删除的。特别鸣谢 @wbswjc |
41
frylkrttj OP @limuyan44
A,B,C 三个 commit 其中 A 是几乎空白的提交,而 B 是不小心用了 "git add ." 把密码本提交到了 B,于是我删除了密码本文件又提交了一个 C 快照。 现在看你表演了。 |
42
lfzyx 2019-01-29 10:09:08 +08:00
|
43
julyclyde 2019-01-29 10:40:39 +08:00
单个 commit 如果没有后继的话,可以删除:没有其它东西指向它,然后 fsck 掉
如果有后继,那就只能连它带后继一起重做一遍 |
44
fan123199 2019-01-29 11:05:24 +08:00
@frylkrttj 并没有一个删除 commit 的命令(除了最近一个)。因为删除单个 commit 可能会对后续 commit 有影响,必须要 rebase 一条龙解决。
假设有三个 commit,A->B->C,改动分别是往文件中写入 a,b,c 字符。假设按你的理解要删去 B,也就是删去加入 b 这个字符。 那么这时 C 其实无法存在的,因为你删去了 B,也就是没有 b,而 C 是在 ab 上加入 c,没法简单变成 A->C。 所以 rebase -i <commit>的内核是, 让你重写所有那个 commit 之后的所有记录。如果按 hash 值来看,rebase 后的 C 并不是 C,而是 C'。你删去 B 后的历史应该是 A->C'。因为这是危险动作,需要一堆备注让你看清楚。 |