【问题标题】:How can I unstage my files again after making a local commit?进行本地提交后,如何再次取消暂存文件?
【发布时间】:2011-10-04 16:39:42
【问题描述】:

我已经执行了以下命令

git add <foo.java>
git commit -m "add the foo.java file"

如何现在删除我的本地提交并取消暂存 foo.java?

如果我输入git reset --hard,我发现它会将我修改后的foo.java 还原为原来的。

【问题讨论】:

    标签: git


    【解决方案1】:

    用途:

    git reset HEAD^
    

    默认情况下会进行“混合”重置,这将按照您的要求进行;将 foo.java 放入 unstaged,删除最近的提交。

    【讨论】:

    • 您介意向我解释一下什么是“混合”重置、“软”重置和“硬”重置吗?
    • @Kit Ho - git reset 手册对这些有很好的描述。
    • @Kit, @manojlds:stackoverflow.com/questions/2530060/… 也是如此(无耻的插头)
    • 这实际上是唯一正确的答案。其他两个答案将在提交后再次暂存文件。
    • git reset --soft 不起作用,但 git reset HEAD^ 起作用
    【解决方案2】:

    git reset --soft 仅此而已:它类似于git reset --hard,但不涉及文件。

    【讨论】:

    • 这是我听过的最容易理解的解释(只有 11 个字)!谢谢!
    • 那个答案是错误的。 git reset“就像git reset --hard,但不涉及文件。”。不是git reset --softgit reset --soft 将暂存更改,因此您不必将它们添加到暂存中以防万一您要提交它们,但您必须 git reset 它们(是的,第二次,并且没有 --soft)如果你没有。所以这个答案很简短,但不正确。
    【解决方案3】:

    git reset --soft HEAD~1 应该做你想做的事。在此之后,您将在索引中进行第一次更改(使用git diff --cached 可见),并且您的最新更改不会暂存。 git status 将如下所示:

    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   foo.java
    #
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #
    #       modified:   foo.java
    #
    

    然后您可以执行git add foo.java 并同时提交这两项更改。

    【讨论】:

    • 我编辑了答案:“要提交的更改”是第一个更改,“未暂存的更改”是第二个更改。
    • 这个答案中描述的实际上是git commit --amend 所做的;但工作流程要复杂得多。尽管给出了一个很好的方向 (git reset),但这并不能回答 OP 提出的问题。
    • 必须将 '^' 替换为 '~' 才能正常工作,所以它看起来像:git reset --soft HEAD~
    • 执行 git reset --soft HEAD~1 然后 git reset HEAD
    • 完美回答我想要的!
    【解决方案4】:

    对我来说,以下是更易读(因此更可取)的方式:

    git reset HEAD~1
    

    除了1,可以有任意数量的你想取消暂存的提交。

    【讨论】:

    • @AlexandreDaubricourt 您可以使用任何名称创建命令(别名)或函数供您自己使用。例如,它可以是git_unstage(num_of_commits)。这可能需要一些努力,因为它可能需要传递一个参数(提交次数),但这是可能的。
    • 我对此毫无疑问,但这应该是一个内置功能。
    【解决方案5】:

    用于取消暂存您上次提交中的所有文件 -

    git reset HEAD~

    【讨论】:

      【解决方案6】:

      “重置”是在本地撤消更改的方式。提交时,您首先选择要包含在“git add”中的更改——这称为“暂存”。一旦更改完成,然后您“git commit”它们。

      要从暂存或提交中退出,您“重置”了 HEAD。在一个分支上,HEAD 是一个指向最近提交的 git 变量。因此,如果您已暂存但尚未提交,则您“git reset HEAD”。通过取消舞台上的更改,这可以支持当前的 HEAD。它是“git reset --mixed HEAD~0”的简写。

      如果你已经提交了,那么 HEAD 已经推进了,所以你需要备份到之前的提交。这里你“reset HEAD~1”或“reset HEAD^1”或“reset HEAD~”或“reset HEAD^ "-- 所有引用 HEAD 减一。

      ~ 或 ^ 哪个符号更好?将 ~ 波浪号视为一个单个流 - 当每个提交都有一个父级并且它只是一系列顺序更改时,您可以使用波浪号引用备份流,作为 HEAD~ 1,HEAD~2,HEAD~3,用于父母、祖父母、曾祖父母等(从技术上讲,它是在早期的世代中寻找第一个父母)。

      当有合并时,提交有多个父级。这就是 ^ 插入符号发挥作用的时候——你可以记住,因为它显示了分支聚集在一起。使用插入符号,HEAD^1 将是第一个父项,HEAD^2 将是单个提交的第二个父项——例如,母亲和父亲。

      因此,如果您只是在单亲提交上返回一跳,那么 HEAD~ 和 HEAD^ 是等效的——您可以使用任何一个。

      此外,重置可以是 --soft--mixed--hard。软重置只是撤销提交——它重置了 HEAD,但它不会从之前的提交中检出文件,因此工作目录中的所有更改都将被保留。而--soft reset 甚至不会清除stage(也称为index),所以所有被staged 的​​文件仍然会在stage 上。

      --mixed 重置(默认)也不会从早期提交中检出文件,因此所有更改都被保留,但阶段被清除。这就是为什么一个简单的“git reset HEAD”将清除舞台的原因。

      --hard 重置会重置 HEAD,并清除阶段,但它还会检查早期提交中的所有文件,因此它会覆盖所有更改。

      如果您已将提交推送到远程存储库,那么 reset 就不能很好地工作。你可以在本地重置,但是当你尝试推送到远程时,git 会看到你本地的 HEAD 在远程分支中的 HEAD 之后,会拒绝推送。您也许可以强制推送,但 git 真的不喜欢这样做。

      或者,如果您想保留更改,您可以stash签出较早的提交,取消存储更改,暂存它们,创建新提交,然后推动它。

      【讨论】:

      • +1 为操作的详细解释。 IMO 这应该是公认的答案!
      【解决方案7】:

      假设您想要取消暂存更改最多 n 次提交,

      其中提交哈希如下:

      • h1
      • h2 ...
      • hn
      • hn+1

      然后运行以下命令:
      git reset hn

      现在 HEAD 将位于 hn+1。从 h1 到 hn 的更改将不会暂存。

      【讨论】:

        猜你喜欢
        • 2015-10-10
        • 2016-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-02
        • 2011-06-18
        相关资源
        最近更新 更多