将所有文件都添加到提交中,除了一个单独的文件?

845

我有一堆文件在一个变更集中,但我想特别忽略一个修改过的文件。在 git status 之后看起来像这样:

# modified:   main/dontcheckmein.txt
# deleted:    main/plzcheckmein.c
# deleted:    main/plzcheckmein2.c
...

我能否在执行git add命令时忽略一个我不想处理的文本文件?类似这样:

git add -u -except main/dontcheckmein.txt

2
“-u”标志的目的是什么?它可以在没有“-u”的情况下工作吗? - Saad Abbasi
3
从 man git add: -u, --update “仅在索引中已有匹配项的位置更新。这将删除以及修改索引条目以匹配工作树,但不添加新文件。...”</pathspec> - Simeon
5
也许这个来自https://github.com/git-guides/git-add的表格更好地解释了-u命令: git add -u:只缓存新建和修改的文件,不包括已删除的文件。 - Simeon
3
如果您有未被追踪的文件,则使用“-u”选项确保这些文件不会被添加。而“git add --all”则会添加所有未被追踪的文件。 - Simeon
20个回答

4

添加所有文件

使用命令: git add .

获取文件路径并粘贴到下面

使用命令: git status

从提交中移除

使用命令: git reset -- file/to/path/file-to-ignore.txt


3

对于问题中的特定情况,最简单的方法是添加所有扩展名为.c的文件并排除其他所有文件:

git add *.c

git-scm(或/和man git add):

git add <pathspec>…​

要添加内容的文件。可以使用文件通配符(例如*.c)以添加所有匹配的文件。<...>

请注意,这意味着您也可以执行以下操作:

git add **/main/*

添加所有未被忽略的位于main文件夹中的文件。您甚至可以使用更复杂的模式:

git add **/s?c/*Service*

上面的命令将会添加所有在以 s(any char)c 命名的文件夹中,并且文件名中包含 Service 的文件。
显然,您不需要限制每个命令只有一个匹配模式。也就是说,您可以要求 git 添加所有扩展名为 .c.h 的文件:
git add *.c *.h

这个链接可能会给你一些更多的glob模式想法。
我发现当我需要做很多改变但仍希望我的提交保持原子性并反映逐步过程而不是一堆我正在进行的变化时,它特别有用。当然,在某些时候,设计复杂的模式的成本超过了使用简单方法添加文件甚至逐个添加文件的成本。然而,大多数情况下,我可以轻松地通过一个简单的模式找到我需要的文件,并排除其他所有文件。
顺便说一句,你可能需要引用你的glob模式才能使它们工作,但这对我来说从未发生过。

2

试试这个:

git checkout -- main/dontcheckmein.txt

1
这将撤销所有更改 main/dontcheckmein.txt。 - gsumk
这将撤销更改:git checkout与git checkout的区别。 - Dhanapal

1

我知道你的要求是关于编程的,虽然下面的方法不能一次完成你想要的结果,但最终可以达到你的目标。

在通过以下方式将所有文件添加到暂存区后:

git add -u

键入git status将建议您:
git restore --staged main/dontcheckmein.txt

1

您可以使用git的推荐功能

将所有文件更改添加并恢复不想推送的文件

git add .
git restore --staged <file_not_push>

0

我经常使用git add --patch,但希望有一些方法可以避免在同一文件中一遍又一遍地按下d键。因此,我编写了一对非常简单的git别名来完成这项工作:

[alias]
    HELPER-CHANGED-FILTERED = "!f() { git status --porcelain | cut -c4- | ( [[ \"$1\" ]] && egrep -v \"$1\" || cat ); }; f"
    ap                      = "!git add --patch -- $(git HELPER-CHANGED-FILTERED 'min.(js|css)$' || echo 'THIS_FILE_PROBABLY_DOESNT_EXIST' )"

在我的情况下,我只想始终忽略某些缩小的文件,但您可以使用类似于 $GIT_EXCLUDE_PATTERN 这样的环境变量来实现更常见的用例。

0
如果您想要每次忽略特定文件,有三种有效的解决方案不涉及.gitignore
  1. 将要忽略的文件添加到.git/info/exclude中。它的工作方式与您的.gitignore相同,只是配置是特定于您的机器

  2. 使用pre-commit git hook重置要使用的文件。例如:

    $ echo 'git reset -- src/main/resources/log4j.properties' >> .git/hooks/pre-commit
    $ chmod +x .git/hooks/pre-commit
    

    pre-commit钩子在提交之前运行。因此,您的文件可以在每次提交之前自动重置。

    $ git status
    On branch CHANGE-137-notifications-support ...
    
    Changes not staged for commit:
     modified:   Dockerfile
     modified:   src/main/resources/log4j.properties
    
    $ git add .
    
    $ git status
    On branch CHANGE-137-notifications-support ...
    
    Changes to be committed:
     modified:   Dockerfile
     modified:   src/main/resources/log4j.properties
    
    
    $ git commit -m "Trivial change"
    
    Unstaged changes after reset:
    M    src/main/resources/log4j.properties
    
    [CHANGE-137-notifications-support 97cfb3f] Trivial change
    1 file changed, 3 insertions(+)
    
  3. 第三种方法是更新特定文件的索引。

    $ git update-index --assume-unchanged src/main/resources/log4j.properties
    

0
根据《Pro Git》一书(作者:Scott Chacon, Ben Straub)的说法,有两种方法可以实现:

git reset

$ git reset HEAD main/dontcheckmein.txt

Git版本2.23.0引入了一个新的命令:git restore。它基本上是我们刚刚介绍的git reset的一个替代品。从Git版本2.23.0开始,Git将使用git restore来执行许多撤销操作。
$ git restore --staged main/dontcheckmein.txt

:warning: 重要的是要明白,git restore <file> 是一个危险的命令。你对该文件所做的任何本地更改都将消失 - Git只是用最后一个暂存或提交的版本替换了该文件。除非你绝对确定不想保存这些未保存的本地更改,否则永远不要使用这个命令。
:warning: 的确,git reset 可能是一个危险的命令,特别是如果你使用了 --hard 标志。然而,在上述描述的情况下,你的工作目录中的文件不会被触及,所以相对来说是安全的。

0

待提交的更改: (使用“git reset HEAD…”取消暂存)


-2
你可以尝试这个命令:git add * && git reset main/dontcheckmein.txt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接