【问题标题】:Git: How to list all (staged) files attempting to be committedGit:如何列出所有尝试提交的(暂存的)文件
【发布时间】:2015-09-11 11:08:59
【问题描述】:

为 prepare-commit-msg git 钩子编写了一个 bash 脚本。它列出了所有存在的暂存文件,但我只想要尝试提交的暂存文件(即页面底部所需输入/输出的示例)。

我的脚本的工作是防止在尝试提交的文件不遵循特定的注释约定(即认为 java 文档)时发生提交。不仅如此,它还会编辑和自动格式化 cmets 以满足我的评论约定。需要注意这一点非常重要,因为我不能只获取提交的 SHA-1,因为该脚本需要在创建该密钥之前发生。

当我执行commit -a(即提交所有文件)时,这非常有效。但是,当我只想提交一些暂存文件时遇到了问题。

有没有一种方法可以只捕获试图提交的暂存文件,而不仅仅是每个存在的暂存文件?

例如,假设我的暂存文件如下:

file1.txt
file2.txt
file3.txt
file4.txt
file5.txt

当我执行git commit file1.txt file2.txt file3.txt 时,我想在我的脚本中捕捉file1.txt file2.txt file3.txt...但不是file4.txtfile5.txt

有没有办法做到这一点?

编辑:绝对不是重复的。 “重复”问题的解决方案绝对不是我想要的。

【问题讨论】:

  • 啊,我认为您的 git 词汇有误:文件状态可以是未跟踪、已忽略、已跟踪、暂存和最新中的一种或多种。跟踪文件只是存储库中的文件,暂存文件被暂存到所谓的index(参见 gitglossary(7))。当您对文件进行提交时,您会同时执行两项操作:添加和提交。 git commit -a 也是如此,仅适用于 git 找到且未被忽略的所有文件。
  • 您的第二句话是:它列出了所有跟踪的文件,但我只想要暂存的文件。这就是我的命令所做的,使用 grep。
  • @ikrabbe 当我按照您的示例执行git reset E,然后执行git status 时,它会在未跟踪的文件下列出E,然后告诉我“使用”git add ...”以包括将要提交的内容)。我是否严重误解了某些内容或在翻译中丢失了某些内容? :(
  • @ikrabbe,那么如果我在项目中的文件 1-5 上运行“git add”会怎样。然后我决定只做git commit file1.txt file2.txt file3.txt。使用下面列出的命令,我会只看到列出的文件 1-3,还是会看到文件 4 和 5,因为我在它们上使用了 git add,但不一定将它们作为参数传递给 git commit?我回家后会测试。

标签: linux git bash shell unix


【解决方案1】:

Git提交操作、状态及控制

Git 引入了自己的术语。其中一些词被错误地使用了,我将描述被误解的概念和导致错误表述的有问题的命令。

幸运的是 git 有一个非常强大的定义语言,其中每个术语都有确切的含义,其中一些可以在 git help gitglossary 中看到。要理解 git 使用的概念,git help git 页面值得阅读 5-50 次以及从那里链接的介绍性页面。

如果您安装了没有文档的 git 版本,请打您的系统管理员。我认为,大多数积极阅读问题、答案和文章的人都有自己的管理员,所以要打自己一巴掌,但不要太用力;)当然可以在网上找到文档,但它们是 to-的一个组成部分使用 git 安装。

幸运的是 git 被启动,它的核心完全由我们这个时代最优秀的人之一编写,或者至少是由一个使用最严格的逻辑概念而不是使用杀手级工具来编写和控制他的软件开发的人编写的:Linus托瓦尔兹。

当我们谈论 git 和 git 存储库中的操作时,这使得使用具有定义含义的相同术语成为可能。不过我不会深入探讨,因为其中一些概念是根据计算机科学中相当先进的理论术语开发的。

git 仓库

有两种主要类型的 git 存储库,称为 barenon-bare,或者我有时会说 checked-out (git help init)。在本文中,我只讨论非裸存储库,其中存储库的跟踪文件位于 工作目录

来自 gitglossary(7):
 working tree
      The tree of actual checked out files. The working tree normally 
      contains the contents of the HEAD commit’s tree, plus any local
      changes that you have made but not yet committed.

