【问题标题】:Commit files without Staging提交文件而不暂存
【发布时间】:2013-03-01 15:46:38
【问题描述】:

我是 Git 新手,我正在使用 Git 扩展。我想问一下,当我提交目录时,这些文件是自动进行暂存还是在不暂存的情况下提交? 我可以在不暂存的情况下提交文件吗??

【问题讨论】:

  • 为什么要这样做? git add -u 将在一个命令中为您准备所有内容。
  • 在git中,不能提交目录,只能提交文件。
  • 您可以使用@David_Tryon 的回答轻松地为某些事情起别名来做您想做的事情。
  • 是的,类似于git config --global alias.yabadabadoo !git add -u && git commit -a

标签: git


【解决方案1】:

是的,您可以在提交中使用 am 进行暂存和提交:

git commit -am "my commit message"

不过,我还是倾向于使用git add -u,因为上述命令不会暂存未跟踪的文件。

【讨论】:

  • 那只会做被跟踪的文件...?
  • 我未跟踪的文件不会被选择跟踪。不要(错误)使用 git 作为 thrash 容器。
【解决方案2】:

这里值得一提的是,所有这些方法都使用索引,也就是暂存区,也就是缓存。

当 Git 进行新的提交时,它会使用“索引”中的任何内容。正如短语索引所暗示的,有一个单一的、特殊的、可区分的东西:索引,而不是一个索引。但实际上,Git 可以使用一些 other 索引。我们需要知道什么是“the”索引,以及作为 the 索引相对于其他索引意味着什么。

简而言之,索引是 Git 用来构建下一次提交的东西。我们从 this 提交中的内容开始,即当前或HEAD 提交。你运行git checkout mastergit checkout branch 或其他什么,Git 用一堆文件填满你的工作树。它将相同的文件放入(单个、特殊、杰出)索引,也称为暂存区。这意味着索引/暂存区开始时充满了许多文件:大多数情况下,工作树中的相同文件,您在其中进行工作。例外情况是某些工作树文件可能未跟踪

未跟踪文件是不在索引中的文件。就这么简单:索引中not 的任何文件都不会被跟踪;跟踪索引中的任何文件。索引中的那些开始与您git checkout-ed 的那些相同,git checkout 放入您的工作树中。

然后,您对一堆文件进行大量更改。但是,如果您现在运行git commit,则索引/暂存区域仍然具有原始git checkout 版本,而不是修改后的工作树版本。所以你必须 git add 将更改的文件复制到索引中。

这有点麻烦,所以 Git 有 git add -ugit commit -a。但是这两个都只是查看索引中的内容,然后将它们的新工作树版本复制到索引中。所以git commit -a -m "commit message" 不会添加工作树中但不在在索引中的文件——即当前未跟踪的文件。这与git add -u 相同:只有跟踪的 文件得到更新。

这里有点复杂

除此之外,git commit 可以将路径名作为参数:

git commit -m "some message" file1 file2

例如。但这意味着--only 标志,即 提交file1file2 中的更改。你也可以运行:

git commit -m "some message" --include file1 file2

这会覆盖--only

这一切的运作方式是 Git 可以使用 不同的 索引,而不是标准索引。当使用--only 时,Git 所做的是从HEAD 提交构建一个新的临时索引。然后,Git 将工作树中的指定文件复制到这个临时索引中,替换旧版本或添加新文件。然后 Git 从这个临时索引进行提交:新提交与 HEAD 提交具有所有相同的文件,除了由于 --only file1 file2 而添加的任何文件。

当您使用--include 时,Git 通过复制当前索引而不是再次提取HEAD 来创建其临时索引。所以现在无论你有什么git add-ed 都在临时索引中。然后 Git 添加指定的文件,并进行新的提交。

在所有情况下,在 Git 进行新的提交之后,它也必须修复 real 索引,因为现在您已经提交了最新的 file1file2(可能还有其他更新)如果你使用--include)。如果你使用--include,临时索引就变成了真正的索引。

如果你使用--only,这是最复杂的情​​况。在这里,Git 也将添加的文件复制到实际索引中,但除此之外,单独保留实际索引。这样,您之前上演的任何内容仍然是上演的。新提交中包含 HEAD 提交中的任何内容(通过临时索引),但指定的文件(被 git add 编辑到临时索引中)除外。而且,您刚才特别提交的任何内容现在也将 git add-ed 到 real 索引中,就像您在这些文件上运行 git add 一样。

【讨论】:

  • 哇,非常全面。谢谢!
  • 这是一个绝妙的解释。有趣的是,如果能以某种方式看到临时索引来验证工作的细微差别,那就太好了。
  • @theOne:临时索引仅在一个git commit 命令的持续时间内存在。您可以通过某些方式看到它:例如,您的预提交挂钩运行时设置了环境变量 GIT_INDEX_FILE 以显示临时文件的名称(默认设置已取消设置或设置到标准索引)。不幸的是,没有完美而简单的方法来测试,因为git worktree add 添加了一个工作树,其标准索引不是.git/index,而是.git/worktrees/<id>/index 用于某些ID,并且没有承诺这总有一天可能不会改变。
  • 同时,如果您使用运行编辑器的git commit 命令,并使用第二个窗口或类似的窗口在.git 目录中四处寻找,而该编辑器正在等待您(人类)要编辑提交消息,您可以找到临时索引。在git commit --only 的情况下,实际上有三个 索引文件处于活动状态; git commit --include 有两个。但同样,这些都是实施细节,没有做出真正的承诺。这有点不幸,因为它限制了您可以在预提交挂钩中执行的操作。
猜你喜欢
  • 2019-05-06
  • 2011-02-27
  • 2019-01-17
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 2020-07-18
  • 2020-11-04
  • 2015-01-09
相关资源
最近更新 更多