最终追溯性.gitignore(如何使Git完全/追溯性地现在忘记.gitignore中的文件)

愚蠢的

前言

这个问题试图消除关于追溯应用.gitignore的困惑,而不仅仅是针对当前/未来。1个

基本原理

我一直在寻找一种使我当前的.gitignore具有追溯力的方式,就像我在第一次commit中创建.gitignore一样

我正在寻找的解决方案:

  • 不会需要手动指定文件
  • 要求提交
  • 将追溯适用于所有分支的所有提交
  • 忽略工作目录中.gitignore指定的文件,而不删除它们(就像最初由根用户提交的.gitignore文件一样)
  • 将使用git,而不是BFG
  • 将适用于.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 rebasegit 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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何追溯和完全删除添加到.gitignore的文件和文件夹的痕迹

HPQC 10中的可追溯性矩阵

如何使Git“忘记”已跟踪但现在位于.gitignore中的文件?

我怎样才能让 Git“忘记”一个被跟踪但现在在 .gitignore 中的文件?

*〜在.gitignore文件中做什么?

查找不在.gitignore中的文件

'!' 不排除.gitignore中的文件

Gitignore文件中的正斜杠

在PhpStorm中显示.gitignore文件

Git:如何删除现在在gitignore中但之前已添加到仓库中的文件

如何使用.gitignore文件正确忽略git中的文件?

如何将自定义变量传递到用于调用函数的可追溯性承诺中?

Git-.gitignore中的提交文件

Git忽略父目录中的.gitignore文件

Git正在忽略不在gitignore中的文件

Git在.gitignore中添加被忽略的文件

Git push不会忽略.gitignore中的文件

Git如何从签出中忽略.gitignore中的文件

Silver Searcher:如何忽略.gitignore中的文件?

如何忽略.gitignore中的子文件?

github是否支持可追溯性?

无法提交不在 gitignore 文件中的文件

如何在忽略 .gitignore 的同时排除 Git 中的文件?

gitignore 文件中“.gitignore~”的可能用法是什么?

.gitignore 文件不起作用,并且 git status 仍然显示 .gitignore 中列出的文件(已解决)

忽略子目录中的gitignore文件

货物发布不会忽略 .gitignore 中的文件

爆炸似乎不排除.gitignore中的文件

无法忽略gitignore中的Eclipse特定文件