【发布时间】:2014-03-05 19:41:09
【问题描述】:
我在 Github 上有一个包含文件夹和文件的现有存储库,我刚刚创建了四个新存储库。
我希望将现有存储库中的文件/文件夹分发到我刚刚创建的新存储库中。
有没有一种方法可以使用 GUI 或 CMD (Macbook) 做到这一点?
【问题讨论】:
我在 Github 上有一个包含文件夹和文件的现有存储库,我刚刚创建了四个新存储库。
我希望将现有存储库中的文件/文件夹分发到我刚刚创建的新存储库中。
有没有一种方法可以使用 GUI 或 CMD (Macbook) 做到这一点?
【问题讨论】:
我不知道是否有任何方法可以使用 GUI。
如果您要提取的内容包含在它们自己的文件夹中,则在命令行上非常简单。这里解释了一种使用git filter-branch --subdirectory-filter 的方法:
https://stackoverflow.com/a/12818479/955926
如果您的文件和文件夹没有很好地包含,或者与简单模式不匹配(即仅保留 *.py 文件等),一种方法(我称之为“整理”)就是继续运行简单的过滤器分支命令 - 在克隆上,而不是原来的! - 不断剥离它的一部分,直到你的历史只包含你想要的。
当然,我们总是希望能够验证我们在做什么。这将显示您的存储库中曾经存在的所有相对文件/文件夹路径的排序、唯一列表:
$ git log --pretty='format:' --name-only | grep -v '^$' | sort -u
假设在该列表中,您看到了您希望从历史记录中删除的 foo 和 bar/baz 文件夹(即删除位于 bar 和 foo 中的 baz):
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch foo bar/baz'
现在您可以运行之前的log 命令来验证这些链接是否不存在任何时间,并从那个较小的列表中选择更多的东西来删除。或者,您可以将每条路径都粘贴到对 filter-branch 的调用中。我只是感觉更好地采取更小的步骤并进行验证,就像我更愿意细粒度地提交一样。
Filter-branch 每次都进行一次备份,第二次运行会因为它的存在而停止。这就是-f 的用途。每次再次过滤时,您都会覆盖备份,但这没关系,因为您是在克隆上执行此操作(对!?),如果您搞砸了,您总是可以在新的克隆上再次执行此操作。
最后,您需要清除 refs/original/* 头,这将指向您在每次通过后过滤的分支的最后一个头。如果您过滤分支master 分支,您将有一个refs/original/refs/heads/master 文件指向master 的旧负责人,预过滤。当您强制执行下一次传球时,您将指向新传球。如果由于某种原因您想在每次过滤后保留指向每个备份的指针,只需在每次通过后在那些“原始”引用处放置一个分支或标记。或者在过滤之前删除一个标签/分支,或者只使用 reflog。
【讨论】: