git add 添加忽略的文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32401387/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 03:33:56  来源:igfitidea点击:

git add adding ignored files

gitgitignore

提问by aw04

I'm trying to remove a previously tracked directory from git, which works, but it's being added back with each subsequent git add ., git add -A, etc. Here's what I've done:

我试图删除混帐,其工作的先前跟踪的目录,但它是被加回以后每次git add .git add -A等这里是我做了什么:

Add to .gitignore in root of project:

添加到项目根目录中的 .gitignore :

node_modules

Run the following:

运行以下命令:

git rm -r --cached node_modules
git commit -a -m "removed node_modules"
git push origin master

So far so good, this removes the directory from the remote repository. The problem is when I later run git statusit tells me the node_modules directory is untracked and keeps adding it back on future commits.

到目前为止一切顺利,这将从远程存储库中删除目录。问题是当我稍后运行时,git status它告诉我 node_modules 目录未被跟踪,并在以后的提交中继续添加它。

What am I missing and/or how do I find the root of my problem?

我错过了什么和/或如何找到问题的根源?

From here:

这里

The git add command will not add ignored files by default. ... The git add command can be used to add ignored files with the -f (force) option.

git add 命令默认不会添加被忽略的文件。... git add 命令可用于通过 -f(强制)选项添加被忽略的文件。

Additional information from comments:

评论中的其他信息:

I am tracking .gitignore file.

我正在跟踪 .gitignore 文件。

git check-ignore node_modules/returns node_modules/ as expected.

git check-ignore node_modules/按预期返回 node_modules/ 。

No use of submodules.

不使用子模块。

Update:

更新:

I've created a sample that appears to replicate the issue following the steps above:

我创建了一个示例,它似乎按照上述步骤复制了该问题:

https://github.com/awhitehouse104/SampleRepo

https://github.com/awhitehouse104/SampleRepo

Resolution:

解析度:

To summarize the answer and comments from below, the issue was in the encoding of my .gitignore file. I had used echo 'node_modules' > .gitignoreto create the file on windows 8 and it came out as UTF-16 with BOM (according to answer below). After a few google searches, it seems this is the default encoding with powershell and I can confirm that saving as UTF-8 seems to have resolved the issue.

总结下面的答案和评论,问题出在我的 .gitignore 文件的编码上。我曾经echo 'node_modules' > .gitignore在 Windows 8 上创建该文件,它以带有 BOM 的 UTF-16 格式出现(根据下面的回答)。经过几次谷歌搜索后,这似乎是 powershell 的默认编码,我可以确认保存为 UTF-8 似乎已经解决了这个问题。

tldr;Probably don't use this method of creating .gitignore files or be prepared to change the encoding

tldr; 可能不要使用这种创建 .gitignore 文件的方法或准备更改编码

echo 'node_modules' > .gitignore

echo 'node_modules' > .gitignore

采纳答案by Roman

You probably have a negative rule (include-again rule, the one that starts with an !) in your .gitignorefile somewhere after the node_modulesline.

!.gitignore文件中该node_modules行之后的某处可能有一个否定规则(再次包含规则,以 an 开头的规则)。

git check-ignorehas a bug/ambiguity in the docs. You expect that if git check-ignore node_modules/prints node_modules/, then node_modules/is ignored. But actually it prints a pathname if that pathname matches any ignore pattern - positive or negative. The only way to be sure is to use the -v(--verbose) option, which will make git check-ignoreprint the matching pattern.
Moreover, if git check-ignore -vsays a directory is ignored, it doesn't necessarily mean that all files in that directory are ignored. Example repo:

git check-ignore文档中有错误/歧义。您期望如果git check-ignore node_modules/打印node_modules/, thennode_modules/被忽略。但实际上,如果该路径名匹配任何忽略模式 - 正或负,它会打印一个路径名。唯一确定的方法是使用-v( --verbose) 选项,它将git check-ignore打印匹配的模式。
此外,如果git check-ignore -v说一个目录被忽略,并不一定意味着该目录中的所有文件都被忽略。示例回购:

/
    .git/
    .gitignore
    node_modules/
        bar
        foo
