简体   繁体   English

如何停止跟踪并忽略对 Git 中文件的更改?

[英]How to stop tracking and ignore changes to a file in Git?

I have cloned a project that includes some .csproj files.我克隆了一个包含一些.csproj文件的项目。 I don't need/like my local csproj files being tracked by Git (or being brought up when creating a patch), but clearly they are needed in the project.我不需要/不喜欢我的本地csproj文件被 Git 跟踪(或在创建补丁时被提出),但显然项目中需要它们。

I have added *.csproj to my LOCAL .gitignore , but the files are already in the repo.我已将*.csproj添加到我的 LOCAL .gitignore中,但这些文件已经在 repo 中。

When I type git status, it shows my changes to csproj which I am not interested in keeping track of or submitting for patches.当我输入 git 状态时,它显示我对csproj的更改,我对跟踪或提交补丁不感兴趣。

How do I remove the "tracking of" these files from my personal repo (but keep them in the source so I can use them) so that I don't see the changes when I do a status (or create a patch)?如何从我的个人存储库中删除这些文件的“跟踪”(但将它们保留在源中以便我可以使用它们),以便在我执行状态(或创建补丁)时看不到更改?

Is there a correct/canonical way to handle this situation?是否有正确/规范的方法来处理这种情况?

Just calling git rm --cached on each of the files you want to remove from revision control should be fine.只需在要从修订控制中删除的每个文件上调用git rm --cached就可以了。 As long as your local ignore patterns are correct you won't see these files included in the output of git status.只要您的本地忽略模式是正确的,您就不会在 git status 的输出中看到这些文件。

Note that this solution removes the files from the repository, so all developers would need to maintain their own local (non-revision controlled) copies of the file请注意,此解决方案会从存储库中删除文件,因此所有开发人员都需要维护自己的本地(非修订控制)文件副本

To prevent git from detecting changes in these files you should also use this command:为了防止 git 检测到这些文件中的更改,您还应该使用以下命令:

git update-index --assume-unchanged [path]

