简体   繁体   English

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

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

I am working with a git repository that somehow has a file named .css in it.我正在使用 git 存储库,其中包含一个名为.css的文件。 This causes an error when checking out in Windows (but in Linux it works fine).这在 Windows 中签出时会导致错误(但在 Linux 中它工作正常)。

How do I remove this file from all branches in git , without accidentally removing all css files from all branches?如何从git的所有分支中删除此文件,而不会意外删除所有分支中的所有 css 文件?

Here's how you can do it for a single branch, since "all branches" is rather ambiguous, I left the automation/iteration part over all branches for you to do how you prefer (I suggest doing it manually if you don't have too many branches that have this problematic file)这是您如何为单个分支执行此操作的方法,因为“所有分支”相当模糊,我将自动化/迭代部分留在所有分支上,让您按照自己的喜好进行操作(如果您没有的话,我建议您手动进行许多分支都有这个有问题的文件)

# 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

I didn't use git rm (which combines deletion and git add in one command) on purpose because I couldn't get it to ignore the * as a character, it tried to get smart and delete all .css files in the project.我没有故意使用git rm (它结合了删除和git add在一个命令中添加),因为我无法让它忽略*作为一个字符,它试图变得聪明并删除项目中的所有.css文件。 EDIT: See torek's answer for a way to specify literal asterisks in git commands编辑:有关在 git 命令中指定文字星号的方法,请参阅torek 的答案

How do I remove this file from all branches in git, without accidentally removing all css files from all branches?如何从 git 中的所有分支中删除此文件,而不会意外删除所有分支中的所有 css 文件?

Omer's answer shows one way;奥马尔的回答显示了一种方式; here is another.这是另一个。

Note: you aren't removing the file from branches .注意:您没有从分支中删除文件 You are making new commits that lack the file , which each new commit made on some particular branch.您正在进行缺少文件的新提交,每个新提交都在某个特定分支上进行。 This is an important distinction because the existing commits continue to exist, and continue to have the file.这是一个重要的区别,因为现有的提交继续存在,并且继续拥有该文件。 No existing commit can ever be altered!任何现有的提交都不能更改! You simply stop using those commits.您只需停止使用这些提交。 But as long as you still have those earlier commits, any attempt to extract one of them on Windows will give you the same sort of heartburn.但只要你还有那些早期的提交,任何试图在 Windows 上提取其中一个的尝试都会给你同样的胃灼热。 1 1

To make a new commit on a branch, we will (of course) use git commit as usual.要在分支上进行新的提交,我们(当然)会像往常一样使用git commit To get on some particular branch, we will use git checkout or git switch as usual.进入某个特定的分支,我们将照常使用git checkoutgit switch As in Omer's answer, it's important to be sure that you are starting from a clean setup, though I won't show any particular method for guaranteeing that here.正如 Omer 的回答一样,重要的是要确保您从一个干净的设置开始,尽管我不会在这里展示任何特定的方法来保证这一点。

Given a list of branches that do have the file whose name is literally *.css , we now want a loop, written in whatever scripting language you prefer.给定一个分支列表,这些分支的文件名称实际上是*.css ,我们现在需要一个循环,用您喜欢的任何脚本语言编写。 Since Git includes sh (or bash) and that's a nice powerful scripting language, that's the one I would use here:由于 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

The :(literal) prefix is part of a pathspec and prevents git rm from expanding *.css to match all the .css files. :(literal)前缀是路径规范的一部分,可防止git git rm扩展*.css以匹配所有.css文件。 This is documented in the gitglossary , albeit rather well-hidden.这记录在gitglossary中,尽管隐藏得相当好。 (The -f flag here allows the git rm even on Windows, though on Windows the git checkout step would probably fail so you'd have to modify the && chain. If you are doing this on a Linux system you don't need the -f flag here.) (The -f flag here allows the git rm even on Windows, though on Windows the git checkout step would probably fail so you'd have to modify the && chain. If you are doing this on a Linux system you don't need the -f标志在这里。)

You can follow this up with a single git push of all the branches in question:您可以通过单个git push所有相关分支来跟进此操作:

git push origin br1 br2 br3 master

for instance.例如。


1 It is possible to "rewrite history" in a Git repository so as to not merely stop using a commit, but also stop keeping it in the repository at all. 1可以在 Git 存储库中“重写历史记录”,以便不仅停止使用提交,而且完全停止将其保留在存储库中。 The downside to doing this is that every subsequent commit's commit-number (hash-ID) also changes, such that the new repository can never be mixed with the original repository: if it is mixed together, all the old commits come right back.这样做的缺点是每个后续提交的提交编号(hash-ID)也会更改,因此新存储库永远不能与原始存储库混合:如果混合在一起,所有旧提交都会立即返回。 This is sometimes, but not all that often, worth the pain it takes to achieve.有时,但并非总是如此,值得付出努力来实现。 The amount of pain depends on the number and importance of copies of the repository that exist and have the original commits, pre-rewrite.痛苦的程度取决于存在并具有原始提交、预重写的存储库副本的数量和重要性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM