由于一些糟糕的挑选,我的本地 Git 存储库目前比原点提前 5 次提交,而且状态不佳。我想摆脱所有这些提交并重新开始。
显然,删除我的工作目录并重新克隆就可以了,但是再次从 GitHub 下载所有内容似乎有点过头了,而且没有很好地利用我的时间。
也许 git revert
是我需要的,但我不想在原点(甚至六个)之前完成 10 次提交,即使它确实让代码本身恢复到正确的状态.我只想假装最后半小时从未发生过。
有没有一个简单的命令可以做到这一点?这似乎是一个明显的用例,但我没有找到任何例子。
请注意,这个问题专门关于提交,而不是关于:
未跟踪的文件
未分阶段的变化
分阶段但未提交的更改
如果您的多余提交仅对您可见,您只需执行 git reset --hard origin/<branch_name>
即可移回原点所在的位置。这会将存储库的状态重置为先前的提交,并将丢弃所有本地更改。
执行 git revert
会使 new 提交删除 old 提交,从而使每个人的历史保持正常。
删除最近的提交,而不会破坏您所做的工作:
git reset --soft HEAD~1
删除最近的提交并移除更改:
git reset --hard HEAD~1
--hard "HEAD@{1}"
中
只需删除您的本地主分支并像这样重新创建它:
git branch -D master
git checkout origin/master -b master
git reset --hard origin/<branch_name>
尝试:
git reset --hard <the sha1 hash>
让你的头脑重新回到你想去的任何地方。使用 gitk 查看您想要进行的提交。您也可以在 gitk 中进行重置。
在您的分支尝试中:
git reset --hard origin/<branch_name>
因此使用“git log
”或“git status
”验证反转(到状态,没有本地提交)。
Just to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
如果您使用的是 Atlassian SourceTree 应用程序,则可以使用上下文菜单中的重置选项。
https://i.stack.imgur.com/2fbjm.jpg
简单的解决方案是将本地 master 分支 HEAD 匹配到 origin/master 分支 HEAD
git reset --hard origin/master
PS:origin/master - 是指向 master 分支的远程指针。您可以将 master 替换为任何分支名称
git reset --hard @{u}
* 删除当前分支上的所有本地更改,包括提交。我很惊讶没有人发布此内容,但考虑到您不必查找要恢复的提交或使用分支。
* 即重置到 @{upstream}
处的当前分支——通常是 origin/<branchname>
,但不总是
在回答之前,让我们添加一些背景知识,解释一下 HEAD
是什么。因为下面的一些选项会导致头部分离
首先什么是HEAD?
HEAD
只是对当前分支上当前提交(最新)的引用。
在任何给定时间只能有一个 HEAD
。 (不包括git worktree
)
HEAD
的内容存储在 .git/HEAD
中,它包含当前提交的 40 字节 SHA-1。
分离头
如果您不是最新的提交 - 这意味着 HEAD
指向历史上的先前提交,它称为 detached HEAD
。
https://i.stack.imgur.com/OlavO.png
在命令行上,它看起来像这样 - SHA-1 而不是分支名称,因为 HEAD
没有指向当前分支的尖端
https://i.stack.imgur.com/qplvo.png
关于如何从分离的 HEAD 中恢复的一些选项:
git结帐
git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back
这将签出指向所需提交的新分支。此命令将检出给定的提交。此时,您可以创建一个分支并从这一点开始工作。
# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>
# create a new branch forked to the given commit
git checkout -b <branch name>
git reflog
您也可以始终使用 reflog
。
git reflog
将显示更新 HEAD
的任何更改,并且检查所需的 reflog 条目会将 HEAD
设置回此提交。
每次修改 HEAD 时,reflog
中都会有一个新条目
git reflog
git checkout HEAD@{...}
这将使您回到所需的提交
https://i.stack.imgur.com/atW9w.png
git reset --hard
将您的 HEAD “移动”回所需的提交。
# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32
# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
注意:(从 Git 2.7 开始)您也可以使用 git rebase --no-autostash。
git revert
“撤消”给定的提交或提交范围。重置命令将“撤消”在给定提交中所做的任何更改。将提交带有撤消补丁的新提交,而原始提交也将保留在历史记录中。
# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>
此架构说明了哪个命令执行什么操作。
如您所见,reset && checkout
修改 HEAD
。
https://i.stack.imgur.com/NuThL.png
你可以使用这个 git 命令
git reset --hard origin/<branch_name>
使用任意次数,在不删除您最近创建的任何文件的情况下恢复到上次提交。
git reset --soft HEAD~1
然后使用
git reset HEAD <name-of-file/files*>
取消舞台或取消跟踪。
我有一种情况,我想删除一个未推送的提交,但该提交在另一个提交之前。为此,我使用了以下命令
git rebase -i HEAD~2
->它将重新设置最后两个提交
我使用 'drop' 作为我想要删除的提交签名。
要查看/获取您想要返回的提交的 SHA-1 id
gitk --all
回滚到那个提交
git reset --hard sha1_id
!笔记。在该提交之后所做的所有提交都将被删除(以及您对项目的所有修改)。所以首先最好将项目克隆到另一个分支或复制到另一个目录。
删除未跟踪的文件(未提交的本地更改)
git clean -df
永久删除所有本地提交并获取最新的远程提交
git reset --hard origin/<branch_name>
如果您的分支在 'origin/XXX
' 之前 5 次提交。
您可以发出:
git reset --hard HEAD~5
它应该删除最后 5 次提交。
对于未推送的本地提交,您还可以使用 git rebase -i
删除或压缩提交。
git rebase -i
是解决许多类似问题的更通用的方法,并且可以在各种情况下提供帮助。
drop
关键字(而不是删除一行)以避免 rebase 中止。
对于那些对 Visual Studio 解决方案感兴趣的人,这里是练习:
在 Team Explorer 窗口中,连接到目标存储库。然后从分支中,右键单击感兴趣的分支并选择查看历史记录。右键单击历史记录窗口中的提交,然后选择重置 -> 删除更改 (--hard)。
这将丢弃您的本地提交并将您的回购状态重置为选定的提交。即,您提取回购后的更改将丢失。
更新
上述程序在 VS2019 之前运行良好;在 VS2022 中有新的 Git 体验。工作流程类似,但 UI 有点不同。使用 Git
菜单中的 Manage Branches
代替 Team Explorer
。现在只需单击左侧的分支,其历史记录就会显示在右侧。然后去Right Click -> Reset -> Delete Changes (--hard)
如果您只想丢弃本地提交并将修改保留在文件中,请执行 git reset @~ 其他答案解决了硬重置
找到要恢复到的提交的 sha1:
za$ git reflog
... snip ...
cf42fa2... HEAD@{0}: commit: fixed misc bugs
~
~
cf42fa2... HEAD@{84}: commit: fixed params for .....
73b9363... HEAD@{85}: commit: Don't symlink to themes on deployment.
547cc1b... HEAD@{86}: commit: Deploy to effectif.com web server.
1dc3298... HEAD@{87}: commit: Updated the theme.
18c3f51... HEAD@{88}: commit: Verify with Google webmaster tools.
26fbb9c... HEAD@{89}: checkout: moving to effectif
然后使用 --mixed 标志,以便您“重置 HEAD 和索引”:
za$ git reset --mixed cf42fa2
可用标志:
za$ git reset -h
-q, --quiet be quiet, only report errors
--mixed reset HEAD and index
--soft reset only HEAD
--hard reset HEAD, index and working tree
--merge reset HEAD, index and working tree
--keep reset HEAD but keep local changes
--recurse-submodules[=<reset>]
control recursive updating of submodules
-p, --patch select hunks interactively
-N, --intent-to-add
git reset --hard <SHA-Code>
如果您在本地副本上犯了一些错误,您想确保不会被错误地推送到远程分支,这将派上用场。
可以通过查看 git 仪表板的 webVersion 来获取分支上最后一次提交的 SHA 代码。
这样您就可以与分支上的最后一次提交同步。
成功完成硬重置后,您可以执行 git pull
以确认 syn 没有任何新内容,即您可以看到该消息。
您的分支是最新的 Origin/<Branch Name>
如果您将本地存储库弄得一团糟,那么在 Git 中丢弃本地提交的可靠方法是...
使用“git config --get remote.origin.url”获取远程源的 URL 将本地 git 文件夹重命名为“my_broken_local_repo”使用“git clone
以我的经验,Eclipse 可以很好地处理周围发生的变化。但是,您可能需要在 Eclipse 中选择受影响的项目并清理它们以强制 Eclipse 重新构建它们。我猜其他 IDE 也可能需要强制重建。
上述过程的一个附带好处是,您会发现您的项目是否依赖于未放入 git 的本地文件。如果您发现缺少文件,则可以从“my_broken_local_repo”复制它们并将它们添加到 git。一旦你确信你的新本地仓库拥有你需要的一切,你就可以删除“my_broken_local_repo”。
对于所有未暂存的更改git checkout -- .
对于特定文件 git checkout -- path/to/file/to/revert
更新:
您可以在此处使用新的 GIT LFS:https://git-lfs.github.com/
git lfs migrate import --include="*.file_type"
然后 git 推送
您可以查看使用带有 drop 命令的交互式变基
所以说最后三个提交......
git rebase -i HEAD~3
交换选择命令
pick <hash1> Commit message 1
pick <hash2> Commit message 2
pick <hash3> Commit message 3
对于删除命令
drop <hash1> Commit message 1
drop <hash2> Commit message 2
drop <hash3> Commit message 3
git reset --hard <commit hash, branch, or tag>
如果您想转到远程分支以外的特定参考。git reset --hard origin/<branch_name>
它也会重置项目配置,因此请注意这一点。我有一个很大的.cfg
文件,它被重置为默认值。我不得不再次花费数小时。revert
时,我失去了很多工作,这样我就可以在推送之前取出一个敏感值。