接受的答案不会“使Git 忘记文件...”(历史上)。它只会使git 忽略当前/将来的文件。
这种方法使git 完全忘记了被忽略的文件(过去 /现在/将来),但是没有从工作目录(远程即使再拉)删除任何东西。
这种方法需要的使用/.git/info/exclude
(首选)或一个预先存在 .gitignore
于所有有文件提交到可以忽略/忘记。1个
所有强制执行git的方法都会事后忽略行为,从而有效地重写了历史记录,因此对在此过程之后可能被拉出的任何公共/共享/协作存储库都有明显的影响。2
一般建议:从干净的仓库开始 -提交的所有东西,在工作目录或索引中没有待处理的东西,然后进行备份!
此外,评论/ 修订历史的这个答案(和修订历史的这个问题)可能是有用/启发。
#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
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
最后,遵循本GitHub指南的其余部分(从第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因为/.git/info/exclude
可以使用上面的说明将其应用于所有历史提交,所以有关将.gitignore
文件放入需要历史提交的文件的详细信息可能超出了此答案的范围。我希望一个适当的.gitignore
人参与root提交,好像这是我做的第一件事。其他人可能不在乎,因为/.git/info/exclude
无论.gitignore
提交历史记录中存在什么内容,它们都可以完成相同的事情,并且即使在意识到后果的情况下,显然重写历史记录也是非常敏感的主题。。
FWIW,潜在方法可能包括git rebase
或git filter-branch
将外部 复制.gitignore
到每个提交中,例如该问题的答案
2通过提交独立git rm --cached
命令的结果来强制执行git事后忽略行为,这可能会导致在将来从强制推送的远程操作中删除新忽略的文件。--prune-empty
以下git filter-branch
命令中的标志通过自动删除以前的“删除所有忽略的文件”仅索引提交来避免此问题。重写git历史记录也会更改提交哈希,这将对公共/共享/协作存储库中的将来撤回造成严重破坏。在执行此回购之前,请充分了解其后果。该GitHub指南指定了以下内容:
告诉你的合作者底垫中,不合并,他们创造了旧的(污点)仓库的历史掉任何分支机构。一次合并提交可能会重新引入您刚刚遇到清除麻烦的部分或全部历史记录。
不影响远程回购的替代解决方案是git update-index --assume-unchanged </path/file>
或git update-index --skip-worktree <file>
,可以在此处找到其示例。
git clean -X
听起来很相似,但不适用于这种情况(当Git仍在跟踪文件时)。我正在为寻求解决方案而不遵循错误路线的任何人写这篇文章。