【问题标题】:Can a file be both staged and unstaged in Git?文件可以在 Git 中暂存和未暂存吗?
【发布时间】:2014-07-19 07:21:56
【问题描述】:

在处理另一个文件时,我编辑了README.md,然后运行了git add README.md。在进行 git 提交时,我看到 README.md 位于“要提交的更改”和“未准备提交的更改”中。

这有意义吗?我可以在.git 的哪个位置查看此文件的权威状态?

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   README.md
#       modified:   utils/arrterm
#
# 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:   README.md

【问题讨论】:

  • 你可以这样想:你改变了 10 行。使用git add -p,您只需添加前 5 个更改。现在您的文件也已暂存而不是暂存。

标签: git version-control


【解决方案1】:

这意味着您所做的部分更改是为提交进行的,而部分则不是。

如果你运行,你可以检查暂存的内容

git diff --staged -- README.md

并通过运行检查未暂存的内容

git diff -- README.md

大多数版本控制系统通常只存储两个状态之间的更改。 git 的工作方式,当您对文件进行多项更改时,您必须添加/标记它们中的每一个以成为一组更改的一部分,即提交。当您使用git add 时,这是自动完成的。

但是,这不是您将所有个人更改(大块)添加到“索引”的唯一方法。例如,您可以对同一个文件进行多次更改并在不同的提交中提交它们,或者只向提交添加特定的更改。例如。要明确向“索引”添加一些更改而不是其他更改,您可以使用 git add -p 仅添加更改的一些“大块”(组)而不是整个更改列表本身。

这里发生的情况是,您对README.md 之前 staging (git add) 所做的更改将显示在staged 中,并且您在after staging @ 中所做的任何更改987654327@ 将显示为您在上面得到的未暂存状态。

【讨论】:

  • 重要的是要知道 git 暂存和提交内容行,而不是文件。这可能非常方便,例如提交文件中的一些更改,而将其他更改留待将来提交。此外,git gui 将更容易查看和更改文件的哪些部分已暂存。
  • @Jerry101:“内容行,而不是文件”——我会说“更改”。因为:删除文件不包含行。更改权限也是如此
  • @zerkms 是的,但是如果您更改文件的哪些部分已暂存/未暂存,它会在“大块”中执行此操作,这似乎是文本文件的一行或多行。如果我错了,请纠正我。
  • @Jerry101:没错。您选择差异,因此会发生变化。这就是我的确切观点。
  • staged 是一个选项,因此正确的语法是--staged。 (它是--cached 的同义词,顺便说一句,我通常看到--cached 使用得更多,但--staged 也可以。)README.md 不是一个选项,所以正确的语法是-- README.md
【解决方案2】:

我可以在 .git 的哪个位置查看此文件的权威状态?

使用git diff:

  • git diff -- yourFile 将为您提供尚未暂存的更改(尚未添加到索引中)
  • git diff --cached -- yourFile 将为您提供已添加到索引中的更改。

在“Changes, not files”查看更多信息:

大多数版本控制系统都使用文件。您将文件添加到源代码管理中,系统会从那时起跟踪更改。

Git 专注于对文件的更改,而不是文件本身
git add file 命令不会告诉 git 将文件添加到存储库,而是要记下文件的当前状态以便稍后提交。

另见“git add -p: The most powerful git feature you're not using yet


请注意,git status -v -v 很快(Git 2.3.4,2015 年第 2 季度)将向您显示两个差异(暂存和未暂存),可能会列出同一文件的不同差异。 p>

见“Show both staged & working tree in git diff?”。

【讨论】:

  • 谢谢,我了解更改的想法。我更想了解为什么 README.md 在状态中出现两次。
  • @MarkHarrison 因为你之前添加了一个更改,然后又做了一个新的
【解决方案3】:

回答“这有意义吗?”

只有当你明白 git 不存储差异它存储快照时,它才有意义。

在您描述的示例中,您的更改中有两个版本的 README.md。暂存版本是您当前满意的版本,如果您选择提交它,最终将成为文件的最新快照。未暂存版本是一个潜在的快照,如果您选择暂存它,它将替换当前暂存版本。

阅读以下链接中的“快照,而不是差异”部分,以进一步了解 git 的工作原理:

http://git-scm.com/book/en/Getting-Started-Git-Basics

还请查看以下链接以进一步解释您在问题中包含的场景(特别是“暂存修改文件”部分):

http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository

【讨论】:

    【解决方案4】:

    其实你看到的状态很容易重现:

    git init
    touch test
    git add test     #1
    echo 42 > test   #2
    git status       #3
    

    在#1 中,我们暂存空的测试文件。 #2 更改文件的内容。这些更改不会被暂存(因为您需要使用git add 明确暂存更改)。 #3 中git status 的输出告诉你这一点。

    要查看已暂存的更改,请运行 git diff --cached。要查看对工作副本文件的哪些更改尚未暂存,请运行 git diff

    在您的问题中,您声明您运行git commit。从您的git status 输出看来,好像没有创建提交,可能是因为您没有输入提交消息。检查git commit 的输出,git 可能告诉你尝试创建提交时出了什么问题!

    【讨论】:

      猜你喜欢
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-16
      • 2015-06-19
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      相关资源
      最近更新 更多