新手注意:gitglossary(7) 表示第 7 节中名为“gitglossary”的手册页。使用man 可以使用man -s7 gitglossary 访问此页面。使用git help gitglossary 将显示完全相同的内容,使用git help --web gitglossary,如果您的系统配置为远程调用一个html 页面到您的浏览器会话中,您会在浏览器中看到一个格式良好的文档。对于没有man 的Windows,您将始终被引导至浏览器。对于 add 等 git 命令,手册页为 man 1 git-addgit-add(1)

跟踪文件

我们在这里看到,术语 tracked 意味着 git 存储库知道并控制该文件。词汇表不是来自gitglossary(7),而是来自git-add(1),选项

  -u, --update
        Update the index just where it already has an entry matching 
        <pathspec>. This removes as well as modifies index entries to 
        match the working tree, but adds no new files.

      If no <pathspec> is given when -u option is used, all tracked 
        files in the entire working tree are updated (old versions of 
        Git used to limit the update to the current directory and
        its subdirectories).

命令git add --update是理解git在工作树中处理的最重要的操作之一。

这里显示了问题

使用git commit file1.txt file2.txt file4.txt,但让我们先定义更多术语。

暂存文件或索引

暂存文件集构建index(请参阅 gitglossary(7) 了解index,但忽略几个合并级别或未合并索引)。为了我们的目的

The index is a stored version of your working tree.

即准备作为一个commit 提交的工作树的存储版本(同样是 gitgloassary(7)

commit `作为名词:Git 历史中的一个点;

...“修订”或“版本”是其他版本控制系统的同义词。作为 Git 用户,我们说“提交”。

...待续(26.Friday)...

【讨论】:

  • 哇,你真棒。太感谢了。我期待着周五你的帖子更新。
【解决方案2】:
$ git status -s -uno
M  E
A  R

文件E被修改,文件R被暂存(添加)。

未暂存的文件在第二列中有操作标记(git reset E 之后,用于取消暂存文件 E):

$ git status -s -uno
 M E
A  R

例如,可以使用grep -v '^ ' 删除这些。

这是我的测试目录中的完整证明:

跟踪文件

 ~/test/ed $ git ls-tree HEAD
100644 blob 96bf192a9be8d1cecc314f66bb1ef5961564e983    E
100644 blob 11470e37f3d22a2548ce5c85040a44c9581d7727    I
100644 blob 8f2f9e95d9b00595d1588ccef91495c06295f5fa    O

文件系统文件(全部,如git commit -a

 ~/test/ed $ ls -l .
total 16
-rw-r--r-- 1 ingo ingo 140 25. Jun 05:48 E
-rw-r--r-- 1 ingo ingo 143 25. Jun 05:39 I
-rw-r--r-- 1 ingo ingo 106 25. Jun 05:29 O
-rw-r--r-- 1 ingo ingo 157 25. Jun 05:28 R

工作目录的状态:针对 HEAD 和暂存文件的更改

 ~/test/ed $ git status -s -uno
 M E
A  R

没有修改过的文件的输出在索引中还没有或不再(git reset)(又名。未暂存或未暂存)

 ~/test/ed $ git status -s -uno|grep -v '^ '
A  R

仅暂存文件名,没有操作标志

 ~/test/ed $ git status -s -uno|grep -v '^ '|awk '{print $2}'
R

【讨论】:

  • 看起来只是取消暂存文件(即使文件不被跟踪)。我正在寻找的命令仅适用于所有暂存文件的集合。然后用户将只提交其中一些暂存文件。我希望所有这些文件都尝试提交,但不是暂存文件没有尝试提交(请参见相关示例)。
  • @MrPickles 不! unstaged 和 untracked 之间是有区别的。未跟踪的文件不是 git 对象数据库的一部分。这就是我使用-uno 删除未跟踪文件的原因。暂存文件是 add/rm 为提交引入的文件。尚未为提交添加未暂存的已修改文件。如果我晚上或明天有空,我可以用一些确切的证据来扩展这个例子。但也许您想在测试存储库中试验这些输出并编辑答案。那会更好。
  • @ikrabbe 在可用时使用长选项来在答案中显示命令。它更易读,更容易记住,对不熟悉命令的人也更友好。
猜你喜欢
  • 1970-01-01
  • 2019-05-06
  • 2022-06-29
  • 2023-02-03
  • 1970-01-01
  • 2020-07-18
  • 2020-11-14
  • 2015-01-09
  • 1970-01-01
相关资源
最近更新 更多