What you probably want to do: (from below @Ryan Taylor answer )您可能想要做什么:(来自@Ryan Taylor 的回答

  1. This is to tell git you want your own independent version of the file or folder.这是告诉 git 你想要你自己的独立版本的文件或文件夹。 For instance, you don't want to overwrite (or delete) production/staging config files.例如,您不想覆盖(或删除)生产/暂存配置文件。

git update-index --skip-worktree <path-name>

The full answer is here in this URL: http://source.kohlerville.com/2009/02/untrack-files-in-git/完整的答案在这个 URL 中:http: //source.kohlerville.com/2009/02/untrack-files-in-git/

There are 3 options;有3个选项; you probably want #3你可能想要#3

  1. This will keep the local file for you, but will delete it for anyone else when they pull.这将为您保留本地文件,但会在其他任何人拉取时将其删除。

    git rm --cached <file-name> or git rm -r --cached <folder-name> git rm --cached <file-name>git rm -r --cached <folder-name>

  2. This is for optimization, like a folder with a large number of files, eg SDKs that probably won't ever change.这是为了优化,就像一个包含大量文件的文件夹,例如可能永远不会改变的 SDK。 It tells Git to stop checking that huge folder every time for changes, locally, since it won't have any.它告诉 Git 每次都停止在本地检查那个巨大的文件夹是否有变化,因为它不会有任何变化。 The assume-unchanged index will be reset and file(s) overwritten if there are upstream changes to the file/folder (when you pull).如果文件/文件夹有上游更改(当您拉取时), assume-unchanged索引将被重置并覆盖文件。

     git update-index --assume-unchanged <path-name>
  3. This is to tell Git that you want your own independent version of the file or folder.这是告诉 Git 你想要你自己的独立版本的文件或文件夹。 For instance, you don't want to overwrite (or delete) production/staging config files.例如,您不想覆盖(或删除)生产/暂存配置文件。

     git update-index --skip-worktree <path-name>

    It's important to know that git update-index will not propagate with Git, so each user will have to run it independently.重要的是要知道git update-index不会随 Git 传播,因此每个用户都必须独立运行它。

If you do git update-index --assume-unchanged file.csproj , git won't check file.csproj for changes automatically: that will stop them coming up in git status whenever you change them.如果您执行git update-index --assume-unchanged file.csproj ,git 不会自动检查 file.csproj 的更改:这将阻止它们在您更改它们时以 git 状态出现。 So you can mark all your .csproj files this way- although you'll have to manually mark any new ones that the upstream repo sends you.因此,您可以通过这种方式标记所有 .csproj 文件——尽管您必须手动标记上游存储库发送给您的任何新文件。 (If you have them in your .gitignore or .git/info/exclude , then ones you create will be ignored) (如果您在.gitignore.git/info/exclude中有它们,那么您创建的将被忽略)

I'm not entirely sure what .csproj files are... if they're something along the lines of IDE configurations (similar to Eclipse's .eclipse and .classpath files) then I'd suggest they should simply never be source-controlled at all.我不完全确定 .csproj 文件是什么......如果它们与 IDE 配置类似(类似于 Eclipse 的 .eclipse 和 .classpath 文件),那么我建议它们永远不应该在源代码控制全部。 On the other hand, if they're part of the build system (like Makefiles) then clearly they should--- and a way to pick up optional local changes (eg from a local.csproj a la config.mk) would be useful: divide the build up into global parts and local overrides.另一方面,如果它们是构建系统的一部分(如 Makefiles),那么显然它们应该——并且一种获取可选本地更改的方法(例如从 local.csproj 和 la config.mk)将很有用:将构建分为全局部分和局部覆盖。

This is a two step process:这是一个两步过程:

  1. Remove tracking of file/folder - but keep them on disk - using删除文件/文件夹的跟踪 - 但将它们保留在磁盘上 - 使用

    git rm --cached

    Now they do not show up as "changed" but still show as现在它们没有显示为“已更改”,但仍显示为

     untracked files in git status -u
  2. Add them to .gitignore将它们添加到.gitignore

The accepted answer still did not work for me接受的答案仍然对我不起作用

I used我用了

git rm -r --cached . git rm -r --cached 。

git add .混帐添加。

git commit -m "fixing .gitignore" git commit -m "修复.gitignore"

Found the answer from here这里找到答案

Forgot your .gitignore?忘记了 .gitignore?

If you have the entire project locally but forgot to add you git ignore and are now tracking some unnecessary files use this command to remove everything如果您在本地拥有整个项目但忘记添加 git ignore 并且现在正在跟踪一些不必要的文件,请使用此命令删除所有内容

git rm --cached -r .

make sure you are at the root of the project.确保您位于项目的根目录。

Then you can do the usual然后你可以照常做

Add添加

git add .

Commit犯罪

git commit -m 'removed all and added with git ignore'

Push

git push origin master

Conclusion结论

Hope this helps out people who have to make changes to their .gitignore or forgot it all together.希望这可以帮助那些不得不对他们的.gitignore进行更改或完全忘记它的人。

  • It removes the entire cache它删除了整个缓存
  • Looks at your .gitignore查看您的 .gitignore
  • Adds the files you want to track添加要跟踪的文件
  • Pushes to your repo推送到您的仓库

As pointed out in other answers, the selected answer is wrong.正如其他答案中指出的那样,所选答案是错误的。

The answer to another question suggests that it may be skip-worktree that would be required.另一个问题的答案表明可能需要跳过工作树。

git update-index --skip-worktree <file>

That answer links to an article ( http://fallengamer.livejournal.com/93321.html ) and quotes the article with a nice summary of the difference between --assume-unchanged and --skip-worktree as follows:答案链接到一篇文章 ( http://fallengamer.livejournal.com/93321.html ) 并引用了这篇文章,并对 --assume-unchanged 和 --skip-worktree 之间的区别进行了很好的总结,如下所示:

--assume-unchanged assumes that a developer shouldn't change a file. --assume-unchanged假定开发人员不应该更改文件。 This flag is meant for improving performance for not-changing folders like SDKs.此标志旨在提高 SDK 等不更改文件夹的性能。

--skip-worktree is useful when you instruct git not to touch a specific file ever because developers should change it. --skip-worktree当您指示 git 不要碰特定文件时很有用,因为开发人员应该更改它。 For example, if the main repository upstream hosts some production-ready configuration files and you don't want to accidentally commit changes to those files, --skip-worktree is exactly what you want.例如,如果上游的主存储库托管了一些生产就绪的配置文件,并且您不想意外提交对这些文件的更改,那么 --skip-worktree 正是您想要的。

All credit to borealid for their research and answer.所有的功劳归功于他们的研究和回答。 Including this info here purely for the convenience of others.在这里包含此信息纯粹是为了方便他人。

To prevent monitoring a file or path by git防止通过 git 监控文件或路径

git update-index --assume-unchanged [file-path]

And to revert it back use并将其恢复使用

git update-index --no-assume-unchanged [file-path]

A repo to refer for similar use cases https://github.com/awslabs/git-secrets参考类似用例的回购https://github.com/awslabs/git-secrets

To save some time the rules you add to your .gitignore can be used for removing multiple files/folders ie为了节省一些时间,您添加到 .gitignore 的规则可用于删除多个文件/文件夹,即

git rm --cached app/**/*.xml

or或者

git rm --cached -r app/widgets/yourfolder/

etc ETC

Lots of people advise you to use git update-index --assume-unchanged .很多人建议您使用git update-index --assume-unchanged Indeed, this may be a good solution, but only in the short run.事实上,这可能是一个很好的解决方案,但只是在短期内。

What you probably want to do is this: git update-index --skip-worktree .您可能想要做的是: git update-index --skip-worktree

(The third option, which you probably don't want is: git rm --cached . It will keep your local file, but will be marked as removed from the remote repository.) (您可能不想要的第三个选项是: git rm --cached 。它将保留您的本地文件,但将被标记为从远程存储库中删除。)

Difference between the first two options?前两个选项之间的区别?

  • assume-unchanged is to temporary allow you to hide modifications from a file. assume-unchanged是临时允许您隐藏文件中的修改。 If you want to hide modifications done to a file, modify the file, then checkout another branch, you'll have to use no-assume-unchanged then probably stash modifications done.如果你想隐藏对文件所做的修改,修改文件,然后签出另一个分支,你必须使用no-assume-unchanged然后可能隐藏修改完成。
  • skip-worktree will follow you whatever the branch you checkout, with your modifications!无论您签出哪个分支, skip-worktree都会跟随您进行修改!

Use case of assume-unchanged assume-unchanged的用例

It assumes this file should not be modified, and gives you a cleaner output when doing git status .它假定不应修改此文件,并在执行git status时为您提供更清晰的输出。 But when checking out to another branch, you need to reset the flag and commit or stash changes before so.但是当签出到另一个分支时,您需要重置标志并在此之前提交或存储更改。 If you pull with this option activated, you'll need to solve conflicts and git won't auto merge.如果您在激活此选项的情况下进行拉取,您将需要解决冲突并且 git 不会自动合并。 It actually only hides modifications ( git status won't show you the flagged files).它实际上只隐藏修改( git status不会显示标记的文件)。

I like to use it when I only want to stop tracking changes for a while + commit a bunch of files ( git commit -a ) related to the same modification.当我只想停止跟踪更改一段时间+提交与相同修改相关的一堆文件( git commit -a )时,我喜欢使用它。

Use case of skip-worktree skip-worktree的用例

You have a setup class containing parameters (eg. including passwords) that your friends have to change accordingly to their setup.您有一个设置类,其中包含您的朋友必须根据他们的设置相应地更改的参数(例如,包括密码)。

  • 1: Create a first version of this class, fill in fields you can fill and leave others empty/null. 1:创建此类的第一个版本,填写您可以填写的字段并将其他字段留空/null。
  • 2: Commit and push it to the remote server. 2:提交并推送到远程服务器。
  • 3: git update-index --skip-worktree MySetupClass.java 3: git update-index --skip-worktree MySetupClass.java
  • 4: Update your configuration class with your own parameters. 4:用你自己的参数更新你的配置类。
  • 5: Go back to work on another functionnality. 5:回去工作另一个功能。

The modifications you do will follow you whatever the branch.无论分支如何,您所做的修改都将跟随您。 Warning: if your friends also want to modify this class, they have to have the same setup, otherwise their modifications would be pushed to the remote repository.警告:如果你的朋友也想修改这个类,他们必须有相同的设置,否则他们的修改会被推送到远程仓库。 When pulling, the remote version of the file should overwrite yours.拉动时,文件的远程版本应覆盖您的文件。

PS: do one or the other, but not both as you'll have undesirable side-effects. PS:做一个或另一个,但不要同时做,因为你会有不良的副作用。 If you want to try another flag, you should disable the latter first.如果你想尝试另一个标志,你应该先禁用后者。

To tell Git not to track changes to your local file/folder (meaning git status won't detect changes to it), do:要告诉 Git 不要跟踪对本地文件/文件夹的更改(意味着 git status 不会检测到对它的更改),请执行以下操作:

git update-index --skip-worktree path/to/file

And to tell Git to track changes to your local version once again (so you can commit the changes), do:并告诉 Git 再次跟踪对本地版本的更改(以便您可以提交更改),请执行以下操作:

git update-index --no-skip-worktree path/to/file

one line answer git update-index --assume-unchanged [path]一行回答git update-index --assume-unchanged [path]

Use this whenever you have a file that is in central repo and also local repo.you need to make changes in that file but must not be staged/committed to the central repo.只要您有一个位于中央仓库和本地仓库中的文件,就可以使用它。您需要在该文件中进行更改,但不得暂存/提交到中央仓库。 This file should not be added in .gitignore .此文件不应添加到.gitignore中。 because new changes in the file if introduced by system administrators, senior developers needs to be distributed among all local repos.因为如果系统管理员引入文件中的新更改,高级开发人员需要分布在所有本地存储库中。

Best Example: config file for DB connections .最佳示例:数据库连接的配置文件 In a central repo, you will have all the username,password, host,port with values of a production DB server.在中央存储库中,您将拥有所有用户名、密码、主机、端口以及生产数据库服务器的值。 But in local dev, you should use only a local or any other development DB server(that your team has setup).但是在本地开发中,您应该只使用本地或任何其他开发数据库服务器(您的团队已经设置)。 In this case you wanna make changes in config file but should not be committed to central repo.在这种情况下,您想在配置文件中进行更改,但不应该提交到中央仓库。

Best最好的

Apply .gitignore to the present/future将 .gitignore 应用于现在/未来

This method applies the standard .gitignore behavior, and does not require manually specifying the files that need to be ignored .此方法应用标准的 .gitignore 行为,不需要手动指定需要忽略的文件

Can't use --exclude-from=.gitignore anymore :/ - Here's the updated method:不能再使用--exclude-from=.gitignore了:/ - 这是更新的方法:

General advice: start with a clean repo - everything committed, nothing pending in working directory or index, and make a backup !一般建议:从一个干净的 repo 开始——所有内容都已提交,工作目录或索引中没有任何待处理的内容,并进行备份

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

If you also need to purge the newly-ignored files from the branch's commit history or if you don't want the newly-ignored files to be deleted from future pulls , see this answer .如果您还需要从分支的提交历史记录中清除新忽略的文件,或者如果您不希望从未来的 pulls 中删除新忽略的文件,请参阅此答案

git rm --fileName

git ls-files以确保文件已被删除或未跟踪

git commit -m "UntrackChanges"

git push

I am assuming that you are asking how to remove ALL the files in a specific folder or the bin folder, Rather than selecting each files separately.我假设您询问如何删除特定文件夹或 bin 文件夹中的所有文件,而不是单独选择每个文件。

You can use this command:你可以使用这个命令:

git rm -r -f /<floder-name>\*

Make sure that you are in the parent directory of the of that directory.确保您位于该目录的父目录中。
This command will, recursively "delete" all the files which are in the bin/ or build/ folders.该命令将递归地“删除” bin/ 或 build/ 文件夹中的所有文件。 By the word delete I mean that git will pretend that those files are "deleted" and those files will not be tracked.删除这个词我的意思是 git 会假装这些文件被“删除”并且这些文件不会被跟踪。 The git really marks those files to be in delete mode. git 确实将这些文件标记为处于删除模式。

Do make sure that you have your .gitignore ready for upcoming commits.请确保您的 .gitignore 已为即将到来的提交做好准备。
Documentation : git rm文档:git rm

The problem may be caused by the order of operation.该问题可能是由操作顺序引起的。 If you modified the .gitignore first, then git rm --cached xxx,you may have to continue to encounter this problem.如果你先修改了.gitignore,然后git rm --cached xxx,你可能还要继续遇到这个问题。

Correct solution:正确解决方案:

  1. git rm --cached xxx git rm --cached xxx
  2. modified the .gitignore修改了 .gitignore

Order invariant!订单不变!

The .gitignore reload after modification! .gitignore 修改后重新加载!

I am assuming that you are trying to remove a single file from git tacking.我假设您正在尝试从 git tacking 中删除单个文件。 for that I would recommend below command.为此,我建议使用以下命令。

git update-index --assume-unchanged git update-index --assume-unchanged

Ex - git update-index --assume-unchanged .gitignore .idea/compiler.xml前 - git update-index --assume-unchanged .gitignore .idea/compiler.xml

To ignore any changes to all the files (of a certain type) in a directory, I had to combine some of these approaches, otherwise the files were created if they didn't previously exist.要忽略对目录中所有文件(某种类型)的任何更改,我必须结合其中一些方法,否则如果文件以前不存在,则会创建这些文件。

In the below, "excludedir" is the name of the directory that I wish to not watch changes to.在下面,“excludedir”是我不希望看到更改的目录的名称。

First, remove any existing new files from your change tracking cache (without removing from your file system).首先,从更改跟踪缓存中删除任何现有的新文件(不从文件系统中删除)。

git status | grep "new file:" | cut  --complement -d " " -f1-4 | grep "^excludedir" | xargs git rm --cache

You can do the same with modified: .您可以对modified:执行相同的操作。 renamed: is a bit more complicated, as you'll have to look at the post -> bit for the new filename, and do the pre -> bit as described for deleted: below. renamed:有点复杂,因为您必须查看新文件名的 post ->位,并按照下面的deleted:描述执行 pre ->位。

deleted: files prove a bit more complicated, as you can't seem to update-index for a file that doesn't exist on the local system deleted:文件证明有点复杂,因为您似乎无法为本地系统上不存在的文件更新索引

echo .deletedfiles >> .gitignore
git status | grep "deleted:" | cut  --complement -d " " -f1-4 | grep "^excludedir" > .deletedfiles
cat .deletedfiles | xargs -d '\n' touch
cat .deletedfiles | xargs -d '\n' git add -f
cat .deletedfiles | xargs -d '\n' git update-index --assume-unchanged
cat .deletedfiles | xargs -d '\n' rm

The last command in the list above will remove the files again from your file system, so feel free to omit that.上面列表中的最后一个命令将再次从文件系统中删除文件,因此请随意省略它。

Then, block change tracking from that directory然后,阻止该目录的更改跟踪

git ls-files excludedir/ | xargs git update-index --skip-worktree
git update index --skip-worktree excludedir/

An almost git command-free approach was given in this answer :在这个答案中给出了一种几乎不需要 git 命令的方法

To ignore certain files for every local repo :要忽略每个本地 repo的某些文件:

  1. Create a file ~/.gitignore_global , eg by touch ~/.gitignore_global in your terminal.创建一个文件~/.gitignore_global ,例如通过在终端中touch ~/.gitignore_global
  2. Run git config --global core.excludesfile ~/.gitignore_global for once.运行git config --global core.excludesfile ~/.gitignore_global一次。
  3. Write the file/dir paths you want to ignore into ~/.gitignore_global .将要忽略的文件/目录路径写入~/.gitignore_global eg modules/*.H , which will be assumed to be in your working directory, ie $WORK_DIR/modules/*.H .例如modules/*.H ,它将被假定在您的工作目录中,即$WORK_DIR/modules/*.H

To ignore certain files for a single local repo :要忽略单个本地 repo 的某些文件:

  1. Do the above third step for file .git/info/exclude within the repo, that is write the file/dir paths you want to ignore into .git/info/exclude .对 repo 中的文件.git/info/exclude执行上述第三步,即将要忽略的文件/目录路径.git/info/exclude eg modules/*.C , which will be assumed to be in your working directory, ie $WORK_DIR/modules/*.C .例如modules/*.C ,它将被假定在您的工作目录中,即$WORK_DIR/modules/*.C

after search a long time , find a way do this .找了半天,想办法做到这一点。 alias a git command in .gitconfig .like in android studio project,before checkout branch revert config file and then skip it ,after checkout branch use sed change config file to my local config..gitconfig中别名一个 git 命令。就像在 android studio 项目中一样,在 checkout 分支之前还原配置文件然后跳过它,在 checkout 分支之后使用sed将配置文件更改为我的本地配置。 checkoutandmodifylocalproperties = !git update-index --no-skip-worktree local.properties && git checkout local.properties && git checkout $1 && git update-index --skip-worktree local.properties && sed -i '' 's/.*sdk.dir.*/sdk.dir=\\/Users\\/run\\/Library\\/Android\\/sdk/g' local.properties && :

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM