<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Gitignore on DK Blog</title><link>/tags/gitignore/</link><description>Recent content in Gitignore on DK Blog</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Mon, 08 Jun 2026 20:54:07 +0800</lastBuildDate><atom:link href="/tags/gitignore/index.xml" rel="self" type="application/rss+xml"/><item><title>已经 push 到远程的文件，再加入 .gitignore 还会生效吗？</title><link>/dkblog/021-gitignore-tracked-file/</link><pubDate>Mon, 08 Jun 2026 20:54:07 +0800</pubDate><guid>/dkblog/021-gitignore-tracked-file/</guid><description>&lt;img src="https://images.unsplash.com/photo-1618401471353-b98afee0b2eb?auto=format&amp;fit=crop&amp;w=900&amp;q=60" alt="Featured image of post 已经 push 到远程的文件，再加入 .gitignore 还会生效吗？" /&gt;&lt;h2 id="问题背景"&gt;&lt;a href="#%e9%97%ae%e9%a2%98%e8%83%8c%e6%99%af" class="header-anchor"&gt;&lt;/a&gt;问题背景
&lt;/h2&gt;&lt;p&gt;有时候我们会把某个本来不应该提交的文件 commit 并 push 到远程仓库，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本地配置文件：&lt;code&gt;application-local.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;IDE 配置文件：&lt;code&gt;.idea/workspace.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;临时生成文件：&lt;code&gt;debug.log&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;编译产物：&lt;code&gt;dist/&lt;/code&gt;、&lt;code&gt;target/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;机器相关文件：&lt;code&gt;.env.local&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;等发现问题时，第一反应通常是：把这个文件写进 &lt;code&gt;.gitignore&lt;/code&gt;，然后再提交一次 &lt;code&gt;.gitignore&lt;/code&gt;，是不是远程仓库里的那个文件就不会有了？&lt;/p&gt;
&lt;p&gt;答案是：&lt;strong&gt;不会。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 只对还没有被 Git 跟踪的文件生效。只要某个文件已经被 commit 过，它就是 tracked file。即使后来把它加入 &lt;code&gt;.gitignore&lt;/code&gt;，Git 仍然会继续跟踪它。&lt;/p&gt;
&lt;h2 id="直接结论"&gt;&lt;a href="#%e7%9b%b4%e6%8e%a5%e7%bb%93%e8%ae%ba" class="header-anchor"&gt;&lt;/a&gt;直接结论
&lt;/h2&gt;&lt;p&gt;如果文件已经被 commit 并 push 到远程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;只修改 &lt;code&gt;.gitignore&lt;/code&gt;，远程仓库里的文件不会自动删除&lt;/li&gt;
&lt;li&gt;只修改 &lt;code&gt;.gitignore&lt;/code&gt;，本地文件也不会停止被 Git 跟踪&lt;/li&gt;
&lt;li&gt;后续继续修改这个文件，&lt;code&gt;git status&lt;/code&gt; 里仍然可能看到它&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;想让 Git 以后不再跟踪它，常见做法是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把文件路径加入 &lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;用 &lt;code&gt;git rm --cached&lt;/code&gt; 把它从 Git 索引中移除，但保留本地文件&lt;/li&gt;
&lt;li&gt;commit 并 push 这次变更&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="正确处理方式远程删除本地保留"&gt;&lt;a href="#%e6%ad%a3%e7%a1%ae%e5%a4%84%e7%90%86%e6%96%b9%e5%bc%8f%e8%bf%9c%e7%a8%8b%e5%88%a0%e9%99%a4%e6%9c%ac%e5%9c%b0%e4%bf%9d%e7%95%99" class="header-anchor"&gt;&lt;/a&gt;正确处理方式：远程删除，本地保留
&lt;/h2&gt;&lt;p&gt;假设误提交的文件是：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-0-1"&gt;&lt;a class="lnlinks" href="#hl-0-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;config/local.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;先把它加入 &lt;code&gt;.gitignore&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-1-1"&gt;&lt;a class="lnlinks" href="#hl-1-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;config/local.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-2-1"&gt;&lt;a class="lnlinks" href="#hl-2-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm --cached config/local.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个命令的意思是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从 Git 索引中删除这个文件&lt;/li&gt;
&lt;li&gt;不删除你本地工作区里的真实文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接着提交并推送：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-3-1"&gt;&lt;a class="lnlinks" href="#hl-3-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-2"&gt;&lt;a class="lnlinks" href="#hl-3-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-3-3"&gt;&lt;a class="lnlinks" href="#hl-3-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .gitignore
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;stop tracking local config file&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;推送完成后，结果是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;远程仓库中这个文件会在新提交里被删除&lt;/li&gt;
&lt;li&gt;本地的 &lt;code&gt;config/local.yml&lt;/code&gt; 仍然存在&lt;/li&gt;
&lt;li&gt;因为 &lt;code&gt;.gitignore&lt;/code&gt; 已经包含它，后续 Git 不会再把它作为未跟踪文件提示出来&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="如果是目录怎么办"&gt;&lt;a href="#%e5%a6%82%e6%9e%9c%e6%98%af%e7%9b%ae%e5%bd%95%e6%80%8e%e4%b9%88%e5%8a%9e" class="header-anchor"&gt;&lt;/a&gt;如果是目录怎么办？
&lt;/h2&gt;&lt;p&gt;如果误提交的是整个目录，比如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-4-1"&gt;&lt;a class="lnlinks" href="#hl-4-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;logs/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 中写：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-5-1"&gt;&lt;a class="lnlinks" href="#hl-5-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;logs/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-6-1"&gt;&lt;a class="lnlinks" href="#hl-6-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-6-2"&gt;&lt;a class="lnlinks" href="#hl-6-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-6-3"&gt;&lt;a class="lnlinks" href="#hl-6-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-6-4"&gt;&lt;a class="lnlinks" href="#hl-6-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm --cached -r logs/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .gitignore
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;stop tracking logs directory&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这里需要加 &lt;code&gt;-r&lt;/code&gt;，因为 &lt;code&gt;logs/&lt;/code&gt; 是目录。&lt;/p&gt;
&lt;h2 id="为什么-gitignore-不会影响已跟踪文件"&gt;&lt;a href="#%e4%b8%ba%e4%bb%80%e4%b9%88-gitignore-%e4%b8%8d%e4%bc%9a%e5%bd%b1%e5%93%8d%e5%b7%b2%e8%b7%9f%e8%b8%aa%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;为什么 .gitignore 不会影响已跟踪文件？
&lt;/h2&gt;&lt;p&gt;Git 判断一个文件是否要纳入版本管理，大致可以分成两类：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;已经被 Git 跟踪的文件&lt;/li&gt;
&lt;li&gt;还没有被 Git 跟踪的文件&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 管的是第二类，也就是 untracked file。&lt;/p&gt;
&lt;p&gt;比如你新建了一个 &lt;code&gt;debug.log&lt;/code&gt;，它还没有被 &lt;code&gt;git add&lt;/code&gt;，这时 &lt;code&gt;.gitignore&lt;/code&gt; 里写了：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-7-1"&gt;&lt;a class="lnlinks" href="#hl-7-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;debug.log
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;那么 &lt;code&gt;git status&lt;/code&gt; 就不会再提示这个文件。&lt;/p&gt;
&lt;p&gt;但如果 &lt;code&gt;debug.log&lt;/code&gt; 之前已经被提交过，Git 的索引里已经有它了。此时 &lt;code&gt;.gitignore&lt;/code&gt; 不会让 Git 自动忘记它。你必须显式告诉 Git：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-8-1"&gt;&lt;a class="lnlinks" href="#hl-8-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm --cached debug.log
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;也就是把它从索引里移除。&lt;/p&gt;
&lt;h2 id="如何判断文件是否已经被-git-跟踪"&gt;&lt;a href="#%e5%a6%82%e4%bd%95%e5%88%a4%e6%96%ad%e6%96%87%e4%bb%b6%e6%98%af%e5%90%a6%e5%b7%b2%e7%bb%8f%e8%a2%ab-git-%e8%b7%9f%e8%b8%aa" class="header-anchor"&gt;&lt;/a&gt;如何判断文件是否已经被 Git 跟踪？
&lt;/h2&gt;&lt;p&gt;可以用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-9-1"&gt;&lt;a class="lnlinks" href="#hl-9-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git ls-files config/local.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果有输出，说明它已经被 Git 跟踪。&lt;/p&gt;
&lt;p&gt;也可以查看当前状态：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-10-1"&gt;&lt;a class="lnlinks" href="#hl-10-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果某个文件修改后显示在 &lt;code&gt;Changes not staged for commit&lt;/code&gt; 里，通常说明它已经是 tracked file。&lt;/p&gt;
&lt;p&gt;如果显示在 &lt;code&gt;Untracked files&lt;/code&gt; 里，说明它还没被跟踪，这时 &lt;code&gt;.gitignore&lt;/code&gt; 才能直接让它消失在状态列表中。&lt;/p&gt;
&lt;h2 id="常见误区"&gt;&lt;a href="#%e5%b8%b8%e8%a7%81%e8%af%af%e5%8c%ba" class="header-anchor"&gt;&lt;/a&gt;常见误区
&lt;/h2&gt;&lt;h3 id="误区一提交-gitignore-后远程文件会自动消失"&gt;&lt;a href="#%e8%af%af%e5%8c%ba%e4%b8%80%e6%8f%90%e4%ba%a4-gitignore-%e5%90%8e%e8%bf%9c%e7%a8%8b%e6%96%87%e4%bb%b6%e4%bc%9a%e8%87%aa%e5%8a%a8%e6%b6%88%e5%a4%b1" class="header-anchor"&gt;&lt;/a&gt;误区一：提交 .gitignore 后，远程文件会自动消失
&lt;/h3&gt;&lt;p&gt;不会。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 只是忽略规则，不是删除命令。远程文件是否删除，取决于后续提交里有没有把这个文件从 Git 索引中移除。&lt;/p&gt;
&lt;p&gt;需要配合：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-11-1"&gt;&lt;a class="lnlinks" href="#hl-11-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm --cached 文件路径
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="误区二git-rm-cached-会删除本地文件"&gt;&lt;a href="#%e8%af%af%e5%8c%ba%e4%ba%8cgit-rm-cached-%e4%bc%9a%e5%88%a0%e9%99%a4%e6%9c%ac%e5%9c%b0%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;误区二：git rm &amp;ndash;cached 会删除本地文件
&lt;/h3&gt;&lt;p&gt;不会。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git rm 文件路径&lt;/code&gt; 会删除本地文件，并把删除动作加入索引。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git rm --cached 文件路径&lt;/code&gt; 只从索引中移除文件，本地工作区文件会保留。&lt;/p&gt;
&lt;p&gt;这也是处理本地配置文件时最常用的方式。&lt;/p&gt;
&lt;h3 id="误区三gitignore-能阻止所有人提交这个文件"&gt;&lt;a href="#%e8%af%af%e5%8c%ba%e4%b8%89gitignore-%e8%83%bd%e9%98%bb%e6%ad%a2%e6%89%80%e6%9c%89%e4%ba%ba%e6%8f%90%e4%ba%a4%e8%bf%99%e4%b8%aa%e6%96%87%e4%bb%b6" class="header-anchor"&gt;&lt;/a&gt;误区三：.gitignore 能阻止所有人提交这个文件
&lt;/h3&gt;&lt;p&gt;不完全能。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt; 能让正常情况下的 &lt;code&gt;git add .&lt;/code&gt; 不再添加这个文件，但别人仍然可以强制添加：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-12-1"&gt;&lt;a class="lnlinks" href="#hl-12-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add -f config/local.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以如果是敏感文件，比如密钥、token、数据库密码，不能只依赖 &lt;code&gt;.gitignore&lt;/code&gt;，还要配合权限控制、密钥扫描、CI 检查等手段。&lt;/p&gt;
&lt;h2 id="如果已经把敏感信息-push-出去了怎么办"&gt;&lt;a href="#%e5%a6%82%e6%9e%9c%e5%b7%b2%e7%bb%8f%e6%8a%8a%e6%95%8f%e6%84%9f%e4%bf%a1%e6%81%af-push-%e5%87%ba%e5%8e%bb%e4%ba%86%e6%80%8e%e4%b9%88%e5%8a%9e" class="header-anchor"&gt;&lt;/a&gt;如果已经把敏感信息 push 出去了怎么办？
&lt;/h2&gt;&lt;p&gt;如果误提交的是普通文件，比如日志、编译产物、本地配置模板，用 &lt;code&gt;git rm --cached&lt;/code&gt; 通常就够了。&lt;/p&gt;
&lt;p&gt;但如果误提交的是敏感信息，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API token&lt;/li&gt;
&lt;li&gt;SSH 私钥&lt;/li&gt;
&lt;li&gt;数据库密码&lt;/li&gt;
&lt;li&gt;云厂商访问密钥&lt;/li&gt;
&lt;li&gt;生产环境配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那就不能只删除文件了，因为敏感内容仍然存在于 Git 历史提交中。&lt;/p&gt;
&lt;p&gt;正确处理顺序应该是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;立刻废弃或轮换已经泄露的密钥&lt;/li&gt;
&lt;li&gt;从当前版本中删除敏感文件&lt;/li&gt;
&lt;li&gt;把敏感文件加入 &lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如有必要，使用 &lt;code&gt;git filter-repo&lt;/code&gt; 或 BFG 清理历史记录&lt;/li&gt;
&lt;li&gt;强制推送清理后的历史&lt;/li&gt;
&lt;li&gt;通知所有协作者重新拉取或重新 clone 仓库&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;也就是说：&lt;strong&gt;删除当前版本里的文件，不等于删除历史里的泄露内容。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="如果我想远程保留本地以后不提交改动呢"&gt;&lt;a href="#%e5%a6%82%e6%9e%9c%e6%88%91%e6%83%b3%e8%bf%9c%e7%a8%8b%e4%bf%9d%e7%95%99%e6%9c%ac%e5%9c%b0%e4%bb%a5%e5%90%8e%e4%b8%8d%e6%8f%90%e4%ba%a4%e6%94%b9%e5%8a%a8%e5%91%a2" class="header-anchor"&gt;&lt;/a&gt;如果我想远程保留，本地以后不提交改动呢？
&lt;/h2&gt;&lt;p&gt;这是另一种需求。&lt;/p&gt;
&lt;p&gt;比如仓库里有一个默认配置文件：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-13-1"&gt;&lt;a class="lnlinks" href="#hl-13-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;config/dev.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;团队希望远程继续保留这个文件，但你本地会根据自己的环境改它，而且不想每次都在 &lt;code&gt;git status&lt;/code&gt; 里看到它。&lt;/p&gt;
&lt;p&gt;这种情况不适合靠 &lt;code&gt;.gitignore&lt;/code&gt;，因为文件已经是 tracked file。&lt;/p&gt;
&lt;p&gt;可以考虑：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-14-1"&gt;&lt;a class="lnlinks" href="#hl-14-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git update-index --skip-worktree config/dev.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;恢复跟踪时执行：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-15-1"&gt;&lt;a class="lnlinks" href="#hl-15-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git update-index --no-skip-worktree config/dev.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;还有一个类似命令：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-16-1"&gt;&lt;a class="lnlinks" href="#hl-16-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git update-index --assume-unchanged config/dev.yml
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;两者区别可以简单理解为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;assume-unchanged&lt;/code&gt; 更偏性能优化，告诉 Git 暂时假设这个文件没变&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skip-worktree&lt;/code&gt; 更偏本地覆盖场景，告诉 Git 尽量不要关心工作区里的这个文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;日常如果是“仓库保留默认配置，本地想长期改成自己的配置”，一般优先考虑 &lt;code&gt;skip-worktree&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;不过这个方案只影响你本地，不会影响其他人，也不会改变远程仓库。&lt;/p&gt;
&lt;h2 id="推荐实践"&gt;&lt;a href="#%e6%8e%a8%e8%8d%90%e5%ae%9e%e8%b7%b5" class="header-anchor"&gt;&lt;/a&gt;推荐实践
&lt;/h2&gt;&lt;p&gt;对于不应该提交的本地文件，推荐一开始就做好这几件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;把真实本地配置加入 &lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;提供一个可提交的模板文件，比如 &lt;code&gt;.env.example&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;文档里说明如何复制模板并填写本地值&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-17-1"&gt;&lt;a class="lnlinks" href="#hl-17-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-17-2"&gt;&lt;a class="lnlinks" href="#hl-17-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.env
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.env.local
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;仓库里提交：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-18-1"&gt;&lt;a class="lnlinks" href="#hl-18-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;.env.example
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这样既不会泄露本地敏感配置，也能让新人知道需要哪些环境变量。&lt;/p&gt;
&lt;h2 id="总结"&gt;&lt;a href="#%e6%80%bb%e7%bb%93" class="header-anchor"&gt;&lt;/a&gt;总结
&lt;/h2&gt;&lt;p&gt;已经 commit 或 push 过的文件，再加入 &lt;code&gt;.gitignore&lt;/code&gt; 并不会自动停止跟踪。&lt;/p&gt;
&lt;p&gt;如果你的目标是“远程删除，本地保留，以后不再跟踪”，使用：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-19-1"&gt;&lt;a class="lnlinks" href="#hl-19-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-19-2"&gt;&lt;a class="lnlinks" href="#hl-19-2"&gt;2&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-19-3"&gt;&lt;a class="lnlinks" href="#hl-19-3"&gt;3&lt;/a&gt;
&lt;/span&gt;&lt;span class="lnt" id="hl-19-4"&gt;&lt;a class="lnlinks" href="#hl-19-4"&gt;4&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm --cached 文件路径
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git add .gitignore
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git commit -m &lt;span class="s2"&gt;&amp;#34;stop tracking ignored file&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git push
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果是目录，加上 &lt;code&gt;-r&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt" id="hl-20-1"&gt;&lt;a class="lnlinks" href="#hl-20-1"&gt;1&lt;/a&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git rm --cached -r 目录路径
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果是敏感信息泄露，要先轮换密钥，再考虑清理 Git 历史。&lt;/p&gt;
&lt;p&gt;记住一句话就够了：&lt;strong&gt;&lt;code&gt;.gitignore&lt;/code&gt; 只负责忽略未跟踪文件，不能让 Git 自动忘记已经跟踪过的文件。&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>