只将修改过的变化添加到Git中,忽略未跟踪的文件。

889

我运行了"git status"命令,下面列出了一些被修改的文件或者在"未暂存的改动"这个部分中。它还列出了一些我想要忽略的未跟踪的文件(这些目录下有一个".gitignore"文件)。

我想将修改后的文件放入暂存区以便提交。当我运行"git add ."时,它添加了修改的文件和我想要忽略的文件到暂存区。

如果下面的git状态呈现出来,如何只添加修改后的文件并忽略未跟踪的文件?

另外,我的".gitignore"文件是否正常工作?

$ git status
# On branch addLocation
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   someProject/path/domain/viewer/LocationDO.java
#       modified:   someProject/path/service/ld/LdService.java
#       modified:   someProject/path/service/ld/LdServiceImpl.java
#       modified:   someProject/path/web/jsf/viewer/LocationFormAction.java
#       modified:   someProject/war/WEB-INF/classes/message/viewer/viewer.properties
#       modified:   someProject/war/page/viewer/searchForm.xhtml
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       .metadata/
#       someProject/build/
no changes added to commit (use "git add" and/or "git commit -a")

2
如果在跟踪文件之后添加了 .gitignore 文件,则 .gitignore 文件将不会忽略已经被跟踪的文件。这可能会成为一个问题。 - BenKoshy
10个回答

1192

理想情况下,您的.gitignore应该防止未跟踪(和被忽略的)文件在状态中显示,使用git add等添加。因此,我建议您更正您的.gitignore

您可以执行git add -u,这样它将对修改和删除的文件进行暂存。

您还可以执行git commit -a,只提交修改和删除的文件。

请注意,如果您使用的是Git版本2.0之前的版本并且使用了git add .,那么您需要使用git add -u .(请参见““git add -A”和“git add .”的区别”)。


110
重点是,add -u 不仅会添加“修改过”的文件,还会“添加”已删除的文件... 这正是我目前试图防止的。 - Zach Lysobey
7
为了仅添加修改过的文件,通常我会进入我的repo的顶层目录并输入以下命令:for fil in $(git diff --name-only --relative); do git add $fil; done。如果我需要频繁使用它(实际上不需要),我会在我的~/.bashrc文件中创建一个别名。当然,这只适用于bash。 - Krøllebølle
12
没有确定的答案,只有“适合大多数人”的答案?我必须使用另一个过程来正确地完成这个任务?为什么这不被集成到git add中呢?它似乎是一个非常普遍的需求。 - Samuel
2
请注意,如果您的文件名不规则(包含空格、星号等),则这些注释中提到的方法将失败。为了正确转义任何奇怪命名的文件,请使用以下命令:IFS=$(echo -en "\n\b"); for file in $(git diff --name-only); do git add "$file"; done - Orwellophile
8
git add -ugit add --update 的简写,git commit -agit commit --all 的简写。 - Hugo
显示剩余3条评论

130

这对我起作用:

#!/bin/bash

git add `git status | grep modified | sed 's/\(.*modified:\s*\)//'`

甚至更好的是:

$ git ls-files --modified | xargs git add

如果您不打算重复使用组,则无需使用分组(()),并且对于文件名前的空格,\s会留下空格。虽然在这种情况下它不会影响最终结果,但为了树立榜样,在此提供我使用的sed命令:sed 's/.*modified: *//'. 在Mac OS X 10.9.5上验证过。 - Samuel
@Samuel 分组在测试表达式时非常有用。然后我可以将匹配内容打印在方括号内,以确保我的正确性。 - user877329
1
@Ярослав,您的解决方案添加了修改和未跟踪的文件,并且等同于 git add -u,因此它并没有回答问题。 - Nick Volynkin
8
修改似乎包括已删除的内容,而不仅仅是修改过的内容。 - DMart
2
git diff-files -z --diff-filter=M --name-only | xargs -0 git add --dry-run 看起来运行良好。 - DMart
显示剩余5条评论

53

将修改和删除的文件暂存:

git add -u

其中,-u--update 的缩写。


很棒!谢谢! - KansaiRobot

20
git commit -a -m "message"

-a:将本次提交中所有已更改/删除的文件都包含在内。但要记住,未跟踪(新建)的文件不包括在内。

-m:设置提交的信息。


