在git中,已经提交到并推送到远程的目录,如何忽略掉?

437 阅读4分钟

有些时候,我们一不小心把build目录也提交,甚至还推送了,后面怎么能删除掉它呢?

忽略已经提交到 Git 仓库并推送到远程的文件或目录需要一些步骤。仅仅在 .gitignore 中添加条目是不够的,因为那只会忽略尚未被跟踪的文件。要忽略已经被跟踪的文件或目录,你需要执行以下步骤:

  1. .gitignore 中添加你想忽略的目录或文件:

    如果你想忽略一个名为 example_directory/ 的目录,你可以在 .gitignore 文件中添加以下内容:

    example_directory/
    
  2. 从 Git 仓库中移除该目录或文件:

    执行以下命令:

    git rm --cached -r example_directory/
    

    这将会从 Git 仓库中移除该目录(但不会在你的本地文件系统中删除它)。

  3. 提交这些更改:

    git commit -m "Removed example_directory from Git tracking."
    
  4. 推送到远程仓库:

    git push
    

请注意,上述操作会从 Git 的历史记录中删除指定的目录或文件,并且下次克隆或拉取该仓库的用户不会得到这个目录或文件。但是,这不会改变旧的提交或历史记录。如果你需要彻底从 Git 历史记录中删除敏感信息,你需要考虑使用工具如 filter-branchBFG Repo-Cleaner。但这是一个更复杂的操作,可能需要额外的考虑和步骤。

现在我们再解释一下上面的那条命令git rm --cached -r example_directory/

这条命令用于从 Git 的索引中移除文件或目录,但在工作目录中保持它们不变。

  • git rm: 这是 Git 的命令,用于从工作目录和索引中移除文件。
  • --cached: 这个选项告诉 Git 只从索引中移除文件或目录,而不是从工作目录中删除它们。换句话说,使用 --cached,你的文件或目录在物理上仍然存在,但 Git 不再跟踪它们的更改。
  • -r: 这是递归的意思。当你处理目录时,你需要递归地处理其下的所有文件和子目录。这就是为什么我们使用 -r 选项的原因。
  • example_directory/: 这是你想从 Git 跟踪中移除的目录的名字。

执行该命令后,example_directory/ 不再被 Git 跟踪。但在你的文件系统中,它仍然存在,任何之前对该目录或其内容所做的更改都不会被 Git 考虑,直到你再次将其添加回 Git 跟踪。

这一步的目的是确保 Git 不再跟踪你想忽略的目录,同时保留在你的本地文件系统中的这些文件。这样,当你推送更改到远程仓库时,其他人克隆或拉取仓库不会看到这个目录,但它仍然存在于你的本地工作目录中。

再看下面几个FAQ:

  1. 为什么最后面有一个斜杠 (/)?

    在此上下文中,斜杠表示目录,强调你要从 Git 跟踪中移除的是一个目录,而不仅仅是一个名为 example_directory 的文件。但实际上,不加斜杠也会起作用,因为 git rm 会自动识别是目录还是文件,斜杠只是为了明确性。

  2. 如果没有 --cached 会怎么样?

    如果不使用 --cached 选项,那么 git rm 不仅会从 Git 的索引中移除文件或目录,还会在你的物理文件系统中删除它们。这意味着,你的文件或目录实际上会被删除,而不只是从 Git 跟踪中移除。

    例如:

    git rm -r example_directory/
    

    这会从 Git 索引中移除 example_directory/,并且在你的工作目录中完全删除它。

  3. git rmrm 有什么区别?

    • rm: 这是一个 shell 命令,用于从文件系统中删除文件或目录。当你使用 rm 删除一个文件或目录时,Git 还会认为这些文件/目录在索引中(除非你提交了这些更改)。
    • git rm: 这是一个 Git 命令,用于从 Git 的索引中移除文件或目录,并默认在你的物理文件系统中删除它们。但如上所述,如果使用 --cached 选项,那么文件/目录仍会保留在你的物理文件系统中,只是 Git 不再跟踪它们。

    简单来说,rm 只关心物理文件系统,而 git rm 则同时关心 Git 的索引和物理文件系统(除非使用 --cached)。