删除本地 Git 更改的各种方法

Posted

技术标签:

【中文标题】删除本地 Git 更改的各种方法【英文标题】:Various ways to remove local Git changes 【发布时间】:2014-05-02 11:00:12 【问题描述】:

我刚刚克隆了一个 git 存储库并签出了一个分支。我处理了它,然后决定删除我所有的本地更改,因为我想要原始副本。

简而言之,我必须执行以下两个命令来删除我的本地更改

git checkout .

git clean -f

我的问题是,

(1)这是摆脱本地更改的正确方法吗,否则请告诉我正确的方法。

(2) 我们什么时候使用git reset --hard,因为即使没有这个命令我也可以重置

谢谢

*解决方案:主要编辑:03/26:* 用 git 特定的术语替换了许多模糊的术语 [跟踪/未跟踪/暂存/未暂存]

当我们进行本地更改时,可能只有三类文件:

类型 1. 分阶段跟踪文件

类型 2. 未暂存的跟踪文件

类型 3. Unstaged UnTracked files a.k.a UnTracked files

已暂存 - 已移至暂存区/已添加到索引中 跟踪 - 修改文件 未跟踪 - 新文件。始终未上演。如果分阶段进行,则意味着他们会被跟踪。

每个命令的作用:

    git checkout . - 仅删除未暂存的跟踪文件 [类型 2]

    git clean -f - 仅删除未暂存的未跟踪文件 [类型 3]

    git reset --hard - 仅删除分阶段跟踪和非分阶段跟踪文件[类型 1,类型 2]

    git stash -u - 删除所有更改 [Type 1, Type 2, Type 3]

结论:

很明显,我们可以使用任何一个

(1) combination of `git clean -f` and `git reset --hard` 

(2) `git stash -u`

达到预期的效果。

注意:存放,因为这个词的意思是“将(某物)安全、秘密地存放在指定的地方。”这始终可以使用git stash pop 检索。 因此,在上述两个选项之间进行选择是开发人员的电话。

感谢 Christoph 和 Frederik Schøning。

编辑:03/27

我认为值得将“当心”备注发送到git clean -f

git clean -f

没有回头路。使用-n--dry-run 预览您将造成的伤害。

如果您还想删除目录,请运行 git clean -f -d

如果您只想删除被忽略的文件,请运行git clean -f -X

如果您想删除被忽略的文件和未被忽略的文件,请运行git clean -f -x

参考:git clean 的更多信息:How to remove local (untracked) files from the current Git working tree?

编辑:2015 年 5 月 20 日

丢弃该分支上的所有本地提交 [删除本地提交]

为了丢弃该分支上的所有本地提交,使本地分支相同 到这个分支的“上游”,只需运行git reset --hard @u

参考:http://sethrobertson.github.io/GitFixUm/fixup.html

或者做git reset --hard origin/master [如果本地分支是master]

注意:2015 年 6 月 12 日不是与标记为重复的其他 SO 问题的重复。这个问题解决了如何删除本地 GIT 更改 [删除添加的文件、删除添加到现有文件的更改等以及各种方法;在其他 SO 线程中仅解决如何删除本地提交的位置。如果您添加了一个文件,并且您想单独删除它,那么另一个 SO 线程不会讨论它。因此,这不是另一个的重复]

编辑:06/23/15

如何恢复已经推送到远程仓库的提交?

$ git revert ab12cd15

编辑:09/01/2015

从本地分支和远程分支中删除之前的提交

案例:您刚刚对本地分支提交了更改并立即推送到远程分支, 突然意识到,哦不!我不需要这个改变。现在做什么?

git reset --hard HEAD~1 [用于从本地分支删除该提交]

git push origin HEAD --force [这两个命令都必须执行。从远程分支删除]

什么是分支?它是当前签出的分支。

Edit 09/08/2015 - 删除本地 git merge

我在master 分支上并将master 分支与新工作的分支phase2 合并

$ git status
# On branch master

