如何从 git 中的所有分支中删除名为 .css 的文件

How to remove a file named .css from all branches in git

我正在使用一个 git 存储库,其中有一个名为 .css 的文件。这会在 Windows 中检出时导致错误(但在 Linux 中它工作正常)。

如何从 git 的所有分支中删除此文件而不 不小心 删除 来自所有分支的所有 css 个文件?

以下是针对单个分支的操作​​方法,因为“所有分支”相当含糊,我将 automation/iteration 部分留在所有分支上,供您按自己喜欢的方式执行(我建议手动执行)如果你没有太多的分支有这个有问题的文件)

# First checkout the branch - WARNING - Note I use
# --force here to make sure `git status` is clean. 
# I'm relying on it later when doing `git add -A`.
# The --force flag will delete any uncommited local changes,
# so make sure you don't have any of those before running
# the following command
git checkout --force my_branch

# Now delete the `*.css` file. Note the single quotes, they
# are crucial to prevent the shell from doing expansion on the asterisk:
rm -- '*.css'

# Add "all" the changes (The deletion of the file should be the only change):
git add -A

# Now commit
git commit -m 'Removed evil *.css file'

# And push
git push origin my_branch

我没有故意使用 git rm(它在一个命令中结合了删除和 git add),因为我无法让它忽略 * 作为一个字符,它试图变聪明并删除项目中的所有 .css 个文件。编辑:请参阅 以了解在 git 命令

中指定文字星号的方法

How do I remove this file from all branches in git, without accidentally removing all css files from all branches?

显示一种方式;这是另一个。

注意:您并不是从分支中删除文件。您正在进行 缺少文件 的新提交,每个新提交都在某个特定分支上进行。这是一个重要的区别,因为现有的提交继续存在,并继续拥有该文件。任何现有的提交都不能被改变!您只需停止 using 那些提交。但是只要您仍然有那些较早的提交,任何在 Windows 上提取其中一个的尝试都会给您带来同样的胃灼热。1

要在分支上进行新的提交,我们(当然)将像往常一样使用 git commit。要在某个特定分支上 get,我们将像往常一样使用 git checkoutgit switch。正如 Omer 的回答,重要的是要确保您是从一个干净的设置开始的,尽管我不会在这里展示任何特定的方法来保证这一点。

给定一个分支列表,这些分支确实具有名称为 *.css 的文件,我们现在需要一个循环,用您喜欢的任何脚本语言编写。由于 Git 包含 sh(或 bash),这是一种非常强大的脚本语言,我将在这里使用它:

for name in br1 br2 br3 master; do
    git checkout $name &&
    git rm -f -- ":(literal)*.css" &&
    git commit -m "remove file named *.css" ||
    echo "failed to update branch $name"
done

:(literal) 前缀是 pathspec 的一部分,防止 git rm 扩展 *.css 以匹配所有 .css文件。这记录在 the gitglossary 中,尽管 well-hidden。 (这里的 -f 标志甚至在 Windows 上允许 git rm,尽管在 Windows 上 git checkout 步骤可能会失败,因此您必须修改 && 链。如果您在 Linux 系统上执行此操作,则此处不需要 -f 标志。)

您可以使用所有相关分支中的一个 git push 来跟进:

git push origin br1 br2 br3 master

例如。


1 可以在 Git 存储库中“重写历史”,这样不仅可以停止 使用 提交,但也完全停止将其保留在存储库中。这样做的缺点是每个 后续 提交的 commit-number (hash-ID) 也会更改,这样新的存储库就永远不会与原始存储库混合:如果它混合在一起,所有旧的提交都会立即返回。这有时是值得的,但并非经常如此,为此付出的痛苦是值得的。痛苦的程度取决于存在并具有原始提交的存储库副本的数量和重要性,pre-rewrite。