我不小心将一些数据文件提交到本地存储库中,多次提交。我想从本地删除这些数据文件,而不撤消工作副本中的进度。
答案 0 :(得分:2)
有几种方法。
变基
一种选择是使用git rebase
。假设您的历史记录看起来像
... x -- o -- A -- B -- C <--(master)
在o
中发生不正确添加的地方(可能还有其他更改)。然后你可以说
git rebase -i master~5 master
之所以选择master~5
是因为在此示例中,它是一个引用o
的父代的表达式。 (当然,您可以根据回购的真实状态替换类似的表达式。)
这将显示一个带有TODO列表的文本编辑器。列表中的每一行将显示您的提交之一。找到提交o
的条目,并将该行上的第一个单词从pick
更改为edit
。然后保存并退出编辑器。
稍作处理后,将出现命令提示符。从索引中删除不需要的文件
git rm --cached file/that/shouldn't/be/committed
然后继续变基。发生冲突的唯一原因是,如果随后的提交也编辑了其中一个文件,在这种情况下,您将通过再次确保从索引中删除文件来解决冲突。
过滤器分支
如果您的“最近的历史记录”很复杂,则rebase会有一些问题。在上面的示例中,只有一个参考(master
)可以在其历史记录中“看到” o
,并且该参考文献回到o
的历史是线性的;所以重新设置就可以了。但是,如果还有其他分支或合并提交,则您可能应该尝试其他方法。
然后,您可以尝试将git filter-branch
与--index-filter
一起使用。您可以编写一个Shell脚本来执行git rm
命令。 (这与上面类似,但是您想说
git rm --cached --ignore-unmatch file/that/shouldn't/be/committed
假设您编写了此脚本并将其放在../index-filter.sh
处;并且您拥有
F -- G -- H
/ \
... x -- o -- A -- B -- C -- M <--(master)
\
D -- E <--(feature)
然后您可以说类似
git filter-branch --index-filter ../index-filter.sh -- --all ^master~5
在这种情况下选择master~5
是因为它指向x
(o
的父对象)。请注意,我们在^
之前放置了master~5
;这限制了重写以排除x
及其历史记录,因此您只需重写回o
。
由于某些原因,这可能很重要。
首先,如果您知道尚未推送o
,那么您就不会重写任何已共享的内容。 (无论如何,即使相同的路径更早出现,您也不需要更改,对吧?)
此外,通过限制重写的提交次数,可以帮助避免filter-branch
花费太长时间(这可能是一个运行时间很长的过程)。
还有其他选项,例如BFG回购清洁器;但对于您的用例而言,这些可能会显得过大了,我建议您首先尝试上述方法之一。
答案 1 :(得分:1)
如果将提交添加到上一次提交(git commit --amend
),则可以对其进行修改。
如果这是您的最后一次提交,请在添加文件之前从上一次提交创建分支,然后重新创建不包含新文件的提交,然后将其他提交重新置于新提交的基础上。
然后删除旧分支并重命名新分支。
答案 2 :(得分:-5)
推送提交,进行拉取,删除不需要的文件,提交,推送。 -_-