设置和配置
获取和创建项目
基本快照
分支和合并
共享和更新项目
检查和比较
打补丁
调试
外部系统
服务器管理
- 2.39.4 → 2.49.0 没有更改
-
2.39.3
2023-04-17
- 2.36.1 → 2.39.2 没有更改
-
2.36.0
2022-04-18
- 2.34.1 → 2.35.8 没有更改
-
2.34.0
2021-11-15
- 2.27.1 → 2.33.8 没有更改
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 没有更改
-
2.25.0
2020-01-13
- 2.23.1 → 2.24.4 没有更改
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 没有更改
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 没有更改
-
2.21.0
2019-02-24
- 2.20.1 → 2.20.5 没有更改
-
2.20.0
2018-12-09
- 2.15.4 → 2.19.6 没有更改
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
-
2.12.5
2017-09-22
- 2.1.4 → 2.11.4 没有更改
-
2.0.5
2014-12-17
概要
git reset [-q] [<tree-ish>] [--] <pathspec>… git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>] git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>…] git reset [--soft | --mixed [-N] | --hard | --merge | --keep] [-q] [<commit>]
描述
在前三种形式中,将条目从 <tree-ish>
复制到索引。在最后一种形式中,将当前分支头 (HEAD
) 设置为 <commit>
,可以选择修改索引和工作树以匹配。在所有形式中,<tree-ish>
/<commit>
默认为 HEAD
。
- git reset [-q] [<tree-ish>] [--] <pathspec>…
- git reset [-q] [--pathspec-from-file=<file> [--pathspec-file-nul]] [<tree-ish>]
-
这些形式将所有与
<pathspec>
匹配的路径的索引条目重置为其在<tree-ish>
的状态。(它不影响工作树或当前分支。)这意味着
git reset <pathspec>
与git add <pathspec>
相反。此命令等效于git restore [--source=<tree-ish>] --staged <pathspec>...
。运行
git reset <pathspec>
以更新索引条目后,您可以使用 git-restore[1] 将内容从索引检出到工作树。或者,使用 git-restore[1] 并使用--source
指定提交,您可以一次性地将路径的内容从提交复制到索引和工作树。 - git reset (--patch | -p) [<tree-ish>] [--] [<pathspec>…]
-
交互式地选择索引和
<tree-ish>
(默认为HEAD
)之间的差异中的块。选择的块以相反的顺序应用于索引。这意味着
git reset -p
与git add -p
相反,即,您可以使用它来选择性地重置块。请参阅 git-add[1] 的“交互模式”部分,了解如何操作--patch
模式。 - git reset [<mode>] [<commit>]
-
这种形式将当前分支头重置为
<commit>
,并可能根据<mode>
更新索引(将其重置为<commit>
的树)和工作树。在操作之前,ORIG_HEAD
设置为当前分支的提示。如果省略<mode>
,则默认为--mixed
。<mode>
必须是以下之一- --soft
-
完全不触及索引文件或工作树(但像所有模式一样,将头重置为
<commit>
)。这将使所有已更改的文件都处于“要提交的更改”状态,正如git status
所说的那样。 - --mixed
-
重置索引但不重置工作树(即,保留已更改的文件,但不会标记为要提交),并报告尚未更新的内容。这是默认操作。
如果指定了
-N
,则删除的路径将标记为计划添加(请参阅 git-add[1])。 - --hard
-
重置索引和工作树。自
<commit>
以来对工作树中跟踪文件的任何更改都将被丢弃。写入任何跟踪文件的任何未跟踪的文件或目录都将被简单地删除。 - --merge
-
重置索引并更新工作树中
<commit>
和HEAD
之间不同的文件,但保留索引和工作树之间不同的文件(即,具有尚未添加的更改)。如果<commit>
和索引之间不同的文件具有未暂存的更改,则重置将被中止。换句话说,
--merge
执行类似于git read-tree -u -m <commit>
的操作,但会结转未合并的索引条目。 - --keep
-
重置索引条目并更新工作树中
<commit>
和HEAD
之间不同的文件。如果<commit>
和HEAD
之间不同的文件具有本地更改,则重置将被中止。 - --[no-]recurse-submodules
-
更新工作树时,使用 --recurse-submodules 也会根据超级项目中记录的提交递归地重置所有活动子模块的工作树,并将子模块的 HEAD 设置为在该提交处分离。
有关三个命令之间的差异,请参阅 git[1] 中的“重置、还原和恢复”。
选项
- -q
- --quiet
-
保持安静,仅报告错误。
- --refresh
- --no-refresh
-
在混合重置后刷新索引。默认启用。
- --pathspec-from-file=<file>
-
Pathspec 在
<file>
中传递,而不是命令行参数。 如果<file>
恰好是-
,则使用标准输入。 Pathspec 元素由 LF 或 CR/LF 分隔。 Pathspec 元素可以按照配置变量core.quotePath
的说明进行引用 (参见 git-config[1])。 另请参见--pathspec-file-nul
和全局--literal-pathspecs
。 - --pathspec-file-nul
-
仅对
--pathspec-from-file
有意义。 Pathspec 元素用 NUL 字符分隔,所有其他字符都按字面意义理解(包括换行符和引号)。 - --
-
不要将更多参数解释为选项。
- <pathspec>…
-
限制受操作影响的路径。
有关更多详细信息,请参阅 gitglossary[7] 中的 pathspec 条目。
示例
- 撤消添加
-
$ edit (1) $ git add frotz.c filfre.c $ mailx (2) $ git reset (3) $ git pull git://info.example.com/ nitfol (4)
-
您很高兴地在处理某些内容,并发现这些文件中的更改井然有序。 当您运行
git diff
时,您不想看到它们,因为您计划处理其他文件,并且这些文件的更改会分散注意力。 -
有人要求您拉取,并且这些更改听起来值得合并。
-
但是,您已经弄脏了索引(即,您的索引与
HEAD
提交不匹配)。 但是您知道您要进行的拉取不会影响frotz.c
或filfre.c
,因此您还原了这两个文件的索引更改。 您在工作树中的更改仍然存在。 -
然后,您可以拉取和合并,将
frotz.c
和filfre.c
更改保留在工作树中。
-
- 撤消提交并重做
-
$ git commit ... $ git reset --soft HEAD^ (1) $ edit (2) $ git commit -a -c ORIG_HEAD (3)
-
当您记起刚刚提交的内容不完整,或者您拼错了提交消息,或者两者兼而有之时,通常会这样做。 将工作树保留为“重置”之前的状态。
-
更正工作树文件。
-
"reset" 命令会将旧的 head 复制到
.git/ORIG_HEAD
;通过从其日志消息开始,重新进行提交。如果不需要进一步编辑消息,可以使用-C
选项。另请参阅 git-commit[1] 的
--amend
选项。
-
- 撤销提交,使其成为主题分支
-
$ git branch topic/wip (1) $ git reset --hard HEAD~3 (2) $ git switch topic/wip (3)
-
您已经进行了一些提交,但意识到它们过早地进入了
master
分支。 您希望在主题分支中继续完善它们,因此从当前的HEAD
创建topic/wip
分支。 -
回退 master 分支以摆脱这三个提交。
-
切换到
topic/wip
分支并继续工作。
-
- 永久撤销提交
-
$ git commit ... $ git reset --hard HEAD~3 (1)
-
最后三个提交(
HEAD
、HEAD^
和HEAD~2
)很糟糕,您不想再看到它们。 如果您已经将这些提交提供给其他人,请不要这样做。(有关这样做的影响,请参阅 git-rebase[1] 中的 “从上游变基恢复” 部分。)
-
- 撤销合并或拉取
-
$ git pull (1) Auto-merging nitfol CONFLICT (content): Merge conflict in nitfol Automatic merge failed; fix conflicts and then commit the result. $ git reset --hard (2) $ git pull . topic/branch (3) Updating from 41223... to 13134... Fast-forward $ git reset --hard ORIG_HEAD (4)
-
尝试从上游更新导致了很多冲突;您现在不准备花费大量时间进行合并,因此您决定稍后再做。
-
"pull" 没有创建合并提交,因此
git reset --hard
(它是git reset --hard HEAD
的同义词) 清理了索引文件和工作树中的混乱。 -
将一个主题分支合并到当前分支中,导致快速前进。
-
但是您认为该主题分支尚未准备好公开发布。"pull" 或 "merge" 总是将当前分支的原始尖端保留在
ORIG_HEAD
中,因此硬重置到它会将您的索引文件和工作树恢复到该状态,并将分支的尖端重置为该提交。
-
- 在脏工作树中撤销合并或拉取
-
$ git pull (1) Auto-merging nitfol Merge made by recursive. nitfol | 20 +++++---- ... $ git reset --merge ORIG_HEAD (2)
-
即使您的工作树中可能存在本地修改,当您知道另一个分支中的更改与它们不重叠时,也可以安全地使用
git pull
。 -
在检查了合并的结果后,您可能会发现另一个分支中的更改不能令人满意。 运行
git reset --hard ORIG_HEAD
将使您回到原来的位置,但会丢弃您不想丢失的本地更改。git reset --merge
会保留您的本地更改。
-
- 中断的工作流程
-
假设您在进行一项重大更改时,被一个紧急修复请求打断。您工作树中的文件还不能提交,但您需要切换到另一个分支进行快速错误修复。
$ git switch feature ;# you were working in "feature" branch and $ work work work ;# got interrupted $ git commit -a -m "snapshot WIP" (1) $ git switch master $ fix fix fix $ git commit ;# commit with real log $ git switch feature $ git reset --soft HEAD^ ;# go back to WIP state (2) $ git reset (3)
-
此提交将被删除,因此抛弃式的日志消息是可以接受的。
-
这会从提交历史记录中删除 *WIP* 提交,并将您的工作树设置为您创建快照之前的状态。
-
此时,索引文件仍然包含您作为 *snapshot WIP* 提交的所有 WIP 更改。 这会更新索引,以将您的 WIP 文件显示为未提交。
另请参阅 git-stash[1]。
-
- 重置索引中的单个文件
-
假设您已将文件添加到索引中,但后来决定不想将其添加到您的提交中。 您可以使用 git reset 从索引中删除该文件,同时保留您的更改。
$ git reset -- frotz.c (1) $ git commit -m "Commit files in index" (2) $ git add frotz.c (3)
-
这会从索引中删除该文件,同时将其保留在工作目录中。
-
这将提交索引中的所有其他更改。
-
再次将文件添加到索引。
-
- 保留工作树中的更改,同时丢弃一些先前的提交
-
假设您正在处理某些内容并提交了它,然后您继续工作了一点,但现在您认为工作树中的内容应该位于与您之前提交的内容无关的另一个分支中。您可以启动一个新分支并重置它,同时保留工作树中的更改。
$ git tag start $ git switch -c branch1 $ edit $ git commit ... (1) $ edit $ git switch -c branch2 (2) $ git reset --keep start (3)
-
这会将您的第一次编辑提交到
branch1
中。 -
在理想的世界中,您本可以在创建和切换到
branch2
时意识到较早的提交不属于新主题(即git switch -c branch2 start
),但没有人是完美的。 -
但是您可以使用
reset --keep
在切换到branch2
后删除不需要的提交。
-
- 将一个提交拆分成一系列提交
-
假设您创建了很多逻辑上独立的更改并将它们一起提交。 然后,稍后您决定最好将每个逻辑块与其自己的提交关联起来。 您可以使用 git reset 来回退历史记录,而无需更改本地文件的内容,然后依次使用
git add -p
来交互式地选择要包含到每个提交中的块,并使用git commit -c
来预填充提交消息。$ git reset -N HEAD^ (1) $ git add -p (2) $ git diff --cached (3) $ git commit -c HEAD@{1} (4) ... (5) $ git add ... (6) $ git diff --cached (7) $ git commit ... (8)
-
首先,将历史记录向后重置一个提交,以便我们删除原始提交,但保留包含所有更改的工作树。 -N 确保使用
HEAD
添加的任何新文件仍然被标记,以便git add -p
可以找到它们。 -
接下来,我们交互式地选择差异块以使用
git add -p
功能添加。 这将按顺序询问您每个差异块,您可以使用简单的命令,例如 “yes, include this”、“No don’t include this” 甚至是非常强大的 “edit” 功能。 -
对要包含的块感到满意后,您应该使用
git diff --cached
验证已为第一次提交准备了什么。 这显示了所有已移入索引并即将提交的更改。 -
接下来,提交存储在索引中的更改。
-c
选项指定从您在第一次提交中开始使用的原始消息预填充提交消息。 这有助于避免重新输入它。HEAD@{1}
是一个特殊的表示法,用于表示在原始重置提交之前HEAD
所在的提交(1 个更改前)。 有关更多详细信息,请参阅 git-reflog[1]。 您也可以使用任何其他有效的提交引用。 -
您可以重复步骤 2-4 多次,以将原始代码分解为任意数量的提交。
-
现在您已经将许多更改分成了它们自己的提交,并且可能不再使用
git add
的补丁模式来选择所有剩余的未提交更改。 -
再次,检查以验证您是否包含了想要的内容。 您可能还希望验证 git diff 是否没有显示任何剩余的更改将在以后提交。
-
最后创建最终提交。
-
讨论
下表显示了运行以下命令时会发生的情况
git reset --option target
将 HEAD
重置为另一个提交 (target
),具体取决于文件的状态,使用不同的重置选项。
在这些表中,A
、B
、C
和 D
是文件的不同状态。 例如,第一个表的首行表示,如果一个文件在工作树中处于状态 A
,在索引中处于状态 B
,在 HEAD
中处于状态 C
,在目标中处于状态 D
,那么 git reset --soft target
将使工作树中的文件处于状态 A
,索引中处于状态 B
。 它将 HEAD
(即当前分支的尖端,如果您位于某个分支上)重置(即移动)到 target
(该文件的状态为 D
)。
working index HEAD target working index HEAD ---------------------------------------------------- A B C D --soft A B D --mixed A D D --hard D D D --merge (disallowed) --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- A B C C --soft A B C --mixed A C C --hard C C C --merge (disallowed) --keep A C C
working index HEAD target working index HEAD ---------------------------------------------------- B B C D --soft B B D --mixed B D D --hard D D D --merge D D D --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- B B C C --soft B B C --mixed B C C --hard C C C --merge C C C --keep B C C
working index HEAD target working index HEAD ---------------------------------------------------- B C C D --soft B C D --mixed B D D --hard D D D --merge (disallowed) --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- B C C C --soft B C C --mixed B C C --hard C C C --merge B C C --keep B C C
reset --merge
旨在用于从冲突的合并中重置出来。 任何合并操作都保证,在合并开始之前,工作树文件中涉及合并的文件与索引相比没有本地更改,并且它将结果写入工作树。 因此,如果我们看到索引和目标之间以及索引和工作树之间存在一些差异,那么这意味着我们没有从合并操作在冲突失败后留下的状态重置出来。 这就是为什么在这种情况下我们不允许使用 --merge
选项的原因。
reset --keep
旨在用于删除当前分支中的一些最后提交,同时保留工作树中的更改。 如果我们想要删除的提交中的更改与我们想要保留的工作树中的更改之间可能存在冲突,则不允许重置。 这就是为什么当工作树和 HEAD
之间以及 HEAD
和目标之间都存在更改时,它是不允许的。 为了安全起见,当存在未合并的条目时,它也是不允许的。
下表显示了存在未合并条目时会发生的情况
working index HEAD target working index HEAD ---------------------------------------------------- X U A B --soft (disallowed) --mixed X B B --hard B B B --merge B B B --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- X U A A --soft (disallowed) --mixed X A A --hard A A A --merge A A A --keep (disallowed)
X
表示任何状态,U
表示未合并的索引。
GIT
git[1] 套件的一部分