6

我有一个损坏的合并,我想恢复工作目录中的更改以找出它损坏的位置。我想保留索引,以便可以将修复添加到它并最终签入。本质上,我希望工作目录与 HEAD 相同,但不修改索引。这实质上会将基于索引的反向补丁应用到工作目录。看起来这将与 a 相反git reset

你如何在 git 中做到这一点?

4

6 回答 6

6

您可以提交索引,重置工作目录,然后重置提交。

$ git commit -m "blah"
$ git reset --hard
$ git reset --soft HEAD^

编辑: 看来我误解了原来的问题。

要在不影响索引的情况下将工作树重置为 HEAD,请执行以下操作:

$ git checkout -- .
$ git diff --cached | git apply --reverse

(看起来@Brice 已经给出了这个答案。)

于 2014-06-16T21:26:10.250 回答
5

我在看一个做同样事情的简单命令,但没有。尽管您在问题中说明了这样做的正确方法:

这实质上会将基于索引的反向补丁应用到工作目录。

所以答案很简单:

git diff --no-color --staged | git apply --reverse

所以不需要提交任何东西,只需应用索引的反向即可。

请注意,如果工作目录中的某些更改没有暂存/在索引中,它们将不会以这种方式反转。

如果要恢复工作目录中的所有内容(即使是未编入索引的更改和新文件),除了索引本身,请在之前运行以下命令:

git stash save --include-untracked --keep-index

如果您不打算重复使用它,您可以在之后删除它:

git stash drop

如果您想恢复除未跟踪文件(不在索引中的新文件)之外的所有内容,
请先执行以下操作:

git checkout .

总结一下,这里有几个 bash 函数:

function git-unapply-index {
    git diff --no-color --staged | which git apply --reverse
}

function git-revert-workdir-keep-untracked {
    git checkout .
    git-unapply-index
}

function git-revert-workdir-all {
    git stash save --include-untracked --keep-index
    git stash drop
    git-unapply-index
}
于 2016-08-09T09:05:28.517 回答
2

可以为现有提交生成反向补丁,而不是为索引中的更改生成。

  1. 提交索引中的更改[可能在 diff 分支中]。
  2. 执行git revert -n <commit>

它将在您的工作目录中为您的提交生成反向补丁。

于 2012-10-31T07:25:05.463 回答
1

你试过git checkout <commit>吗?

的片段git help checkout

git checkout [<branch>], git checkout -b|-B <new_branch> [<start point>], git checkout [--detach] [<commit>]
       This form switches branches by updating the index, working tree, and HEAD to reflect the specified branch or commit.

       If -b is given, a new branch is created as if git-branch(1) were called and then checked out; in this case you can use the --track or --no-track
       options, which will be passed to git branch. As a convenience, --track without -b implies branch creation; see the description of --track below.

       If -B is given, <new_branch> is created if it doesn’t exist; otherwise, it is reset. This is the transactional equivalent of

           $ git branch -f <branch> [<start point>]
           $ git checkout <branch>

       that is to say, the branch is not reset/created unless "git checkout" is successful.
于 2012-10-30T20:18:57.807 回答
1

也许你正在寻找git stashgit stash您可以使工作目录看起来像 HEAD,并且当您处于该状态时,您可以做任何其他事情。完成后,您可以git stash pop取回所有更改。您必须确保不更改隐藏的文件,否则您将需要解决合并冲突。

于 2012-10-30T20:24:32.443 回答
0

这正是您需要的:

git commit -m "Say thanks to John McClane"
git reset --hard HEAD^
git reset HEAD@{1} -- .

我假设您在执行此操作之前已经暂存了所有必要的文件。否则将-a密钥添加到第一个命令或在它之前调用git-add

请注意,--最后一个命令是可选的,它仅用于说明目的,以将其与其他形式的git-reset区分开来。

于 2018-11-27T01:19:49.270 回答