我一直在寻找一种使我当前的.gitignore可以追溯执行的方法,就像我在第一次提交中创建了.gitignore一样。
我正在寻找的解决方案:
*.ext
!*special.ext
git rm --cached *.ext
git commit
这需要手动指定文件和其他提交,当其他开发人员提取该文件时,将导致新忽略的文件删除。
git filter-branch --index-filter 'git rm --cached *.ext'
这需要手动指定文件,并从local工作目录中删除指定的文件!
1在SO上有许多类似的帖子,定义的问题少于特定的定义,而答案却不够准确。根据“忘记” this question with 23 answers的标准定义,请参见accepted answer with ~4k votes,其中as noted by one mostly-correct answer为不正确,并且只有2个答案包括必需的git filter-branch
命令。
This question with 21 answers被标记为上一个的重复项,但是对问题的定义不同(忽略还是忘记),因此尽管答案可能适当,但它是not重复项。
This question是我所寻找的最接近的东西,但是答案并非在所有情况下都有效(带有空格的路径...),并且可能比创建一个外部存储库.gitignore文件并将其复制到每个提交中。
此方法使git 完全忘记被忽略的文件(过去 / present / future),但是不是从工作目录中删除任何内容(即使从远程重新拉出)。
此方法需要使用
强制执行git的所有方法都会在事后忽略行为,从而有效地重写了历史记录,因此对于在此过程之后可能被拉出的任何公共/共享/协作存储库,其值为significant ramifications。/.git/info/exclude
(首选)OR和all中的[[pre-existing.gitignore
),这些提交的文件将被忽略/遗忘。 12
一般建议:从干净的仓库开始-提交的所有内容,工作目录或索引中没有待处理的内容,并进行备份!
此外,revision history的注释/ this answer(and revision history的this question可能有用/启发。
#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
#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --prune-empty flag in the following command
#this command must be run on each branch
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.
git commit -m "ignored index"
#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all
#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch
git ls-files --other --ignored --exclude-standard
最后,遵循this GitHub guide的其余部分(从第6步开始)其中包括有关以下命令的重要警告/信息。
git push origin --force --all git push origin --force --tags git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin git reflog expire --expire=now --all git gc --prune=now
从现在修改的远程仓库中提取的其他开发人员应进行备份,然后:
#fetch modified remote git fetch --all #"Pull" changes WITHOUT deleting newly-ignored files from working directory #This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed git reset FETCH_HEAD
脚注1因为可以使用上面的说明将
FWIW,可能的方法可以包括/.git/info/exclude
应用于所有历史提交,所以有关获取.gitignore
文件into需要其的历史提交的详细信息超出了范围这个答案。我希望在根提交中使用适当的.gitignore
,好像这是我所做的第一件事。其他人可能并不关心,因为无论/.git/info/exclude
在提交历史记录中的什么位置,.gitignore
都可以完成相同的事情,并且即使重写ramifications,显然重写历史也是一个[[very敏感主题。git rebase
或将externalgit filter-branch
复制到每个提交中的.gitignore
,如this question的答案>>2
通过提交独立的git rm --cached
命令的结果来强制执行git忽略行为,可能会在将来从强制推送的远程中拉出新忽略的文件deletion。下面的
合并他们根据您的旧(受污染的)存储库历史创建的任何分支。一次合并提交可能会重新引入您刚刚遇到的麻烦的部分或全部历史记录。--prune-empty
命令中的git filter-branch
标志通过自动删除以前的“删除所有忽略的文件”仅索引提交来避免此问题。重写git历史记录也会更改提交哈希,这将在将来从公共/共享/协作存储库中提取时wreak havoc。在进行此类回购之前,请先全面了解ramifications。 This GitHub guide指定以下内容:告诉您的协作者rebase,不不影响远程回购的替代解决方案是
git update-index --assume-unchanged </path/file>
或git update-index --skip-worktree <file>
,可以在here中找到其示例。