$ cat .gitignore 
/node_modules/*
!/node_modules/foo

$ git check-ignore -v node_modules/
.gitignore:1:/node_modules/*    node_modules/
             ^ positive pattern => ignored

$ git check-ignore -v node_modules/foo
.gitignore:2:!/node_modules/foo node_modules/foo
             ^ negative pattern => not ignored

$ git add -A

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   node_modules/foo
#

So if git check-ignore -v node_modules/says node_modules/is ignored, do git add -A node_modules/and then run git check-ignore -v --no-indexagainst individual files that got added, to discover why they were added.

因此,如果git check-ignore -v node_modules/saynode_modules/被忽略,请执行git add -A node_modules/然后git check-ignore -v --no-index针对添加的单个文件运行,以发现添加它们的原因。



Update:I didn't expect that: your .gitignorefile is in "UTF-16 with BOM (byte order mark)" encoding:

更新:我没想到:您的.gitignore文件采用“带有 BOM(字节顺序标记)的 UTF-16”编码:

$ cat .gitignore | hexdump -vC
00000000  ff fe 6e 00 6f 00 64 00  65 00 5f 00 6d 00 6f 00  |..n.o.d.e._.m.o.|
00000010  64 00 75 00 6c 00 65 00  73 00 0d 00 0a 00        |d.u.l.e.s.....|

That's why git probably can't handle it. Save the file in UTF-8 without BOM, that should fix the problem. But I also suggest filing a bug report against git check-ignore- in this corner case its output is clearly not consistent with what git actually ignores.

这就是 git 可能无法处理它的原因。将文件保存在没有 BOM 的 UTF-8 中,应该可以解决问题。但我也建议提交一个错误报告git check-ignore- 在这种极端情况下,它的输出显然与 git 实际忽略的不一致。

回答by hspandher

Add the file to git ignore, then

将文件添加到 git ignore,然后

git update-index --assume-unchanged <file>

回答by jthill

You can do

你可以做

git check-ignore -v --no-index path/with/unexpected/result

to see why git adddid or didn't add that path.

看看为什么git add添加或没有添加该路径。

git check-ignoredocs.

git check-ignore文档

In particular, the point is you want to check what's actually getting added, not a directory.

特别是,关键是您要检查实际添加的内容,而不是目录。

further, do find . -name .git. Submodules are nested repos, .gitmodulesand the submodule command are handy but they're just there to help with them.

进一步,做find . -name .git。子模块是嵌套的存储库,.gitmodules子模块命令很方便,但它们只是为了帮助它们。

回答by shan1024

Here is what I do to ignore node_modulesfolder after I tracked it.

这是我在跟踪node_modules文件夹后忽略它的方法。

  1. Create the .gitignorefile and add node_modulesto it.

  2. Commit the .gitignorefile. After this point, whatever you update in the node_modulesfolder won't appear in git status.

  3. But this does not delete what we already have on the repo under the node_modulesfolder. So now we need to remove whatever we have committed previously.

    For this, use git rm --cached node_modules -r

  4. Now git statuswill show that the files are deleted.

  5. Use git commit -m "node_modules removed"command with any message.

  1. 创建.gitignore文件并将node_modules添加到其中。

  2. 提交.gitignore文件。在此之后,您在node_modules文件夹中更新的任何内容都不会出现在git status.

  3. 但这不会删除我们在node_modules文件夹下的 repo 中已有的内容。所以现在我们需要删除我们之前提交的任何内容。

    为此,使用 git rm --cached node_modules -r

  4. 现在git status将显示文件已删除。

  5. git commit -m "node_modules removed"对任何消息使用命令。

Now everything should be removed from the repo and future changes will not be tracked.

现在应该从 repo 中删除所有内容,并且不会跟踪未来的更改。

回答by Jonathan.Brink

Another approach if you don't want to use git rm --cached

如果您不想使用git rm --cached 的另一种方法

rm -Rf node_modules
git add -u
git commit -m "stop tracking node_modules"

npm install
# done

Also note the distinction between node_modules and node_modules/ which you seem to have correct. (Thanks uml?ute for the note on this)

还要注意 node_modules 和 node_modules/ 之间的区别,您似乎是正确的。(感谢 uml?ute 对此的注释)

回答by IAMZERG

I created a repository to try and duplicate your issue, and I got the first answer from http://www.stackoverflow.com/questions/11451535/gitignore-not-workingto work.

我创建了一个存储库来尝试复制您的问题,我从http://www.stackoverflow.com/questions/11451535/gitignore-not-working得到了第一个答案。

Here's my repo if you are curious: https://github.com/IAMZERG/so_project_gitignore

如果你好奇,这是我的回购:https: //github.com/IAMZERG/so_project_gitignore

Try adding this to the .gitignore instead:

尝试将其添加到 .gitignore 中:

**/directory_to_remove

**/directory_to_remove

After that, run git rm --cached directory_to_remove -r

之后,运行 git rm --cached directory_to_remove -r

git status should show that you deleted a bunch of files in the directory you are trying to remove. Then, commit and push to your remote, and everything should be golden... Maybe?

git status 应该显示您删除了要删除的目录中的一堆文件。然后,提交并推送到您的遥控器,一切都应该是金色的......也许吧?

回答by Austin Miller