$ git merge phase2

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 8 commits.

问:如何摆脱这种合并? 试过git reset --hardgit clean -d -f 两者都不起作用。

起作用的只有以下任何一种:

$ git reset --hard origin/master

$ git reset --hard HEAD~8

$ git reset --hard 9a88396f51e2a068bb7 [sha 提交代码 - 这是在所有合并提交发生之前存在的那个]

【问题讨论】:

我猜这个帖子可能会回答你的问题:***.com/questions/1146973/… "git stash" 将删除您所做的任何更改。 不错的总结!我会添加另一个文件类别:“类型 4。忽略的文件。” git stash -a [或 --all] 也将隐藏被忽略和未跟踪的文件。 git clean -x 也会清理被忽略的文件。 git clean -X 将只清理被忽略的文件。 @JavaDev 您的问题更像是一个答案。感谢您继续编辑和编译所有答案。 感谢我运行了所有 4 个命令来反转本地更改 【参考方案1】:

选项 1:放弃跟踪和未跟踪的文件更改

放弃对暂存文件和未暂存文件所做的更改。

$ git reset --hard [HEAD]

然后完全丢弃(或删除)未跟踪的文件。

$ git clean [-f]

选项 2:隐藏

您可以先存储您的更改

$ git stash

然后根据您想要执行的操作将其放下或弹出。见https://git-scm.com/docs/git-stash#_synopsis。

选项 3:手动将文件恢复到原始状态

首先我们切换到目标分支

$ git checkout <branch-name>

列出所有有变化的文件

$ git status

手动将每个文件恢复到原始状态

$ git restore <file-path>

【讨论】:

【参考方案2】:

此时添加答案的原因:

到目前为止,我正在将结论和“答案”添加到我最初的问题本身,使问题变得非常冗长,因此转向单独的答案。

我还添加了更多常用的 git 命令,这些命令可以帮助我使用 git,也可以帮助其他人。

基本上清除所有本地提交 $ git reset --hard$ git clean -d -f


在您进行任何提交之前的第一步是配置您的用户名和与您的提交一起显示的电子邮件。

#设置要附加到提交事务的名称

$ git config --global user.name "[name]"

#设置您要附加到提交事务的电子邮件

$ git config --global user.email "[email address]"

#列出全局配置

$ git config --list

#列出远程网址

$ git remote show origin

#检查状态

git status

#列出所有本地和远程分支

git branch -a

#创建一个新的本地分支并开始在这个分支上工作

git checkout -b "branchname" 

或者,它可以分两步完成

创建分支:git branch branchname 在这个分支上工作:git checkout branchname

#commit local changes [两步过程:- 将文件添加到索引,即添加到暂存区。然后提交此暂存区域中存在的文件]

git add <path to file>

git commit -m "commit message"

#checkout some other local branch

git checkout "local branch name"

#remove all changes in local branch [假设您在本地分支中进行了一些更改,例如添加新文件或修改现有文件,或者进行本地提交,但不再需要] git clean -d -fgit reset --hard [清除对本地分支所做的所有本地更改,除非本地提交]

git stash -u 也会删除所有更改

注意: 很明显,我们可以使用 (1)git clean –d –fgit reset --hard的组合 要么 (2)git stash -u 达到预期的效果。

注 1:Stashing,因为这个词的意思是“将(某物)安全、秘密地存放在指定的地方。”这总是可以使用 git stash pop 来检索。因此,在上述两个选项之间进行选择是开发人员的电话。

注意 2:git reset --hard 将删除工作目录更改。请务必在运行此命令之前存储您想要保留的任何本地更改。

#切换到master分支并确保你是最新的。

git checkout master

git fetch [这可能是必要的(取决于您的 git 配置)以接收有关 origin/master 的更新]

git pull

#将feature分支合并到master分支中。

git merge feature_branch

# 将主分支重置为原始状态。

git reset origin/master

#不小心从本地删除了一个文件,如何找回来? 执行git status 以获取已删除资源的完整文件路径

