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

时间:2009-06-01 19:08:16

标签: git

我克隆了一个包含一些.csproj文件的项目。我不需要/喜欢我的本地csproj文件被Git跟踪(或者在创建补丁时被提起),但显然它们在项目中是必需的。

我已将*.csproj添加到我的LOCAL .gitignore,但文件已在回购邮件中。

当我输入git status时,它显示我对csproj的更改,我对跟踪或提交补丁不感兴趣。

如何从我的个人仓库中删除这些文件的“跟踪”(但是将它们保存在源代码中以便我可以使用它们)以便在我执行状态时(或创建补丁)时看不到更改)?

是否有正确/规范的方法来处理这种情况?

20 个答案:

答案 0 :(得分:1947)

只需在要从版本控制中删除的每个文件上调用git rm --cached即可。只要您的本地忽略模式正确,您就不会在git status的输出中看到这些文件。

请注意,此解决方案会从存储库中删除文件,因此所有开发人员都需要维护自己的本地(非版本控制)文件副本

要防止git检测到这些文件中的更改,您还应该使用以下命令:

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

你可能想做什么:(来自@Ryan Taylor answer下方)

  
      
  1. 这是告诉git你想要自己的文件或文件夹的独立版本。例如,您不想覆盖(或删除)   生产/暂存配置文件。
  2.         

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

完整答案位于以下网址:http://source.kohlerville.com/2009/02/untrack-files-in-git/

答案 1 :(得分:236)

如果你执行git update-index --assume-unchanged file.csproj,git将不会自动检查file.csproj的更改:这将阻止它们在您更改它们时以git状态出现。因此,您可以用这种方式标记所有.csproj文件 - 尽管您必须手动标记上游repo发送给您的任何新文件。 (如果您在.gitignore.git/info/exclude中有这些内容,那么您创建的内容将被忽略)

我不完全确定.csproj文件是什么......如果它们是IDE配置(类似于Eclipse的.eclipse和.classpath文件),那么我建议它们应该永远不会是源代码完全控制住了。另一方面,如果它们是构建系统的一部分(比如Makefiles),那么显然它们应该---并且一种方法来获取可选的局部更改(例如从local.csproj a la config.mk)将是有用的:将构建划分为全局部分和本地覆盖。

答案 2 :(得分:166)

有3个选项,您可能需要#3

1。这会为您保留本地文件,但会在其他人拉动时将其删除。

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

2。这是为了优化,就像一个包含大量文件的文件夹,例如SDK可能永远不会改变。它告诉git每次在本地停止检查那个巨大的文件夹,因为它没有任何更改。如果文件/文件夹有上游更改(当您拉动时),assume-unchanged索引将被重置并且文件被覆盖。

git update-index --assume-unchanged <path-name>

3. 这是告诉git你想要自己的文件或文件夹的独立版本。例如,您不想覆盖(或删除)生产/暂存配置文件。

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

了解git update-index 不会使用git传播非常重要,每个用户都必须独立运行。

答案 3 :(得分:145)

这是一个两步过程:

  1. 删除文件/文件夹的跟踪 - 但将它们保存在磁盘上 - 使用

    git rm --cached 
    

    现在他们没有显示为“已更改”但仍显示为

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

答案 4 :(得分:88)

接受的答案仍然不适合我

我用过

  

git rm -r --cached。

     

git add。

     

git commit -m“fix .gitignore”

here

找到答案

答案 5 :(得分:43)

忘记你的.gitignore?

如果您在本地拥有整个项目但忘记添加git ignore并且现在正在跟踪一些不必要的文件,请使用此命令删除所有内容

git rm --cached -r .

确保你是项目的根源。

然后你可以做通常的

添加

git add .

提交

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

git push origin master

结论

希望这可以帮助那些必须对.gitignore进行更改或者忘记一切的人。

  • 删除整个缓存
  • 查看你的.gitignore
  • 添加要跟踪的文件
  • 推送您的回购

答案 6 :(得分:22)

正如其他答案所指出,所选答案是错误的。

另一个问题的answer表明可能需要跳过工作树。

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

答案 7 :(得分:21)

为节省时间,您添加到.gitignore的规则可用于删除多个文件/文件夹,例如。

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

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

e.t.c。

答案 8 :(得分:8)

很多人建议你使用git update-index --assume-unchanged。实际上,这可能是一个很好的解决方案,但只是在短期内。

您可能想要做的是:git update-index --skip-worktree

(第三个选项,您可能不需要:git rm --cached。它将保留您的本地文件,但会被标记为从远程存储库中删除。)

前两个选项之间的差异?

  • assume-unchanged是临时允许您隐藏文件的修改。如果你想隐藏对文件所做的修改,修改文件,然后检查另一个分支,你必须使用no-assume-unchanged然后可能存储修改。
  • skip-worktree会跟踪您,无论您检查的分支是什么,并进行修改!

使用assume-unchanged

的案例

它假定不应修改此文件,并在执行git status时为您提供更清晰的输出。但是当签出到另一个分支时,您需要重置标志并提交或存储更改。如果你激活此选项,你需要解决冲突,git不会自动合并。它实际上只隐藏修改(git status不会显示标记的文件)。

