将所有文件添加到提交中,但单个文件除外?


569

我在变更集中有很多文件,但是我想专门忽略一个修改过的文件。看起来像这样git status

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

有什么办法可以做,git add但是我可以忽略一个不想触摸的文本文件?就像是:

git add -u -except main/dontcheckmein.txt

Answers:


850
git add -u
git reset -- main/dontcheckmein.txt

28
如何排除整个文件夹?-main或main /或main / *?
艾伦·科罗马诺

8
@MariusKavansky您可以使用所有这些表格。如果使用main/*它,则必须--在其前面添加,以使git知道这是一条路径。其他两个变体在不包含两个破折号的情况下起作用。(在Windows 7上使用msysGit在命令提示符下进行了测试)
dennisschagt 2014年

2
如果您要排除某些包含大量文件或其他文件夹的文件夹,请执行以下操作:将它们暂时添加到gitignore中。git reset之后对那些文件夹执行a 仍然可以,但是git需要较长时间才能添加大文件夹。
Michael Trouw,2015年

2
所以,没有班轮吗?
BroVic

5
@本·杰克逊(Ben Jackson)会在每一行中发表评论,您不觉得吗?
ed1nh0

140

1)开始忽略对单个已版本化文件的更改

git update-index --assume-unchanged "main/dontcheckmein.txt"

并撤消 git update-index --no-assume-unchanged "main/dontcheckmein.txt"

github文档忽略文件

2)完全忽略特定的单个文件,以防止在存储库中创建该文件

首先,看一下这个stackoverflow帖子:Git全局忽略不起作用

在中.gitignore,将相对路径添加到文件中而不加前导./

因此,如果文件位于MyProject/MyFolder/myfile.txt,(.git也位于MyProject文件夹中),请添加MyFolder/myfile.txt到您的at .gitignore文件。

您可以通过确认与忽略相关的规则 git check-ignore "MyFolder/myfile.txt"

关于全局忽略

该链接涉及~/.gitignore_global,但文件与您的项目有关。因此,如果将排除模式MyFolder/myfile.txt放入中~/.gitignore_global,它会起作用,但意义不大...

另一方面,如果使用git config core.excludesfile .gitignorewhere .gitignorein来设置项目MyProject,则本地文件将覆盖~/.gitignore_global,这可能具有非常有用的规则 ...

所以,现在,我认为这是最好做一些脚本,以你的混音.gitignore~/.gitignore_global.gitignore

最后一个警告
如果您要忽略的文件已经在存储库中,则除非您执行以下操作git rm "MyFolder/myfile.txt",否则该方法将不起作用:,但是请先对其进行备份,因为它也会在本地删除!您可以稍后将其复制回...


5
您可以用来git rm --cached MyFolder/myyfile.txt从存储库中删除文件,但将其保留在本地。help.github.com上的说明
dennisschagt 2014年

87

对于文件

git add -u
git reset -- main/dontcheckmein.txt

对于文件夹

git add -u
git reset -- main/*

9
为什么-u是必需的?为什么不git add . && git reset -- main/*呢?

2
-u选项将在索引已经具有与<pathspec>匹配的条目的位置处更新索引。这会删除和修改索引条目以匹配工作树,但不会添加任何新文件。如果在使用-u选项时未提供<pathspec>,则将更新整个工作树中的所有跟踪文件(旧版本的Git用于将更新限制为当前目录及其子目录)。
Farhad Mammadli

6
谁能用非git专业人士能理解的语言解释为什么-u是必需的?
帕特里克

2
-u用于引用您要推送到的当前分支。您将不再需要键入git push origin master下一个推送,git push而git会知道它在master分支中。希望能帮助到你。
Pepeng Hapon

69

现在git支持exclude certain paths and filespathspec魔术:(exclude)及其简短形式:!。因此,您可以通过以下命令轻松实现它。

git add --all -- :!main/dontcheckmein.txt
git add -- . :!main/dontcheckmein.txt

实际上,您可以指定更多:

git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*

1
最好的答案,谢谢!至少对于我来说:我只需要排除文件类型。
安德烈·波利卡宁

15
太好了!请注意,在Linux上,您需要引用这些:!...子句以防止shell抱怨。因此,例如:git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'
Martin_W

有类似的东西:!/path/to/(file1|file2)吗?
seeker_of_bacon

这与zsh中的内容发生冲突,在macOS和最新的git上对我不起作用。
默林

1
有人可以指出正式记录的地方吗?
samurai_jane

20

尽管本杰克逊是正确的,但我想我也会补充一下如何使用该解决方案。下面是一个非常简单的脚本,我使用它(我称为gitadd)添加所有更改,除了我保留在文件中列出的少数几个.gittrackignore(非常类似于.gitignore的工作原理)。

#!/bin/bash
set -e

git add -A
git reset `cat .gittrackignore`

这就是我目前的.gittrackignore样子。

project.properties

我正在开发一个在部署时从命令行编译的Android项目。该项目依赖于SherlockActionBar,因此需要在project.properties中进行引用,但这会与编译混乱。因此,现在我只需键入gitadd所有更改并将其添加到git中,而不必每次都取消添加project.properties。


--直到您发表评论,我才知道。根据手册页,它是可选的,并且不会更改命令的结果(至少在这种情况下)。这个问题似乎支持 stackoverflow.com/questions/17800994/…。如果我错了,请纠正我,但这似乎意味着“对待--参数之后的任何东西,而不是选项/开关”
Anthony Naddeo 2013年

尼斯用--git checkout我在这个问题看。在我们交换之前,我也不知道双破折号是什么。我想知道git checkout分支和文件之间的歧义是否也会以这种或其他形式影响git reset
Giulio

10

为了保留文件中的更改但不提交,我这样做了

git add .

git reset -- main/dontcheckmein.txt

git commit -m "commit message"

验证文件是否被排除

git status





1

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

git add *.c

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

git add <路径说明> ...

要添加内容的文件。可以指定Fileglob(例如* .c)来添加所有匹配的文件。<...>

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

git add **/main/*

添加文件main夹中的所有文件(不忽略)。您甚至可以采用更精细的模式疯狂:

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

上面将添加文件s(any char)c夹中的所有文件,并具有Service名的文件。

显然,您不限于每个命令使用一种模式。也就是说,您可以要求git添加所有扩展名为.c.h的文件

git add *.c *.h

这个连结可以为您提供更多的glob模式想法。

当我进行许多更改时,我发现它特别有用,但仍希望我的提交保持原子性并反映渐进的过程,而不是我当时可能正在从事的更改大杂烩。当然,在某些时候,提出精心设计的模式所花费的成本超过了以更简单的方法甚至一次只添加一个文件来添加文件的成本。但是,大多数时候,我很容易就能用一种简单的模式精确定位所需的文件,而排除其他所有文件。

顺便说一句,您可能需要引用您的glob模式才能使它们起作用,但是对我而言从来没有这样。


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

您可以尝试以下方法: git add * && git reset main/dontcheckmein.txt

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.