git checkout branchname <file path name>

就是这样!

#将主分支与其他分支合并

git checkout master
git merge someotherbranchname

#rename 本地分支

git branch -m old-branch-name new-branch-name

#删除本地分支

git branch -D branch-name

#delete 远程分支

git push origin --delete branchname

git push origin :branch-name

#revert 已推送到远程存储库的提交

git revert hgytyz4567

#branch 来自使用 GIT 的先前提交

git branch branchname <sha1-of-commit>

#更改已推送到远程的最新提交的提交消息

git commit --amend -m "new commit message"
git push --force origin <branch-name>

# 丢弃该分支上的所有本地提交 [删除本地提交]

为了丢弃该分支上的所有本地提交,使本地分支与该分支的“上游”相同,只需运行

git reset --hard @u

参考:http://sethrobertson.github.io/GitFixUm/fixup.html 或者git reset --hard origin/master [如果本地分支是主分支]

# 恢复已推送到远程存储库的提交?

$ git revert ab12cd15

#从本地分支和远程分支删除之前的提交

用例: 你刚刚对本地分支提交了更改,并立即推送到远程分支,突然意识到,哦不!我不需要这个改变。现在做什么?

git reset --hard HEAD~1 [用于从本地分支中删除该提交。 1 表示您所做的 ONE 提交]

git push origin HEAD --force [这两个命令都必须执行。从远程分支删除]。当前签出的分支将被称为您正在执行此操作的分支。

#从本地和远程仓库中删除一些最近的提交并保留到您想要的提交。 (一种从本地和远程恢复提交)

假设您有 3 个提交已推送到名为“develop”的远程分支

commitid-1 done at 9am
commitid-2 done at 10am
commitid-3 done at 11am. // latest commit. HEAD is current here.

恢复到旧的提交(改变分支的状态)

git log --oneline --decorate --graph // 查看你所有的 commitids

git clean -d -f // 清除所有本地更改

git reset --hard commitid-1 // 本地恢复到这个 commitid

git push -u origin +develop // 将此状态推送到远程。 + 强制推送

# 移除本地 git 合并: 案子: 我在 master 分支上,并将 master 分支与一个新工作的分支 phase2 合并

$ git status

在主分支上

$ git merge phase2 $ git status

在主分支上

您的分支领先于“origin/master”8 次提交。

问:如何摆脱这个本地 git 合并? 试过 git reset --hardgit clean -d -f 都不起作用。 唯一有效的是以下任何一种:

$ git reset --hard origin/master

$ git reset --hard HEAD~8

$ git reset --hard 9a88396f51e2a068bb7 [sha 提交代码 - 这是在所有合并提交发生之前存在的那个]

#创建 gitignore 文件

touch .gitignore // 在 mac 或 unix 用户中创建文件

示例 .gitignore 内容:

.project
*.py
.settings

GIT 备忘单参考链接:https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf

【讨论】:

您的删除远程分支的命令可能不是最好的。您正在使用 git push origin :branch-name 但我建议使用 git push origin --delete branchname 同意,我更新了你的建议,谢谢@vibs2006【参考方案3】:

我认为 git 有一件事没有明确记录。我认为它实际上被忽视了。

git checkout .

伙计,你拯救了我的一天。我总是想尝试使用修改后的代码。但有时这些事情最终会弄乱修改后的代码,添加新的未跟踪文件等。所以我想做的是,分阶段做我想做的事情,做一些乱七八糟的事情,然后快速清理并提交,如果我高兴的话。

git clean -fd 适用于未跟踪的文件。

然后git reset 简单地删除了staged,但是git checkout 有点太麻烦了。逐个指定文件或使用目录并不总是理想的。有时我想要删除的更改文件位于我想要保留的目录中。我希望这个命令只删除未暂存的更改,然后就可以了。谢谢。

但我认为他们应该只拥有git checkout 没有任何选项,删除所有未暂存的更改并且不要触及暂存的。它有点模块化和直观。更像git reset 所做的。 git clean 也应该这样做。

