如何使Git“忘记”已跟踪但现在位于.gitignore中的文件?
git
正在跟踪一个文件,但是现在该文件在.gitignore
列表中。
但是,该文件在编辑后一直以git status
显示。 您如何迫使git
完全忘记它?
#1楼
如果由于其他人可能需要而无法git rm
跟踪的文件(警告,即使您 git rm --cached
,当其他人获得此更改时,其文件也会在其文件系统中删除)。 这些通常是由于配置文件覆盖,身份验证凭据等导致的。请查看https://gist.github.com/1423106了解人们解决该问题的方式。
总结一下:
- 让您的应用程序查找被忽略的文件config-overide.ini,并在已提交的文件config.ini上使用它(或者,查找〜/ .config / myapp.ini或$ MYCONFIGFILE)
- 提交文件config-sample.ini并忽略文件config.ini,根据需要使用脚本或类似文件复制该文件。
- 尝试使用gitattributes clean / smudge magic来为您应用和删除更改,例如,将配置文件作为替代分支的签出进行涂抹,并清洁配置文件作为HEAD的签出。 这是棘手的东西,我不建议新手使用。
- 将配置文件保留在专用于它的部署分支上,该分支永远不会合并到master。 当您要部署/编译/测试时,您可以合并到该分支并获取该文件。 除了使用人工合并策略和Extra-git模块外,这实质上是污迹/清除方法。
- 反建议:不要使用假设不变,它只会以眼泪结束(因为git自欺欺人会导致不好的事情发生,例如您的更改永远丢失)。
#2楼
将其移出,提交,然后再移回。这在过去对我有用。 可能有一种“ gittier”方式来完成此任务。
#3楼
将文件移动或复制到安全位置,以免丢失。 然后git rm文件并提交。 如果恢复到较早的提交之一或尚未删除该文件的另一个分支,该文件仍将显示。 但是,在以后的所有提交中,您将不再看到该文件。 如果文件在git中忽略,则可以将其移回文件夹,而git将看不到它。
#4楼
我通过使用git filter-branch实现了这一点。 我使用的确切命令来自手册页:
警告 :这将从您的整个历史记录中删除该文件
git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD
该命令将重新创建整个提交历史记录,在每次提交之前执行git rm
,因此将删除指定的文件。 不要忘了运行该命令,因为它会丢失之前备份。
#5楼
.gitignore
将阻止将未跟踪的文件添加(不add -f
)到git跟踪的文件集中,但是git将继续跟踪任何已经被跟踪的文件。
要停止跟踪文件,您需要将其从索引中删除。 此命令可以实现。
git rm --cached <file>
如果要删除整个文件夹,则需要递归删除其中的所有文件。
git rm -r --cached <folder>
从主修订版中删除文件将在下一次提交时发生。
警告:虽然这不会从本地删除物理文件,但会在下一个git pull
上从其他开发人员计算机删除文件。
#6楼
下面的一系列命令将删除Git索引中的所有项(而不是工作目录或本地存储库中的所有项),然后在遵守git忽略的同时更新Git索引。 PS。 索引=缓存
第一:
git rm -r --cached .
git add .
然后:
git commit -am "Remove ignored files"
#7楼
git update-index为我完成了这项工作:
git update-index --assume-unchanged <file>
注意:该解决方案实际上独立于.gitignore
因为gitignore仅适用于未跟踪的文件。
编辑:自从发布此答案以来,已经创建了一个新选项,应该优先使用。 您应该使用--skip-worktree
,用于用户不想再提交的已修改跟踪文件,并保持--assume-unchanged
性能,以防止git检查大跟踪文件的状态。 有关更多详细信息,请参见https://stackoverflow.com/a/13631525/717372 ...
git update-index --skip-worktree <file>
#8楼
Matt Fear的回答是最有效的恕我直言。 以下仅是PowerShell脚本,适用于Windows中的脚本,仅用于从其git repo中删除与排除列表匹配的文件。
# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles = gc .gitignore | ?{$_ -notmatch "#"} | ?{$_ -match "\S"} | % {$ignore = "*" + $_ + "*"(gci -r -i $ignore).FullName}
$ignoreFiles = $ignoreFiles| ?{$_ -match "\S"}# Remove each of these file from Git
$ignoreFiles | % { git rm $_}git add .
#9楼
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"
这将获取被忽略文件的列表,并将其从索引中删除,然后提交更改。
#10楼
我总是使用此命令删除那些未跟踪的文件。 Unix风格的单行干净输出:
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
它列出了所有忽略的文件,用引号代替每行输出,以处理内部带有空格的路径,并将所有内容传递给git rm -r --cached
从索引中删除路径/文件/目录。
#11楼
什么对我不起作用
(在Linux下),我想使用此处的帖子建议ls-files --ignored --exclude-standard | xargs git rm -r --cached
ls-files --ignored --exclude-standard | xargs git rm -r --cached
方法。 但是,(某些)要删除的文件的名称中带有嵌入式换行符/ LF / \\n
。 两种解决方案都没有:
git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached
应付这种情况(获取有关找不到文件的错误)。
所以我提供
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
它使用ls-files的-z
参数和xargs的-0
参数安全/正确地满足文件名中的“讨厌”字符。
在手册页git-ls-files(1)中 ,它指出:
不使用-z选项时,路径名中的TAB,LF和反斜杠字符分别表示为\\ t,\\ n和\\\\。
所以我认为如果文件名中包含任何这些字符,则需要我的解决方案。
编辑:我被要求添加---像任何git rm
命令---必须在其后进行提交以使删除永久git commit -am "Remove ignored files"
,例如git commit -am "Remove ignored files"
。
#12楼
更新您的
.gitignore
文件-例如,将您不想跟踪的文件夹添加到.gitignore
。git rm -r --cached .
–删除所有跟踪的文件,包括有用和不需要的文件。 只要您保存在本地,您的代码就将是安全的。git add .
–除了.gitignore
文件外,所有文件都将重新添加。
给@AkiraYamamoto的帽子提示,以指向正确的方向。
#13楼
我认为,也许git不能完全忽略文件,因为它具有概念性( “快照,无差异”部分 )。
例如,在使用CVS时,不会出现此问题。 CVS将信息存储为基于文件的更改的列表。 CVS的信息是一组文件,并且每个文件随时间所做的更改。
但是,每次您提交或保存项目状态时,在Git中,它基本上都会拍下当时所有文件的样子,并存储对该快照的引用。 因此,如果添加一次文件,该文件将始终存在于该快照中。
这2篇文章对我有帮助:
git假定未更改vs skip-worktree以及如何使用Git忽略跟踪文件中的更改
如果已跟踪文件,则在此基础上执行以下操作:
git update-index --skip-worktree <file>
从这一刻起,此文件中的所有本地更改将被忽略,并且不会转到远程。 如果在远程更改文件,则在git pull
时会发生冲突。 藏匿将无法正常工作。 要解决此问题, 请将文件内容复制到安全的地方,然后执行以下步骤:
git update-index --no-skip-worktree <file>
git stash
git pull
文件内容将被远程内容替换。 将您所做的更改从安全的地方粘贴到文件中,然后再次执行:
git update-index --skip-worktree <file>
如果每个与项目一起工作的人都将执行git update-index --skip-worktree <file>
,则应该没有关于pull
问题。 每个开发人员都有自己的项目配置时,此解决方案适用于配置文件。
每次在远程上更改文件后,每次执行此操作都不太方便,但是可以防止远程内容覆盖它。
#14楼
BFG是专为从Git存储库中删除不需要的数据(例如大文件或密码)而设计的,因此它具有一个简单的标志,可以删除任何大的历史(不在您当前提交的文件)文件:'--strip-blobs-大于
$ java -jar bfg.jar --strip-blobs-bigger-than 100M
如果您想按名称指定文件,也可以这样做:
$ java -jar bfg.jar --delete-files *.mp4
BFG比git filter-branch快10-1000倍,并且通常更容易使用-请查看完整的使用说明和示例以获取更多详细信息。
资料来源: https : //confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html
#15楼
如果您不想使用CLI并在Windows上运行,则非常简单的解决方案是使用TortoiseGit ,它在菜单中具有“删除(保持本地)”操作,效果很好。
#16楼
在以下情况下使用此:
1.您要取消跟踪许多文件,或者
2.您更新了gitignore文件
来源连结: http : //www.codeblocq.com/2016/01/Untrack-files-already-add-to-git-repository-based-on-gitignore/
假设您已经将一些文件添加/提交到git存储库,然后将它们添加到.gitignore;中。 这些文件仍将存在于您的存储库索引中。 本文我们将看到如何摆脱它们。
步骤1:提交所有更改
在继续之前,请确保所有更改都已提交,包括.gitignore文件。
步骤2:从存储库中删除所有内容
要清除您的仓库,请使用:
git rm -r --cached .
- rm是删除命令
- -r将允许递归删除
- –cached仅从索引中删除文件。 您的文件仍然在那里。
rm
命令可能无法原谅。 如果您想事先尝试它的功能,请添加-n
或--dry-run
标志以进行测试。
步骤3:重新添加所有内容
git add .
步骤4:提交
git commit -m ".gitignore fix"
您的存储库是干净的:)
将更改推送到您的遥控器,以查看更改是否也在那里生效。
#17楼
如果已经提交DS_Store
:
find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch
通过以下方式忽略它们:
echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global
最后,提交!
#18楼
在最新的git (撰写本文时为v2.17.1)中, 这不再是问题 。
.gitignore
最终会忽略跟踪但已删除的文件。 您可以通过运行以下脚本自行测试。 最终的git status
语句应报告“没有要提交的内容”。
# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore# Remove the file and commit
git rm file
git commit -m "removed file"# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status
#19楼
我喜欢JonBrave的回答,但是我的工作目录杂乱无章,可以提交-a让我有些害怕,所以这是我做的事情:
git config --global alias.exclude-ignored'!git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached && git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m“新建gitignore并从索引中删除忽略的文件”'
分解:
git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git ls-files -z --ignored --exclude-standard | xargs -0 git stage
git stage .gitignore
git commit -m "new gitignore and remove ignored files from index"
- 从索引中删除忽略的文件
- .gitignore和您刚刚删除的文件
- 承诺
#20楼
依次执行以下步骤,就可以了。
1. 从目录/存储中 删除错误添加的文件。 您可以使用“ rm -r”(对于linux)命令或通过浏览目录将其删除。 或将它们移动到PC上的其他位置。[如果正在运行以进行移动/移动,则可能需要关闭IDE]
2.现在将文件/目录添加到gitignore
文件并保存。
3,现在使用这些命令将它们从git cache中 删除 (如果目录不止一个,则通过重复发出此命令将它们一个一个地删除)
git rm -r --cached path-to-those-files
4.now 执行 提交并推送 ,使用这些命令。 这将从git remote删除这些文件 ,并使git 停止跟踪那些文件。
git add .
git commit -m "removed unnecessary files from git"
git push origin
#21楼
复制/粘贴答案是git rm --cached -r .; git add .; git status
git rm --cached -r .; git add .; git status
该命令将忽略已经提交到Git存储库的文件,但是现在我们将它们添加到.gitignore
。
#22楼
特别是对于基于IDE的文件,我使用以下命令:
例如slnx.sqlite,我完全摆脱了它,如下所示:
git rm {PATH_OF_THE_FILE}/slnx.sqlite -f
git commit -m "remove slnx.sqlite"
请记住,其中一些文件存储了项目的某些本地用户设置和首选项(例如您打开的文件)。 因此,每次您在IDE中导航或进行某些更改时,该文件都会更改,因此它会将其检出并显示为未提交的更改。
#23楼
使用git rm --cached
命令不能回答原始问题:
您如何迫使
git
完全忘记[文件]?
实际上,此解决方案将导致在执行git pull
!时在存储库的其他每个实例中删除文件。
正确的方法,以力混帐忘掉一个文件被GitHub的记录在这里 。
我建议阅读文档,但是基本上:
git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --prune-empty --tag-name-filter cat -- --all
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
只需将full/path/to/file
替换full/path/to/file
的完整路径即可。 确保已将文件添加到.gitignore
。
您还需要(临时) 允许非快进推送到存储库 ,因为您正在更改git历史记录。
#24楼
接受的答案不会“使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 branchgit 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 branchgit 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 branchgit 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 commandgit 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 branchgit 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 remotegit 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/stashedgit reset FETCH_HEAD
脚注
1由于可以使用上述说明将/.git/info/exclude
应用于所有历史提交,因此有关将.gitignore
文件放入需要的历史提交中的详细信息可能超出了此答案的范围。 我希望在root提交中使用适当的.gitignore
,好像这是我做的第一件事。 其他人可能不在乎,因为/.git/info/exclude
可以完成相同的操作,而不管提交历史记录中的.gitignore
存在什么地方,并且显然,即使知道了后果 ,重写历史也是非常敏感的主题。
FWIW,可能的方法可能包括git rebase
或git filter-branch
,它将一个外部 .gitignore
复制到每个提交中,例如该问题的答案
2通过提交独立的git rm --cached
命令的结果来强制执行git事后忽略行为,这可能会导致在将来从强制推送的远程操作中删除新忽略的文件。 以下git filter-branch
命令中的--prune-empty
标志通过自动删除以前的“删除所有被忽略的文件”仅索引提交来避免此问题。 重写git历史记录也会更改提交哈希,这将对公共/共享/协作存储库中的将来撤回造成严重破坏 。 在执行此仓库之前,请充分了解其后果 。 该GitHub指南指定了以下内容:
告诉你的合作者底垫中 , 不合并,他们创造了旧的(污点)仓库的历史掉任何分支机构。 一次合并提交可能会重新引入您刚刚遇到清除麻烦的部分或全部历史记录。
不影响远程git update-index --assume-unchanged </path/file>
替代解决方案是git update-index --assume-unchanged </path/file>
或git update-index --skip-worktree <file>
,可以在此处找到示例。
如何使Git“忘记”已跟踪但现在位于.gitignore中的文件?相关推荐
- 【Git、GitHub、GitLab】三 Git基本命令之创建仓库并向仓库中添加文件
前两篇文章已经学会了Git的基本命令与创建仓库的命令,点击链接查看上一篇文章:[Git.GitHub.GitLab]二 Git基本命令之建立Git仓库,本篇文章就来创建一个有模有样的仓库.该仓库中的代 ...
- 【原创】Git删除暂存区或版本库中的文件
0 基础 我们知道Git有三大区(工作区.暂存区.版本库)以及几个状态(untracked.unstaged.uncommited),下面只是简述下Git的大概工作流程,详细的可以参见本博客的 ...
- 从Git存储库中删除文件而不从本地文件系统中删除它
我的初始提交包含一些日志文件. 我已将*log添加到我的.gitignore ,现在我想从我的存储库中删除日志文件. git rm mylogfile.log 将从存储库中删除文件,但也将从本地文件系 ...
- git忽略已被跟踪的文件
问题: 现在项目的根目录放了 .gitignore 文件,并且git远程仓库的项目根目录已经有了 logs文件夹. 由于每次本地运行项目,都会生成新的log文件,但是我并不想提交logs文件夹里面的内 ...
- Git --- 傻瓜内容跟踪器
介绍 Git --- The stupid content tracker, 傻瓜内容跟踪器.Linux 是这样给我们介绍 Git 的. Git 是用于 Linux 内核开发的版本控制工具.与常用的版 ...
- 如何使Git使用我选择的编辑器进行提交?
我更愿意在Vim中编写我的提交消息,但是它正在Emacs中打开它们. 如何配置Git始终使用Vim? 请注意,我要全局执行此操作,而不仅仅是针对单个项目. #1楼 而且,如果您正在与使用命令行的设计师 ...
- git更改已提交作者用户名
git更改已提交作者用户名 官网地址 配置作者用户名 为当前本地库单独配置作者信息 git config -f .git/config user.name "name" git c ...
- 如何使git接受自签名证书?
本文翻译自:How can I make git accept a self signed certificate? Using Git, is there a way to tell it to a ...
- git分支合并、撤销;git修改已push的commit信息; git 撤销操作;
git分支合并 1.分支代码提交 2.git branch 查询本地分支 3.git checkout 分支名1 切换分支到需要合并的分支上 4.git merge 分支名2 //选择要合并到 分支 ...
最新文章
- Java基础-OOP特性之封装、继承、多态、抽象
- easyUI droppable组件使用
- spring异常Unsatisfied dependency expressed through constructor parameter 0
- iOS开发系列-线程同步dispatch_barrier_async
- C++基本数据类型解惑
- 2018牛客网暑期ACM多校训练营(第十场)J	Rikka with Nickname(二分,字符串)
- canvas绘制图像image
- mysql讀取sql_MySQL数据库之python json及mysql读取json文件存sql等问题
- oracle 查询 约束
- C语言字符常量与常量定义
- ios 请在设置中打开相机权限_ios开发相机权限问题
- wps中论文标题编号的设置
- Java8 新特性之stream
- 记人生第一次参加Codeforces比赛
- HP34401a实现高精度温度测量
- FlutterWeb性能优化探索与实践
- AOP—面向切面编程
- 标准光源与色温、波长的关系
- 企业应用层面知识管理咨询方法
- SqlServer狂吃内存不释放解决办法
热门文章
- 关于MySQL事务和存储引擎10个FAQ(Frequently asked questions
- Android10.0 Binder通信原理(五)-Binder驱动分析
- java垃圾回收机制_乐字节Java|GC垃圾回收机制、package和import语句
- Flutter开发之Debug调试(十)
- swift_025(Swift 的自动引用计数(ARC)
- Dubbo下载-从missing artifactId说起
- js中json对象取键和值
- 通过微信公众号获取用户信息(java版)
- 苹果的浏览器safari无法识别 2016-1-1这样的日期,会返回Invalid Date
- linux update更新源