我克隆了一个包含一些 .csproj
文件的项目。我不需要/不喜欢 Git 跟踪我的本地 csproj
文件(或在创建补丁时提出),但显然项目中需要它们。
我已将 *.csproj
添加到我的本地 .gitignore
,但文件已在存储库中。
当我输入 git status 时,它会显示我对 csproj
的更改,我对跟踪或提交补丁不感兴趣。
如何从我的个人存储库中删除这些文件的“跟踪”(但将它们保留在源中以便我可以使用它们),以便在我执行状态(或创建补丁)时看不到更改?
是否有正确/规范的方法来处理这种情况?
.csproj
文件的更改,这是任何项目的重要组成部分。对 .csproj.user
文件或任何 .Publish.XML
文件的更改我完全可以理解不跟踪,但我很好奇您为什么不想跟踪 .csproj
…
只需对要从修订控制中删除的每个文件调用 git rm --cached
就可以了。只要您的本地忽略模式是正确的,您就不会在 git status 的输出中看到这些文件。
请注意,此解决方案会从存储库中删除文件,因此所有开发人员都需要维护自己的本地(非修订控制)文件副本
为了防止 git 检测到这些文件中的更改,您还应该使用以下命令:
git update-index --assume-unchanged [path]
您可能想做的事情:(从下面的 @Ryan Taylor answer 开始)
这是告诉 git 你想要你自己的独立版本的文件或文件夹。例如,您不想覆盖(或删除)生产/暂存配置文件。 git update-index --skip-worktree <路径名>
完整答案在此 URL 中:http://source.kohlerville.com/2009/02/untrack-files-in-git/
有3个选项;你可能想要#3
这将为您保留本地文件,但会在其他任何人拉取时将其删除。 git rm --cached
grep
和 git ls-files
如果您执行 git update-index --assume-unchanged file.csproj
,git 将不会自动检查 file.csproj 的更改:这将阻止它们在您更改它们时以 git 状态出现。因此,您可以通过这种方式标记所有 .csproj 文件——尽管您必须手动标记上游存储库发送给您的任何新文件。 (如果您在 .gitignore
或 .git/info/exclude
中有它们,那么您创建的将被忽略)
我不完全确定 .csproj 文件是什么......如果它们与 IDE 配置类似(类似于 Eclipse 的 .eclipse 和 .classpath 文件),那么我建议它们永远不应该在全部。另一方面,如果它们是构建系统的一部分(如 Makefiles),那么显然它们应该——并且一种获取可选本地更改的方法(例如从 local.csproj 和 la config.mk)将很有用:将构建分为全局部分和局部覆盖。
git ls-files -v
将使用小写指示符显示假定未更改的文件(例如 h
而不是通常的 H
用于缓存文件)。
这是一个两步过程:
删除文件/文件夹的跟踪-但将它们保留在磁盘上-使用 git rm --cached 现在它们不会显示为“已更改”,但仍会在 git status -u 中显示为未跟踪的文件将它们添加到 .gitignore
接受的答案仍然对我不起作用
我用了
git rm -r --cached 。混帐添加。 git commit -m "修复.gitignore"
从 here 找到答案
忘记了 .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
添加要跟踪的文件
推送到您的仓库
正如其他答案中指出的那样,所选答案是错误的。
另一个问题的 answer 表明它可能是需要的跳过工作树。
git update-index --skip-worktree <file>
answer 链接到一篇文章 (http://fallengamer.livejournal.com/93321.html) 并引用该文章,并很好地总结了 --assume-unchanged 和 --skip-worktree 之间的区别,如下所示:
--assume-unchanged 假定开发人员不应该更改文件。此标志旨在提高 SDK 等不更改文件夹的性能。
--skip-worktree 当您指示 git 不要碰特定文件时很有用,因为开发人员应该更改它。例如,如果上游的主存储库托管了一些生产就绪的配置文件,并且您不想意外提交对这些文件的更改,那么 --skip-worktree 正是您想要的。
所有功劳归功于 borealid 的研究和回答。在这里包含此信息纯粹是为了方便他人。
--skip-worktree
用于将文件保留在存储库中但停止跟踪其更改。正如您的回答所说: --skip-worktree 当您指示 git 不要触摸特定文件时很有用,因为开发人员应该更改它
--assume-unchanged
和 --skip-worktree
具有相似的效果,但它们的目的完全不同。前者是通过欺骗 git 不检查特定文件来加快 git 性能,而后者是 忽略特定文件的未来更改,适用于运行时但必不可少的文件。
防止通过 git 监控文件或路径
git update-index --assume-unchanged [file-path]
并将其恢复使用
git update-index --no-assume-unchanged [file-path]
用于参考类似用例的存储库 https://github.com/awslabs/git-secrets
为了节省一些时间,您添加到 .gitignore 的规则可用于删除多个文件/文件夹,即
git rm --cached app/**/*.xml
或者
git rm --cached -r app/widgets/yourfolder/
ETC
很多人建议您使用 git update-index --assume-unchanged
。事实上,这可能是一个很好的解决方案,但只是在短期内。
您可能想要做的是:git update-index --skip-worktree
。
(您可能不想要的第三个选项是:git rm --cached
。它将保留您的本地文件,但会被标记为从远程存储库中删除。)
前两个选项之间的区别?
假设未更改是临时允许您隐藏文件中的修改。如果你想隐藏对文件所做的修改,修改文件,然后签出另一个分支,你必须使用 no-assume-unchanged 然后可能隐藏修改完成。
无论您签出哪个分支,skip-worktree 都会跟随您进行修改!
assume-unchanged
的用例
它假定不应修改此文件,并在执行 git status
时为您提供更清晰的输出。但是当签出到另一个分支时,您需要重置标志并在此之前提交或存储更改。如果您在激活此选项的情况下进行拉取,您将需要解决冲突并且 git 不会自动合并。它实际上只隐藏修改(git status
不会显示标记的文件)。
当我只想暂时停止跟踪更改 + 提交与 same 修改相关的一堆文件 (git commit -a
) 时,我喜欢使用它。
skip-worktree
的用例
您有一个设置类,其中包含您的朋友必须根据他们的设置相应地更改的参数(例如,包括密码)。
1:创建此类的第一个版本,填写您可以填写的字段并将其他字段留空/null。
2:提交并推送到远程服务器。
3: git update-index --skip-worktree MySetupClass.java
4:用你自己的参数更新你的配置类。
5:回去工作另一个功能。
无论分支如何,您所做的修改都将跟随您。警告:如果你的朋友也想修改这个类,他们必须有相同的设置,否则他们的修改会被推送到远程仓库。拉动时,文件的远程版本应覆盖您的文件。
PS:做一个或另一个,但不要同时做,因为你会有不良的副作用。如果你想尝试另一个标志,你应该先禁用后者。
要告诉 Git 不要跟踪对本地文件/文件夹的更改(意味着 git status 不会检测到对它的更改),请执行以下操作:
git update-index --skip-worktree path/to/file
并告诉 Git 再次跟踪对本地版本的更改(以便您可以提交更改),请执行以下操作:
git update-index --no-skip-worktree path/to/file
一行回答git update-index --assume-unchanged [path]
只要您有一个位于中央仓库和本地仓库中的文件,就可以使用它。您需要在该文件中进行更改,但不得暂存/提交到中央仓库。此文件不应添加到 .gitignore
。因为如果系统管理员引入文件中的新更改,高级开发人员需要分布在所有本地存储库中。
最佳示例:数据库连接的配置文件。在中央存储库中,您将拥有所有用户名、密码、主机、端口以及生产数据库服务器的值。但是在本地开发中,您应该只使用本地或任何其他开发数据库服务器(您的团队已经设置)。在这种情况下,您想在配置文件中进行更改,但不应该提交到中央仓库。
最好的
将 .gitignore 应用于现在/未来
此方法应用标准的 .gitignore 行为,不需要手动指定需要忽略的文件。不能再使用 --exclude-from=.gitignore 了:/ - 这是更新的方法: 一般建议:从一个干净的 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
如果您还需要从分支的提交历史记录中清除新忽略的文件或者如果您不希望从未来的拉取中删除新忽略的文件,请参阅this answer。
git rm --fileName
git ls-files
以确保文件已被删除或未跟踪
git commit -m "UntrackChanges"
git push
我假设您询问如何删除特定文件夹或 bin 文件夹中的所有文件,而不是单独选择每个文件。
您可以使用此命令:
git rm -r -f /<floder-name>\*
确保您位于该目录的父目录中。
此命令将递归地“删除”所有文件它们位于 bin/ 或 build/ 文件夹中。删除这个词我的意思是 git 会假装这些文件被“删除”并且这些文件不会被跟踪。 git 确实将这些文件标记为处于删除模式。
请确保您的 .gitignore 已为即将到来的提交做好准备。
Documentation : git rm
该问题可能是由操作顺序引起的。如果你先修改了.gitignore,然后git rm --cached xxx,你可能还要继续遇到这个问题。
正确解决方案:
git rm --cached xxx 修改了 .gitignore
订单不变!
.gitignore 修改后重新加载!
我假设您正在尝试从 git tacking 中删除单个文件。为此,我建议使用以下命令。
git update-index --assume-unchanged
前 - git update-index --assume-unchanged .gitignore .idea/compiler.xml
要忽略对目录中所有文件(某种类型)的任何更改,我必须结合其中一些方法,否则如果文件以前不存在,则会创建这些文件。
在下面,“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/
在这个 answer 中给出了一个几乎 git command-free 方法:
要忽略每个本地 repo 的某些文件:
创建一个文件 ~/.gitignore_global,例如通过在终端中触摸 ~/.gitignore_global。运行 git config --global core.excludesfile ~/.gitignore_global 一次。将要忽略的文件/目录路径写入 ~/.gitignore_global。例如modules/*.H,假定它在你的工作目录中,即$WORK_DIR/modules/*.H。
要忽略单个本地存储库的某些文件:
对 repo 中的文件 .git/info/exclude 执行上述第三步,即将要忽略的文件/目录路径写入 .git/info/exclude。例如modules/*.C,它会被假定在你的工作目录中,即$WORK_DIR/modules/*.C。
找了半天,想办法做到这一点。在 .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 && :
git ls-files | xargs git rm --cached
结合使用——这将从给定目录中的 git 索引中删除所有内容,而不会删除实际文件。git rm --cached -r <dir>
以递归方式作用于文件夹及其中的所有文件。