【讨论】:

【参考方案4】:

首先检查您的重要更改是否保存:

$ git 状态

比 试试

$ git reset --hard

它将您的分支重置为默认值

但如果您只需要撤消:

$ 编辑 (1) $ git添加frotz.c filfre.c $ mailx (2) $ git 重置 (3) $ git pull git://info.example.com/nitfol


阅读全文>>https://git-scm.com/docs/git-reset

【讨论】:

旁注:reset --hard 是危险命令,这将删除所有更改并且无法撤消。用户在使用硬重置时应注意。【参考方案5】:

对于丢弃所有,我喜欢存储并丢弃该存储,这是丢弃所有的最快方法,特别是如果您在多个存储库之间工作。

这将隐藏0 键中的所有更改并立即将其从0 中删除

git stash &amp;&amp; git stash drop

【讨论】:

【参考方案6】:

用途:

git checkout -- <file>

放弃工作目录中的更改。

【讨论】:

【参考方案7】:

1。当您根本不想保留本地更改时。

git reset --hard

此命令将从本地存储库中完全删除所有本地更改。这是在 pull 命令期间避免冲突的最佳方法,前提是您根本不想保留本地更改。

2。当您想保留本地更改时

如果您想从远程拉取新的更改并想忽略 然后在此拉取期间进行本地更改,

git stash

它将存储所有本地更改,现在您可以拉取远程更改,

git pull

现在,您可以通过以下方式恢复本地更改,

git stash pop

【讨论】:

git reset --hard 不会删除所有本地更改。它只删除修改。如果要删除添加,则还必须git clean -fd【参考方案8】:

这完全取决于您要撤消/还原的内容。从阅读the post in Ube's link 开始。但要尝试回答:

硬重置

git reset --hard [HEAD]

完全删除对跟踪文件的所有暂存和未暂存更改。

我发现自己经常使用硬重置,当我想“就像我从遥控器完成完全重新克隆一样撤消所有操作”。在您的情况下,您只希望您的回购原始,这将起作用。

干净

git clean [-f]

删除未跟踪的文件。

用于删除临时文件,但保留已跟踪文件的暂存和未暂存更改。大多数时候,我可能最终会制定一个忽略规则而不是反复清理 - 例如对于 C# 项目中的 bin/obj 文件夹,您通常希望将其从存储库中排除以节省空间,或类似的东西。

-f(强制)选项也将删除未被跟踪的文件并且也被 git 通过忽略规则忽略。在上述情况下,使用忽略规则从不跟踪 bin/obj 文件夹,即使这些文件夹被 git 忽略,使用 force-option 也会将它们从文件系统中删除。我偶尔看到过这个的用途,例如在编写部署脚本时,您想在部署、压缩或其他任何操作之前清理代码。

Git clean 不会触及已经被跟踪的文件。

结帐“点”

git checkout .

在阅读您的帖子之前,我实际上从未见过这种符号。我很难找到这方面的文档(也许有人可以提供帮助),但从玩了一下,它看起来意味着:

“撤消我的工作树中的所有更改”。

即撤消跟踪文件中未暂存的更改。它显然不涉及分阶段的更改,并且单独留下未跟踪的文件。

暂存

有些答案提到了存储。正如措辞所暗示的那样,当您处于某些事情的中间(尚未准备好提交)时,您可能会使用存储,并且您必须暂时切换分支或以某种方式处理代码的另一个状态,稍后才能返回您的“混乱桌子”。我认为这不适用于您的问题,但它绝对很方便。

总结一下

一般来说,如果你确信你已经提交并且可能会推送到远程重要更改,如果你只是在玩耍或类似的东西,使用git reset --hard HEAD 后跟git clean -f 将明确地将你的代码清理到状态,它将在,如果它刚刚被克隆并从分支中签出。需要强调的是,重置也将删除分阶段但未提交的更改。 它将清除所有未提交的内容(除了未跟踪的文件,在这种情况下,请使用 clean)。

