签出旧提交并使其成为新提交

hug*_*gie 190 git

在Git上,说我弄乱了我的提交,我想让版本3提交以前作为新版本.如果我这样做git checkout xxxx,它会创建一个新的分支,似乎我只能合并它?我可以把它变成新的"主版"吗?

我想要:

A-B-C-D-E
Run Code Online (Sandbox Code Playgroud)

成为

A-B-C-D-E-F
Run Code Online (Sandbox Code Playgroud)

其中F与C的内容完全相同

如果我使用git revert xxxx,它似乎肯定会有冲突,我需要手动解决它.

我真正想要的只是在某个时刻进行旧提交新的提交,无论我的工作目录或最新的提交是什么.

我该怎么做呢?

svi*_*ick 203

git rm -r .
git checkout HEAD~3 .
git commit
Run Code Online (Sandbox Code Playgroud)

提交后,新文件HEAD将与修订版中的文件相同HEAD~3.

  • HEAD~3之后的点很重要. (89认同)
  • 这是有效的,但我觉得应该有一个更优雅的方式来做到这一点. (13认同)
  • 不,只是`git checkout XXXXX`.`rev~n`在`rev`之前表示*n*修订版. (7认同)
  • 使用大型仓库需要一段时间才能删除所有文件,然后将它们全部检出.我觉得git应该有办法恢复旧版本,而不必删除所有内容.但这只是我的观点,这对我来说效果很好,当我在寻找替代方案时,我没有看到更好的方法. (6认同)
  • @svick那么`HEAD~99`代表什么? (4认同)
  • 是否可以使用特定的提交ID? (3认同)
  • 可以解释一下`rm -r .`的作用吗? (3认同)
  • @Gabriel,这个解决方案有什么不雅?如果你想用另一个提交的内容完全替换工作目录,这对我来说就像一个直接的方法. (2认同)
  • @watson `HEAD~3` 表示“`HEAD` 的父级的父级的父级的父级的父级”。 (2认同)
  • @Joseph是的,您可以使用提交ID. (2认同)
  • 如果您使用“git checkout XXXXX .”,请不要忘记末尾的“.”。正如 @bbuser 所建议的那样,与“HEAD~3 .”相同。 (2认同)
  • @PeteAlvin 不,它不会丢失任何历史。 (2认同)

Mic*_*zek 30

听起来你只想重置为C; 那就是树:

ABC

你可以这样做reset:

git reset --hard HEAD~3
Run Code Online (Sandbox Code Playgroud)

(注意:你说过三次提交,所以这就是我写的;在你的例子中C只有两次提交,所以你可能想要使用HEAD~2)


您也可以revert根据需要使用,但据我所知,您需要一次恢复一个:

git revert HEAD     # Reverts E
git revert HEAD~2   # Reverts D
Run Code Online (Sandbox Code Playgroud)

这将创建一个新的提交F,它与D的内容相同,而G的内容与C相同.rebase如果你想要,你可以将它们压缩在一起

  • 嗨,谢谢你的回答.但是,如果我不想进行硬重置,因为它已经被推送到公共存储库呢? (3认同)
  • @huggie啊.然后你可能想要使用revert方法 (2认同)

elo*_*one 16

这正是我想要做的.我不确定上一个命令git cherry-pick C,它听起来不错,但似乎你这样做是为了从另一个分支获得更改,但不是在同一个分支上,有人试过吗?

所以我做了一些其他的工作:我从旧的提交文件中获取了我想要的文件

git checkout <commit-hash> <filename>
Run Code Online (Sandbox Code Playgroud)

例如: git checkout 08a6497b76ad098a5f7eda3e4ec89e8032a4da51 file.css

- >这会从旧提交中获取文件

然后我做了我的改变.我再次承诺.

git status (to check which files were modified)
git diff (to check the changes you made)
git add .
git commit -m "my message"
Run Code Online (Sandbox Code Playgroud)

我查看了我的历史记录git log,我仍然记录了我的历史以及从旧文件中做出的新更改.我也可以推动.

请注意,要返回到您想要的状态,您需要在不需要的更改之前放置提交的哈希值.在执行此操作之前,请确保没有未提交的更改.


Nic*_*ser 15

eloone按文件归档

git checkout <commit-hash> <filename>
Run Code Online (Sandbox Code Playgroud)

但你可以通过这样做更容易地检查所有文件

git checkout <commit-hash> .
Run Code Online (Sandbox Code Playgroud)

  • 所以`git checkout &lt;commit-hash&gt;`将分离`HEAD`(推送被拒绝),`git checkout &lt;commit-hash&gt; .`应该从提交到工作树中签出`.`(所有更改),这您可以申请作为新的提交。您还可以分离“HEAD”并分支该提交。然后它应该位于新分支的“HEAD”处,您可以在那里提交。“.”很重要。 (3认同)
  • 这会在推送到原点时导致拒绝。 (2认同)
  • 这适合我.推动原产地不是问题. (2认同)

小智 7

git cherry-pick C

其中C是C的提交哈希.这将在最新的提交之上应用旧提交.

  • `git cherry-pick C`接受C引入的*更改*并将它们应用于E之上.这不是OP所要求的.他希望文件处于他们在C中的确切状态,即`git checkout`提供. (13认同)