I had a similary issue. Making sure my encoding was ANSI and the line endings were Unix(LF) fixed my issue.

我有一个类似的问题。确保我的编码是 ANSI 并且行尾是 Unix(LF) 解决了我的问题。

回答by Mwiapfeo

I've found a way to add files to .gitignore even if they have already been commited once. It's a bit brutal but it works great.

我找到了一种将文件添加到 .gitignore 的方法,即使它们已经提交过一次。这有点残酷,但效果很好。

  1. Add the different files to your .gitignore

  2. Move these files out from your git project

  3. Rescan & StageChanged, these operation will tell you that these files have been deleted

  4. Commit

  5. Move back your files to your project, they won't be tracked anymore !

  1. 将不同的文件添加到您的 .gitignore

  2. 将这些文件从您的 git 项目中移出

  3. Rescan & StageChanged,这些操作会告诉你这些文件已经被删除了

  4. 犯罪

  5. 将您的文件移回您的项目,它们将不再被跟踪!

回答by Emipro Technologies Pvt. Ltd.

gitignore - Specifies intentionally untracked files to ignore.

gitignore - 指定要忽略的有意未跟踪的文件。

$HOME/.config/git/ignore, $GIT_DIR/info/exclude, .gitignore

$HOME/.config/git/ignore, $GIT_DIR/info/exclude, .gitignore

Each line in a gitignore file specifies a pattern. When deciding whether to ignore a path, Git normally checks gitignore patterns from multiple sources, with the following order of precedence, from highest to lowest (within one level of precedence, the last matching pattern decides the outcome):

gitignore 文件中的每一行都指定了一个模式。在决定是否忽略路径时,Git 通常会检查来自多个来源的 gitignore 模式,按照以下优先级顺序,从高到低(在一个优先级内,最后匹配的模式决定结果):

To ignore entire directory you should use /**,

要忽略您应该使用的整个目录/**

A trailing /** matches everything inside. For example, abc/** matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.

尾随 /** 匹配里面的所有内容。例如,abc/** 匹配目录“abc”内的所有文件,相对于 .gitignore 文件的位置,具有无限深度。

Or

或者

You can ignore the entire directory by adding this line to your root .gitignore file:

您可以通过将此行添加到根 .gitignore 文件来忽略整个目录:

/Dir_Name

/Dir_Name

Instead, you can add a /logs/.gitignore file containing this:

相反,您可以添加一个包含以下内容的 /logs/.gitignore 文件:

[^.]*

[^.]*

The directory will remain in your repo, but all files inside /directory will be ignored. Easy!

该目录将保留在您的存储库中,但 /directory 中的所有文件都将被忽略。简单!

The steps you need to follows are,

您需要遵循的步骤是,

  1. Remove it from the project directory (without actually deleting it):

    git rm --cached folder/*

  2. If you don't already have a .gitignore, you can make one right inside of your project folder:
  3. project/.gitignore. Put folder/* (or any of the pattern you think better from above listing) in the .gitignore Commit:
  4. git commit -m "message".
  5. Push your change to github.
  1. 从项目目录中删除它(实际上并没有删除它):

    git rm --cached 文件夹/*

  2. 如果你还没有 .gitignore,你可以在你的项目文件夹中创建一个:
  3. 项目/.gitignore。在 .gitignore Commit 中放入 folder/*(或任何你认为更好的模式):
  4. git commit -m "消息"。
  5. 将您的更改推送到 github。

Example to exclude everything except a specific directory foo/bar (note the /* - without the slash, the wildcard would also exclude everything within foo/bar):

排除除特定目录 foo/bar 之外的所有内容的示例(注意 /* - 没有斜杠,通配符也将排除 foo/bar 中的所有内容):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

回答by Fabian

The origin has to be bare. Here is a little bash to demonstrate it. Feel free to edit it, if it does not represent your use case.

原点必须是裸露的。这里有一个小 bash 来演示它。如果它不代表您的用例,请随意编辑它。

#!/bin/bash

rm -rf /tmp/git_test
mkdir /tmp/git_test/
git init --bare /tmp/git_test/primary_repo

# populate repo
cd /tmp/git_test/
git clone ./primary_repo ./secondary_repo
cd secondary_repo
echo hi_bob > some_content
mkdir node_modules
echo hi_dave > node_modules/moduleA
git add .
git commit -m "populated primary"
git push

# do the removal in tertiary 
cd /tmp/git_test/
git clone ./primary_repo ./tertiary_repo
cd tertiary_repo
echo node_modules >> .gitignore
git add .gitignore
git rm -r --cached node_modules
git commit -a -m "removed node_modules"
git push origin master
rm -r node_modules
echo --------------------------------
echo git status:
git status