所有其他命令都是为了促进更复杂的场景,其中需要“撤消东西”的粒度:)

我觉得,您的问题 #1 已涵盖,但最后要总结 #2:您从未发现需要使用 git reset --hard 的原因是您从未上演过任何事情。如果您进行了更改,git checkout .git clean -f 都不会恢复。

希望这能涵盖。

【讨论】:

感谢您使用git reset --hard 背后的原因。我试过了,是的..那些添加到索引(暂存)的文件仅在git reset --hard 之后被删除,我假设默认情况下git reset --hardgit reset --hard head。这个链接也很有帮助gitready.com/beginner/2009/01/18/the-staging-area.html 我改进了我的答案,为什么我认为git stash -u 在这里最有意义。 谢谢你们俩。我已经总结了答案并嵌入到我的问题中。 Christoph 让我知道 git stash -u 做了什么以及如何弹出它,但 Frederik 让我知道重设困难并使用 git reset --hardgit clean -f 的组合,以及为什么在某些情况下不首选 stash。现在请帮助我选择我应该将哪一个标记为答案:),两者都是我的答案。 . 是一个引用当前工作目录的路径规范,它可能是 repo 的根目录。来自 git-scm.com:git checkout [&lt;tree-ish&gt;] [--] &lt;pathspec&gt;… 从索引文件或命名的 更新工作树中的命名路径。 强调git reset --hardgit clean -dfx 之类的都是破坏性。无论如何,请修复答案中的小写head,它应该是大写HEAD,或者根本不存在。【参考方案9】:

最好的方法是检查更改。

在名为 project-name 的项目中更改文件 pom.xml 即可:

git status

# modified:   project-name/pom.xml

git checkout project-name/pom.xml
git checkout master

# Checking out files: 100% (491/491), done.
# Branch master set up to track remote branch master from origin.
# Switched to a new branch 'master'

【讨论】:

【参考方案10】:

与 git 中的所有内容一样,有多种方法可以做到这一点。您使用的两个命令是一种方法。您可以做的另一件事是简单地将它们隐藏在git stash -u 中。 -u 确保新添加的文件(未跟踪)也包括在内。

git stash -u 的方便之处在于

    这可能是实现目标的最简单(唯一?)的单一命令 如果您之后改变主意,您可以通过git stash pop 恢复所有您的工作(这就像删除 gmail 中的电子邮件,如果您之后改变主意,您可以撤消)

至于您的其他问题git reset --hard 不会删除未跟踪的文件,因此您仍然需要git clean -f。但是git stash -u 可能是最方便的。

【讨论】:

git reset --hard确实不会删除未跟踪的文件,但它删除已在索引中的未跟踪更改,即对文件的更改.我确定这就是你的意思:) 当我使用git stash -u 时,我看到了来自 git bash 的响应。 "保存在 branchname 上的工作目录和索引状态 WIP。可能这个保存的就是我们可以使用 git stash pop 检索的内容。 谢谢你们俩。我已经总结了答案并嵌入到我的问题中。 Christoph 让我知道 git stash -u 做了什么以及如何弹出它,但 Frederik 让我知道重设困难并使用 git reset --hardgit clean -f 的组合,以及为什么在某些情况下不首选 stash。现在请帮助我选择我应该将哪一个标记为答案:),两者都是我的答案。 但是如果有一个我不想跟踪的文件添加到我的存储库怎么办?仅在我的仓库中。如果我将它添加到忽略列表中,那么我有一个 .ignore 文件要提交,这也会影响其他所有人。

以上是关于删除本地 Git 更改的各种方法的主要内容,如果未能解决你的问题,请参考以下文章

怎样从本地删除git远程仓库里面的文件

git可视化工具Sourcetree使用全攻略(包括各种git冲突解决)

Git使用记录:Git各种撤销操作

如何删除git远程仓库的某个文件

git删除本地所有的更改

git 命令使一个分支像另一个分支