我可以在已经暂存的git commit命令中指定多个文件吗?

时间:2017-06-27 22:56:52

标签: git

我有很多文件已经添加到索引中,但我想只提交其中的一些文件,因为审阅工具适用于提交。如果我只是做一个git提交,我想我会得到所有的文件。我想我可以这样做:git commit file1 file2 file3如果这是真的,我希望能够在文件中存储很长的文件列表,并将其指定为commit命令的输入。或者,我希望能够使用单个提交ID多次提交。我不想取消暂存某些文件,因为索引中有数百个文件,其中只有一些是重要的。

有没有一种安全的方法来强迫这种情况发生?完成后,如果可能的话,我会做一个提交以获取剩余文件。

编辑:底线,是的,你可以指定一些分阶段文件的子集,一个部分提交。但是在合并的情况下,导致许多文件发生变化并被上演,而我只想提交一些文件进行审核(其余的以后),你不能这样做;合并期间Git不允许部分提交。如果我错了,我相信有人会告诉我。

编辑:我尝试了“xargs”(由Edmundo建议)解决方案并得到错误:致命:在合并期间无法进行部分提交。

3 个答案:

答案 0 :(得分:2)

如果你有一个文件列表,你可以使用xargs将它们作为git commit的参数传递:cat file-of-files.txt | xargs git commit -m "Here's a few files to be committed"

答案 1 :(得分:2)

  

我想我可以这样做:git commit file1 file2 file3

是的,但你必须明白git会忽略分阶段的帅哥并完全提交这些文件。如果您使用git add -p暂存部分文件,这一点很重要。

  

或者,我希望能够使用一个提交ID多次提交。

不可能。每次修改提交时,其SHA-1 id都会更改。但是如果你使用gerrit进行审核它并不重要:gerrit会在第一次提交时附加自己的id来提交消息,将修改后的提交链接到同一个审核;在修改提交时不要删除此ID。

答案 2 :(得分:0)

由于phdEdmundo都回答了,是的,你可以这样做,但你需要知道Git实际上是如何进行提交的。

Git的正常标准设置是每个文件的三个副本与当前提交相关联:

HEAD     index    work-tree
-----    -----    ---------
file1    file1    file1
file2    file2    file2
  :        :        :
fileN    fileN    fileN

提交中的副本(HEAD)是只读的:它永远不会被更改。索引中的副本是可读/写的,但以其他特殊的Git格式存储。工作树中的副本是可读/写的,并以计算机用于文件的日常格式存储。

当您运行git add时,Git会将文件的工作树版本复制到索引中。假设您稍微改变了file2

HEAD     index    work-tree
-----    -----    ---------
file1    file1    file1
file2    file2    file2*
  :        :        :
fileN    fileN    fileN

这里的星号表示file2的内容不同。

git add file2从工作树中复制file2到索引中:

HEAD     index    work-tree
-----    -----    ---------
file1    file1    file1
file2    file2*   file2*
  :        :        :
fileN    fileN    fileN

(旁白:请注意,将git reset file2file2运行HEAD到索引中,从索引中删除更改,同时将其保留在工作树中。)

当你运行一个普通的git commit时,Git会立即打包索引中的任何内容并使用这些文件进行新的提交。因此,如果您已修改file2,则将新文件复制到索引中,然后运行git commit,您将在新提交中获得修改后的file2。未经修改的file1file3,...,fileN也会进入新提交。

当你跑步时,例如,git commit file1 file2,Git会做一些特别的事情。

使用文件参数提交会产生临时额外索引

让我们对文件file3进行更改,但运行git add

HEAD     index    work-tree
-----    -----    ---------
file1    file1    file1
file2    file2*   file2*
file3    file3    file3*
  :        :        :
fileN    fileN    fileN

例如,如果您现在运行git commit file3,Git首先将某些内容复制到临时索引中。

Git可以在这里明智地复制一些内容,以获得临时索引的起点。它实际使用的内容取决于标志参数:

  • git commit --include file3:Git将现有索引复制到临时索引。这会让您file1file2*file3等等。请注意,我们在此处获取 new file2,而不是旧版本。

  • git commit --only file3:Git将 HEAD提交复制到临时索引。这会让您file1file2file3等等。请注意,我们在此处获取(HEAD版本)file2

接下来,Git添加命令行中列出的文件。这会将临时索引的file3替换为file3*

现在Git使用临时索引进行提交。

最后,Git 将一些内容从临时索引复制回常规(普通)索引。具体来说,它会复制您在命令行中列出的所有文件,因此file3*会进入常规索引。

部分暂存的文件

phd所指的是使用git add -pgit reset -p或能力:

$ make-change-to file2
$ git add file2
$ make-different-change-to file2

现在你有一些我们可能描述的东西:

HEAD     index    work-tree
-----    -----    ---------
file1    file1    file1
file2    file2*   file2†
  :        :        :
fileN    fileN    fileN

也就是说,现在有三个不同版本的file2同时处于活动状态:原始未修改HEAD版本,第一个修改版本存储在索引中,以及存储在工作树中的第二个修改版本。

如果您git commit file2,Git将创建一个新的临时索引,将工作树file2†版本复制到该临时索引中,从临时索引提交,然后 复制常规索引file2†文件 上的临时索引file2*文件。结果就是你完全失去了中间版本。