所有 Git 重置模式之间到底有什么区别?

What exactly is the difference between all the Git Reset modes?

我正在尝试为 Git-Savvy Sublime 扩展添加 Git 重置模式的简洁摘要。好难!

我有这个:

mixed (default): update index 
soft: move branch pointer only
hard: update index & working dir, discard local changes
merge: update index & working dir, keep local changes
keep: update index & working dir, abort if local changes

(希望这暗示分支指针在所有模式下移动。)

关于 reset 模式的文档非常模糊,并且使用短语 "updates the index"、"touches the index file"、"resets the index" 和 "resets index entries"知道它们是否同义。

--hard--merge--keep 之间还有其他细微差别吗?

首先,git reset 重置 HEAD。
HEAD 并不总是 "branch pointer":它是 current commit.

其次,git reset 可以在提交级别或文件级别重置(您可以重置文件)。

但无论如何,我会用"moves HEAD".

这两个词

您会在 git reset Demystified 中找到更准确的 table:

                        head    index   work dir    wd safe
Commit Level     
reset --soft [commit]   REF     NO      NO          YES
reset [commit]          REF     YES     NO          YES
reset --hard [commit]   REF     YES     YES         NO
checkout [commit]       HEAD    YES     YES         YES

File Level   
reset (commit) [file]   NO      YES     NO          YES
checkout (commit) [file]NO      YES     YES         NO

另请参阅:

  • "" 来理解为什么 git 重置默认为 HEAD(而 git checkout -- path 不是)。
  • "What's the difference between “git reset” and “git checkout”?"

好的,因为我找不到对不同模式的完整并排分析,我将使用希望用户更容易理解的语言来做一个 table。我还包括 git checkout.

为清楚起见,"Effect on..."

  • "HEAD":运算后HEAD指向什么
  • "Branch pointer":如果我们当前在分支B的顶端,那么B之后指向什么
  • "Empty index":在没有分阶段更改的情况下进行重置时您会看到什么。
  • "Tracked files": 如果切换到影响它们的提交,工作目录中的文件是否会被更改
  • "Untracked files":是否改变工作目录中未跟踪的文件。 (剧透:没有)

清理工作目录:

Effect on        | soft | mixed   | hard    | merge   | keep   |checkout
-----------------+---------------------------------------------|--------
HEAD             | Move | Move    | Move    | Move    | Move   | Move
Branch pointer   | Move | Move    | Move    | Move    | Move   |  -   
Empty index      | Add* |  -      |  -      |  -      |  -     |  -
Tracked files    |  -   |  -      | Change  | Change  | Change |Change
Untracked files  |  -   |  -      |  -      |  -      |  -     |  -

不受提交影响的工作目录更改(可能暂存)我们 resetting/checking 了。 (例如,我们更改 file.txt,但在当前提交和我们要去的地方之间没有任何变化)

- 表示 "keep in current state",Both 表示对同一文件的暂存和未暂存更改)

Staged changes   |  -   | Unstage | Discard | Discard | Unstage| -
Unstaged changes |  -   |  -      | Discard |     -   |  -     | -
Both             |  - * | Unstage | Discard | Abort   | Unstage| -

工作目录中的更改(可能已暂存)受到我们 resetting/checking 提交的影响。有时表示为询问运算是否为"working directory safe".

  Effect on      | soft | mixed   | hard    | merge   | keep   |checkout
-----------------+---------------------------------------------|--------
Staged changes   |  -   | Unstage | Discard | Discard | Abort  | Abort
Unstaged changes |  - * |    -    | Discard | Abort   | Abort  | Abort
Both             |  - * | Unstage | Discard | Abort   | Abort  | Abort

*关于--soft

的注释

git reset --soft X 将工作目录(包括当前 HEAD)和 X 之间的更改转换为分阶段更改。 Git 的手册页反直觉地将其描述为 "not touching the index file".

当有分阶段更改时,--soft 将它们与新的分阶段更改结合起来。

当存在未暂存的更改时,--soft 保留未暂存的更改,但也会暂存新的更改,如上。它是一致的,但可能会造成混淆。

总结

不同的 git reset 模式由这些问题定义:

  • 是保留(soft)、未暂存(mixedkeep)或丢弃(mergehard
  • 工作目录是否始终更新 (hard),仅在安全的情况下 (keepmerge) 或从不更新 (softmixed)
  • 是保留(softmixedmergekeep)或丢弃(hard
  • 的不相关的未暂存更改

我对每个的最后简明描述:

  • mixed(默认):unstage staged,keep unstaged,不接触工作(安全)
  • soft: 只需移动 HEAD,阶段差异(安全)
  • 困难:丢弃分阶段的,丢弃未分阶段的,更新工作(不安全)
  • 合并:放弃分阶段,保持非分阶段,更新工作(如果不安全则中止)
  • 保持:未暂存暂存,保持未暂存,更新工作(如果不安全则中止)