【问题标题】:How to rewrite Git history so that all files are in a subdirectory?如何重写 Git 历史记录以使所有文件都在子目录中?
【发布时间】:2014-04-05 21:07:36
【问题描述】:

我想将多个 Git 存储库(比如说 repoA 和 repoB)合并到一个新的存储库中。新存储库 (repoNew) 应在单独的子目录中包含每个 repoA 和 repoB。由于到目前为止我只在本地工作,所以我可以对存储库做任何我想做的事情。

在这种情况下,标准方法似乎是使用 git filter-branch 重写每个 repoA 和 repoB 的历史记录,使其看起来好像它们一直位于子文件夹中,然后将它们合并到 repoNew 中。

第一步是困扰我的事情。我很清楚How can I rewrite history so that all files, except the ones I already moved, are in a subdirectory?(Dan Moulding 的回答)等答案,这正是我想要的。

他提出的建议大致如下:

git filter-branch --prune-empty --tree-filter '
if [[ ! -e repoA ]]; then
    mkdir -p repoA
    git ls-tree --name-only $GIT_COMMIT | xargs -i mv {} repoA
fi'

结果应该是<repoA-GIT-base> 下的文件夹结构现在应该在<repoA-GIT-base>/repoA 中。然而,这种情况并非如此。上述命令在不同的提交时随机失败,并显示类似“mv: cannot move 'src' into 'repoA/src'

如前所述重写历史记录时如何避免那些错误的提交?

编辑:

您应该考虑将 .gitignore 从移动中排除,如下所示:

git filter-branch --prune-empty --tree-filter '
if [[ ! -e repoA ]]; then 
    mkdir -p repoA;
    git ls-tree --name-only $GIT_COMMIT | 
    grep -ve '^.gitignore$' | 
    xargs -i mv {} repoA; 
fi'

该命令似乎仍然随机失败。我尝试了几次,每次不同的提交都发生了“无法移动”的失败。我观察到,当我排除 .gitignore 时,通过所有提交的机会似乎增加了。我能够在所有三个不同的存储库上连续执行迁移而不会失败。当我为了好玩而再次尝试使用其中一个存储库的另一个一次性副本时,它又失败了。

由于据称使用某些文件的进程,我有时也难以删除我的一次性副本,因此问题可能与 Windows 7 文件访问处理有关,但我无法做出认真的假设在那里。

继续尝试直到成功当然是荒谬的,并且可能无法在具有大量提交的存储库上工作(我的只有大约 30 个)。

信息:我在 Windows 7 64 位企业版上使用 git-bash 和 git 版本 1.7.10.msysgit.1。

【问题讨论】:

  • 我将my answer 发布到昨天几乎相同的问题,只是作为实际粉碎回购的替代方案。
  • 这是我最初想要的方式,但我想保留单个文件历史记录。我还编辑了这个问题,因为我忘记了一些重要的事情,抱歉。

标签: git git-filter-branch git-rewrite-history


【解决方案1】:

我怀疑您正在寻找类似git subhistory 的东西。这是一个非常小的项目,似乎没有得到很好的维护,但它的设计也几乎完全符合您的描述。试试看!

【讨论】:

  • 非常好的项目。这个对我有用。我发现的唯一缺陷是它不能将一个子项目合并到一个空的仓库中(即将多个项目合并到一个新的空仓库中,每个项目都在一个子目录中),但是 git 本身在这方面是不稳定的。
【解决方案2】:

我已经编写了一个基于 libgit2 的程序来过滤 git 分支以用于另一个目的,我稍微改变了它来做你想要的。你可以试试。

在 github 的 git_filter 的 subdir 分支中:

https://github.com/slobobaby/git_filter/tree/subdir

我刚刚在我们的 100000 提交存储库上对其进行了测试,耗时 43 秒。

我编写程序是因为基于 git filter-branch 的解决方案需要几天到几周才能完成。

示例配置过滤“测试”存储库并将所有内容放在“测试”子目录中 - 您可以更改它以执行您想要的操作。

【讨论】:

    猜你喜欢
    • 2015-08-04
    • 2011-05-01
    • 2020-05-30
    • 1970-01-01
    • 2020-11-07
    • 2019-05-05
    • 2010-12-19
    • 1970-01-01
    相关资源
    最近更新 更多