5
只需要执行git commit -am "message"即可。 - Asef Hossini

9

我碰巧尝试这个来先看到文件列表:

git status | grep "modified:" | awk '{print "git add  " $2}' > file.sh

cat ./file.sh

执行:

chmod a+x file.sh
./file.sh 

编辑:(请参见评论) 这可以通过一步完成:

git status | grep "modified:" | awk '{print $2}' | xargs git add && git status

2
这可以通过一步完成:git status | grep modified | awk '{print $2}' | xargs git add && git status - Choylton B. Higginbottom
是的,我应该也提供了那个解决方案,谢谢,我已经更新了帖子。 - Mike Q
在我看来,这是最佳答案。允许有针对性地添加,仔细查阅了git-add手册,没有像这个答案中建议的那样能够简单实现这一点的内容。干杯! - Meuko

5
我想把修改后的文件放入暂存区,以便提交它们。 TL;DR:开始 使用交互模式(git add -i),选择更新(在What now>提示中键入 2u),选择所有文件(在Update>>提示中键入 *),退出交互模式(在What now>提示中键入 7q)。 TL;DR:结束 对于更有耐心的人:--- 步骤 1 您可以使用交互模式。
git add --interactive 

或者简写形式,
git add -i

这将提供一个所有已修改文件及其状态的列表,以及一些可用的命令选项,例如:
           staged     unstaged path
  1:    unchanged       +17/-0 package-lock.json
  2:    unchanged        +2/-0 package.json
  3:    unchanged       +2/-28 src/App.js
  4:    unchanged        +7/-6 src/App.test.js

*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
What now>

步骤二

对于您的情况,在What now>后键入u2

What now>u

你得到以下内容:

           staged     unstaged path
  1:    unchanged       +17/-0 package-lock.json
  2:    unchanged        +2/-0 package.json
  3:    unchanged       +2/-28 src/App.js
  4:    unchanged        +7/-6 src/App.test.js
Update>> *

步骤 3

Update>> 提示符中,键入 * 将上面列表中的所有文件添加到暂存区(您也可以通过提供逗号分隔的数字来添加单个文件),

Update>> *

此时,您修改的所有文件都已添加到暂存区,您可以通过在“现在怎么办>”提示中键入1s来验证状态(或者只需键入q7退出交互模式并运行通常的git status命令)。请保留HTML标签。
What now> 1

这将显示您的状态。

           staged     unstaged path
  1:       +17/-0      nothing package-lock.json
  2:        +2/-0      nothing package.json
  3:       +2/-28      nothing src/App.js
  4:        +7/-6      nothing src/App.test.js

我们可以看到这里的“未暂存”列显示了列表中所有文件的文本“nothing”。
至于忽略未跟踪的文件的第二个问题,我相信这个SO答案会很有帮助。

4
你没有说明你现在的.gitignore是什么,但是在你的根目录中有以下内容的.gitignore应该可以解决问题。
.metadata
build

4
我一直错误地使用我的 .gitignore 文件。我在每个我想要忽略的目录中都有一个空的 .gitignore 文件,而不是一个包含内容的单个 gitignore 文件。 - Steve
1
@Steve:如果每个.gitignore文件都包含一个起始(忽略所有内容),那么这种方法是可行的。但通常在顶级目录中只需要一个.gitignore文件就足够简单易用了。 - maaartinus

1

我不确定这是一项功能还是一个错误,但对我们有效:

git commit '' -m "Message"

请注意空文件列表''。 Git 将其解释为提交所有已修改的被跟踪的文件,即使它们没有被暂存,并忽略未被跟踪的文件。


使用“--amend”时这肯定是不行的 - GhostCat

1
git add $(git status --short | grep '.M ' | sed 's/.M //')
# Change the regex pattern of grep only.
# So, if you create a custom shell alias or function, 
# the regex pattern of grep should be the parameter.

. 是正则表达式中的任意一个字符。 简写形式由X和Y字段以及文件名组成。例如:XY filename.py

git-status手册的“简写格式”部分中查看以精确选择文件。

M example.py:X字段中有空的暂存更改,Y字段中有未暂存的更改。

MM example.py:X字段中有暂存的更改,Y字段中有未暂存的更改。


-4

git commit -am "在这里输入你的消息" 这对我起作用了


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