Git 如何从现有回购协议为一个文件创建回购协议?

Git 如何从现有回购协议为一个文件创建回购协议?,git,Git,我在一个包含数百个其他文件的Git repo中编写了一个脚本(比如说make.bat)。make.bat的提交始终只涉及文件make.bat,但与其他文件的提交一起 原始回购(包含make.bat以及数百个其他文件,8次提交): 如何创建另一个只有文件make.bat及其所有历史记录的回购协议 新回购协议(仅包含一个文件make.bat,3次提交): 如果在任何make.batcommittes中都没有更改任何文件,那么只需复制项目文件夹,然后说 git rebase -i --root 在编

我在一个包含数百个其他文件的Git repo中编写了一个脚本(比如说
make.bat
)。
make.bat
的提交始终只涉及文件
make.bat
,但与其他文件的提交一起

原始回购(包含
make.bat
以及数百个其他文件,8次提交):

如何创建另一个只有文件
make.bat
及其所有历史记录的回购协议

新回购协议(仅包含一个文件
make.bat
,3次提交):


如果在任何
make.bat
committes中都没有更改任何文件,那么只需复制项目文件夹,然后说

git rebase -i --root
在编辑器中,删除表示不是
make.bat
committes的提交的所有行。保存并退出编辑器


现在您有了一个完全由
make.bat

历史组成的repo,如果在
make.bat
提交的任何文件中都没有更改,那么只需复制您的项目文件夹,然后说

git rebase -i --root
在编辑器中,删除表示不是
make.bat
committes的提交的所有行。保存并退出编辑器


现在,您有了一个完全由
make.bat

历史记录组成的repo,您只想忽略所有其他文件吗?如果是这样,只需将
*
添加到.gitignore文件的顶部,然后在另一行上添加
!make.bat
。这将忽略除make.bat之外的所有文件。您是否知道,目前提交的C、E和G也包含所有其他文件?您没有任何由“仅一个文件”组成的提交。Git不是这样工作的。当你说“make.bat的提交总是只涉及文件make.bat”时,那是错误的。@lxvs:那不是真的。每个提交都有每个文件的完整快照(或者更准确地说,提交的每个文件的完整快照,这似乎有点多余,但如果显式删除文件,新快照将缺少该文件)。我们倾向于通过让Git将提交与以前的提交进行比较来查看提交:在这里,Git只告诉我们在这两次提交之间更改的文件。这样可以减少噪音。但是每一次提交仍然包含每一个文件。当我们使用
git cherry pick
(git-rebase在内部是这样做的)时,git会做同样的比较:旧的还是新的,有什么变化?Git然后可以将相同的更改应用于其他提交;如果以“根本没有文件”为基数开始,并从其提交中复制“添加一个文件”操作,则会得到一个新的“一个文件”提交。如果您随后复制了“更改该文件中的一行”提交,那么您仍然会得到另一个新的提交,其中只有一个文件。看起来很有希望。这可能不是最快的答案,但请克隆您的存储库,然后使用bfg从历史记录中删除所有不是
make.bat
的文件。是否要忽略所有其他文件?如果是这样,只需将
*
添加到.gitignore文件的顶部,然后在另一行上添加
!make.bat
。这将忽略除make.bat之外的所有文件。您是否知道,目前提交的C、E和G也包含所有其他文件?您没有任何由“仅一个文件”组成的提交。Git不是这样工作的。当你说“make.bat的提交总是只涉及文件make.bat”时,那是错误的。@lxvs:那不是真的。每个提交都有每个文件的完整快照(或者更准确地说,提交的每个文件的完整快照,这似乎有点多余,但如果显式删除文件,新快照将缺少该文件)。我们倾向于通过让Git将提交与以前的提交进行比较来查看提交:在这里,Git只告诉我们在这两次提交之间更改的文件。这样可以减少噪音。但是每一次提交仍然包含每一个文件。当我们使用
git cherry pick
(git-rebase在内部是这样做的)时,git会做同样的比较:旧的还是新的,有什么变化?Git然后可以将相同的更改应用于其他提交;如果以“根本没有文件”为基数开始,并从其提交中复制“添加一个文件”操作,则会得到一个新的“一个文件”提交。如果您随后复制了“更改该文件中的一行”提交,那么您仍然会得到另一个新的提交,其中只有一个文件。看起来很有希望。这可能不是最快的答案,但克隆您的存储库,然后使用bfg从历史记录中删除所有不是
make.bat
的文件。更好的是
git reflog expire--all--expire=now
git gc--agressive--prune=now
之后。更好的是
git reflog expire--all--expire=now
git gc--agressive--prune=now
之后。
git rebase -i --root