在Git上,假设我把提交弄乱了,我想把3版提交变成新版本。如果我做git checkout xxxx,它会创建一个新的分支,看起来我只能合并它?我可以把这个变成新的"主版本"吗?
我想要:
成为
其中f与c的内容完全相同
如果我使用git revert xxxx,它看起来肯定会有冲突,我需要手动解决。
我真正想要的是在某个时刻使旧的提交成为新的提交,而不管我的工作目录中有什么或者最新的提交。
我该怎么做呢?
1 2 3
| git rm -r .
git checkout HEAD~3 .
git commit |
提交之后,新的HEAD中的文件将与修订版HEAD~3中的文件相同。
- 这似乎是我想要的。谢谢。如果我想引用sha-1哈希的版本,我应该做git checkout head~xxxxx吗?
- 不,只有git checkout XXXXX。rev~n是指rev之前的n次修订。
- 头3后的圆点很重要。
- @是吗,我刚才错过了,发现了另一个可爱的功能。
- 这是可行的,但我觉得应该有一个更优雅的方式来做到这一点。
- @加布里埃尔,这个解决方案有什么不妥?如果您想用另一个提交的内容完全替换工作目录,在我看来,这是一个简单的方法。
- 对于大型repo,需要一段时间删除所有文件,然后将它们全部签出。我觉得Git应该有一种方法可以在不删除所有内容的情况下恢复到旧版本。但这只是我的观点,这对我很有效,我在寻找替代品时没有发现更好的方法。
- 3代表什么?3从开始还是最近?
- @Watson HEAD~3是指"HEAD父母的父母"。
- 是否可以使用特定的提交ID?
- @那么,HEAD~99代表什么呢?
- @约瑟夫是的,你可以使用提交ID。
- 可以解释一下rm -r .的作用?
- 我注意到这个命令不管理git mv移动的文件。重命名后的文件仍然存在。
- 如果你使用git checkout XXXXX .,不要忘记末尾的.。与@bbuser建议的HEAD~3 .相同。
- HEAD~3后面的点代表什么?这是否与bash当前目录相同?
- @是的,没错,这是当前目录。
听起来您只是想重置为C;这使得树:
A-B-C
你可以用reset来实现:
(注意:您在前面说过三次提交,所以这就是我所写的;在您的示例中,C只是两次提交,所以您可能想要使用HEAD~2。
如果您愿意,也可以使用revert,不过据我所知,您需要一次回复一次:
1 2
| git revert HEAD # Reverts E
git revert HEAD~2 # Reverts D |
这将创建一个新的commit f,它与d和g的内容相同,而g的内容与c的内容相同。
- 嗨,谢谢你的回答。但是如果我不想做硬重置,因为它已经被推到公共存储库中了呢?
- @胡姬啊。那么您可能想使用Revert方法
- 然后git push-f强制push
- 这是否维护提交"e"并创建新的提交"f"?
- @revert方法会执行meetalexjohnson;revert会生成与指定提交相反的新提交,因此它们会取消。第一个还原将使f与e相反,第二个还原将使g与d相反,因此最终得到的代码与c中的代码相同。这就是为什么第二个还原是HEAD~2,而不是HEAD~1--f是第一个还原之后的头提交,所以需要返回2以引用d。
这正是我想要做的。我不太确定之前的命令git cherry-pick C,听起来不错,但似乎您这样做是为了从另一个分支获得更改,但不是在同一个分支,有人尝试过吗?
所以我做了一些其他的工作:我从旧的提交文件中一个接一个地得到了我想要的文件
1
| git checkout <commit-hash> <filename> |
前任:git checkout 08a6497b76ad098a5f7eda3e4ec89e8032a4da51 file.css
->这会将文件从旧提交文件中提取出来
然后我做了一些改变。我再次承诺。
1 2 3 4
| git status (to check which files were modified)
git diff (to check the changes you made)
git add .
git commit -m"my message" |
我和git log核对了我的历史,我仍然保留着我的历史以及我对旧文件所做的新修改。我也可以推。
请注意,要返回想要的状态,您需要将提交的散列放在不需要的更改之前。另外,在执行此操作之前,请确保没有未提交的更改。
Eloone用
1
| git checkout <commit-hash> <filename> |
但是你可以通过这样做更容易地签出所有文件
1
| git checkout <commit-hash> . |
- 当推到原点时,这会导致拒绝。
- 这对我有用。推到原点不是问题。
- 因此,git checkout 将分离HEAD(推送被拒绝),git checkout .应将.从提交到您的工作树中签出(所有更改),您可以将其作为新提交应用。您还可以分离HEAD并从该承诺中分支。然后它应该在HEAD为新的分支机构,你可以在那里承诺。.很重要。
git cherry-pick C
其中c是c的提交哈希。这将在最新的提交哈希之上应用旧的提交。
- git cherry-pick C将c引入的更改应用于e之上。这不是操作要求的。他希望文件的状态与它们在C中的状态完全一致,这是git checkout提供的。
到目前为止,另一个答案是创建新的提交,以撤消旧提交中的内容。可以回到过去"改变历史",但这可能有点危险。只有在更改的提交没有被推送到其他存储库时,才应该这样做。
你要找的命令是git rebase --interactive。
如果你想换头3,你要发出的命令是git rebase --interactive HEAD~4。这将打开一个文本编辑器,并允许您指定要更改的提交。
在用重要的东西尝试之前,先在不同的存储库中进行练习。手册页应该提供您所需的所有其他信息。
- 投票否决。1。这个问题明确要求保持较旧的提交,所以这可能是其他答案试图这样做的原因。2。正如您所说,提交可能已经发布了,不需要对重新平衡意味着什么进行评论。