这个问题试图消除关于追溯应用.gitignore的困惑,而不仅仅是针对当前/未来。1个
我一直在寻找一种使我当前的.gitignore具有追溯力的方式,就像我在第一次commit中创建.gitignore一样。
我正在寻找的解决方案:
*.ext
!*special.ext
git rm --cached *.ext
git commit
这需要1.手动指定文件和2.额外的提交,当其他开发人员提取该文件时,将导致新忽略的文件删除。(它实际上只是一个git rm
-从git跟踪中删除的内容-但仅将文件保留在本地(您的)工作目录中。其他人git pull
之后将收到文件删除提交)
git filter-branch --index-filter 'git rm --cached *.ext'
尽管此操作确实可以追溯清除文件,但它1.要求手动指定文件,并且2.从本地工作目录中删除指定的文件,就像普通文件一样git rm
(其他人也是如此git pull
)!
1在SO上有许多类似的帖子,其定义的问题少于特定的定义,而答案则较不准确。看到这个问题,有23个答案,根据标准的“忘记”定义,接受大约4k票的答案是不正确的,正如一个最正确的答案所指出的那样,只有2个答案包括必需的 git filter-branch
命令。
这21分问题的答案 是 标记为前一个的副本,但问题是有不同的定义(忽略VS忘了),因此,尽管答案可能是适当的,它是不重复的。
这个问题是我所寻找的最接近的问题,但是答案并非在所有情况下都有效(带有空格的路径...),并且可能比创建外部变量要复杂一些。 -repository .gitignore文件并将其复制到每个提交中。
编辑:我最近找到了git-filter-repo。这可能是一个更好的选择。自己研究一下基本原理和分支陷阱可能是一个好主意,但是它们不会影响下面的用例。
这种方法使混帐完全忘记或忽略的文件(过去/现在/未来),但并没有从工作目录(远程即使再拉)删除任何东西。
这种方法需要的使用/.git/info/exclude
(首选)或一个预先存在 .gitignore
于所有有文件提交到可以忽略/忘记。1个
此方法避免了在接下来的2个操作中从其他开发人员计算机上删除新忽略的文件git pull
强制执行Git的所有方法都会事后忽略行为,从而有效地重写了历史记录,因此对在此过程之后可能被拉回的任何公共/共享/协作存储库都有重大影响。3
一般建议:从干净的仓库开始-提交的所有东西,在工作目录或索引中没有任何待处理的东西,然后进行备份!
此外,评论/修订历史的这个答案(和修订历史的这个问题)可能是有用/启发。
#commit up-to-date .gitignore (if not already existing)
#these commands must be run on each branch
#these commands are not strictly necessary if you don't want/need a .gitignore file. .git/info/exclude can be used instead
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
#if using .git/info/exclude, it will need to be modified per branch run, if the branches have differing (per-branch) .gitignore requirements.
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
最后,遵循本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 reset HEAD^
3重写git历史记录也会更改提交哈希值,这将对将来从公共/共享/协作存储库中提取的内容造成严重破坏。在执行此回购之前,请充分了解其后果。该GitHub指南指定了以下内容:
告诉你的合作者底垫中,不合并,他们创造了旧的(污点)仓库的历史掉任何分支机构。一次合并提交可能会重新引入您刚刚遇到的麻烦的部分或全部历史记录。
不影响远程回购的替代解决方案是git update-index --assume-unchanged </path/file>
或git update-index --skip-worktree <file>
,可以在此处找到其示例。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句