当我只想停止跟踪一段时间的更改并提交与相同修改相关的一堆文件(git commit -a)时,我喜欢使用它。

使用skip-worktree

的案例

您有一个包含参数(例如包括密码)的设置类,您的朋友必须根据其设置进行更改。

  • 1:创建此类的第一个版本,填写您可填写的字段,并将其他人留空/为空。
  • 2:提交并将其推送到远程服务器。
  • 3:git update-index --skip-worktree MySetupClass.java
  • 4:使用您自己的参数更新配置类。
  • 5:回去处理另一个功能。

无论分支如何,您所做的修改都会随之而来。警告:如果您的朋友也想修改此类,他们必须具有相同的设置,否则他们的修改将被推送到远程存储库。拉动时,文件的远程版本应覆盖您的。

PS:做一个或另一个,但不是两个,因为你会产生不良副作用。如果你想尝试另一个标志,你应该先禁用后者。

答案 9 :(得分:6)

告诉Git不要跟踪对本地文件/文件夹的更改(意味着git status不会检测到对它的更改),请执行以下操作:

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

要告诉Git再次跟踪对本地版本的更改(以便您可以提交更改),请执行以下操作:

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

答案 10 :(得分:5)

防止通过git监视文件

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

并将其还原为使用

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

引用类似用例的回购https://github.com/awslabs/git-secrets

答案 11 :(得分:1)

一行答案 git update-index --assume-unchanged [path]

只要您在中央存储库中还有本地存储库中都有文件,请使用此文件。您需要在该文件中进行更改,但不得暂存/提交给中央存储库。 此文件不应添加到.gitignore中。因为文件的新更改(如果由系统管理员引入),则高级开发人员需要在所有本地存储库中分发。

最佳示例:用于数据库连接的配置文件。在中央存储库中,您将拥有所有用户名,密码,主机,端口以及生产数据库服务器的值。但是在本地开发人员中,您应该仅使用本地或任何其他开发数据库服务器(您的团队已设置)。在这种情况下,您想在配置文件中进行更改,但不应提交给中央存储库。

最佳

答案 12 :(得分:0)

git rm --fileName

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

git commit -m "UntrackChanges"

git push

答案 13 :(得分:0)

将.gitignore应用于当前/未来

  

此方法应用标准的.gitignore行为,并且不需要手动指定需要忽略的文件

     

不能再使用--exclude-from=.gitignore:/-这是更新的方法:

     

一般建议:从干净的仓库开始-提交的所有内容,工作目录或索引中没有待处理的内容,并进行备份

#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

如果您还需要从分支的提交历史记录中清除新忽略的文件,,或者,如果您不想从以后的提取操作中删除新忽略的文件,请参见{{3} }。

答案 14 :(得分:0)

在此answer中给出了几乎 git无命令的方法

要忽略 每个本地存储区的某些文件:

  1. 创建文件~/.gitignore_global,例如由touch ~/.gitignore_global在您的终端中。
  2. 运行git config --global core.excludesfile ~/.gitignore_global一次。
  3. 将要忽略的文件/目录路径写入~/.gitignore_global。例如modules/*.H,它将被假定在您的工作目录中,即$WORK_DIR/modules/*.H

要忽略某些文件,以单个本地存储库

  1. 对存储库中的文件.git/info/exclude执行上述第三步,即将要忽略的文件/目录路径写入.git/info/exclude。例如modules/*.C,它将被假定在您的工作目录中,即$WORK_DIR/modules/*.C

答案 15 :(得分:0)

要忽略目录中所有文件(某种类型)的任何更改,我必须将这些方法中的一些组合起来,否则如果以前不存在则创建文件。

在下文中,“excludedir”是我不希望更改的目录的名称。

首先,从更改跟踪缓存中删除所有现有新文件(无需从文件系统中删除)。

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

您可以对modified:执行相同的操作。 renamed:稍微复杂一点,因为您必须查看新文件名的->位,并按照->所述执行前deleted:位下方。

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

上面列表中的最后一个命令将再次从文件系统中删除文件,因此请随意省略。

然后,从该目录阻止更改跟踪

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

答案 16 :(得分:0)

我假设您正在尝试从git中删除单个文件。 因为我会推荐下面的命令。

git update-index --assume-unchanged

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

答案 17 :(得分:0)

问题可能是由操作顺序引起的。 如果你先修改.gitignore,然后git rm --cached xxx,你可能不得不继续遇到这个问题。

正确的解决方案:

  1. git rm --cached xxx
  2. 修改了.gitignore
  3. 订单不变!

    .gitignore在修改后重新加载!

答案 18 :(得分:0)

我假设您正在询问如何删除特定文件夹或bin文件夹中的 ALL 文件,而不是单独选择每个文件。

您可以使用此命令:

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

确保您位于该目录的父目录中 此命令将以递归方式“删除”bin /或build /文件夹中的所有文件。通过单词delete我的意思是git将假装这些文件被“删除”并且不会跟踪这些文件。 git确实标记了这些文件处于删除模式。

请确保您的.gitignore已准备好接受即将到来的提交 Documentation : git rm

答案 19 :(得分:-1)

经过长时间的搜索,找到了解决方法。 在.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 && :