将Git仓库合并到子目录中出现错误

7
我已经查看了几个关于此问题的线程。 合并多个git仓库 合并名称带空格的多个git仓库 我还查看了git filter-branch页面。

更新

我已经改为使用两个脚本的系统:

#!/bin/bash
git filter-branch --index-filter '~/doit.sh' HEAD

和 doit.sh

#!/bin/bash
git ls-files -s | \ 
    sed "s-\t-&data/perl_modules/-" | \ 
    GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info && \
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"

这样做避免了之前的错误,但现在出现了以下问题(路径已替换为[...]):
Rewrite c35e4ef0626fb2045f57fa5b605e7663b8d06196 (1/10977)mv: cannot stat `[...]/.git-rewrite/t/../index.new': No such file or directory
index filter failed: ~/doit.sh

当我运行时

ls-files- s | sed ... | git update-index ...

我得到了应该生成的索引文件。当我将doit.sh文件更改为输出sed的结果而不是将其传输到git update-index时,它似乎产生了正确的输出... 似乎在--index-filter下运行时git update-index根本没有创建文件...

再次更新:

当我将

mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"

改为

mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE" || true

第一个mv失败了,但是所有其他的(到目前为止)都可以工作。


所有这一切都在这个脚本中达到了顶峰:
git filter-branch --index-filter \
    'git ls-files -s | sed "s-\t\"*-&data/perl_modules/-" |
            GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                    git update-index --index-info &&
     mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD

理论上,这个脚本应该将仓库中的所有文件推送到data/perl_modules/目录下,并重写历史记录,以使文件一直存在于该目录下。但是我遇到了以下错误:
fatal: ambiguous argument 'ls-files': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

我不确定该如何继续,我对脚本的理解不够深入以进行调试,它直接从git filter-branch手册中获取。

我已经尝试过在手动将文件移动到子目录之前和之后执行此操作,以防需要移动文件或不需要移动文件。


1
Brett Randall 现在向 Git 邮件列表提交了一个补丁,可以在 http://thread.gmane.org/gmane.comp.version-control.git/270407 进行检查。 - Philip Oakley
2个回答

15

有几个问题。

1) git filter-branch --index 过滤器没有正确使用 '...'。

我不确定为什么会这样,是 git-filter 的 bug,还是环境问题?谁知道呢。但我通过将所有内容移出 '...' 并放入脚本文件中来修复它。然后在 '' 中调用了该脚本。

git filter-branch --index-filter '~/doit.sh' HEAD

还有doit.sh:

#!/bin/bash

git ls-files -s | \ 
    sed "s-\t-&data/perl_modules/-" | \ 
    GIT_INDEX_FILE="$GIT_INDEX_FILE.new" git update-index --index-info

mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE" || true

2)第一个提交是空的,所以没有index.new需要移动

这个Git仓库是使用git-svn从svn导入的。因此,第一个提交完全为空,只是简单地表示svn repo的初始化。因此,没有移动文件,也没有需要移动的index.new。通过向mv命令添加|| true来解决了这个问题。请注意,如果多个mv命令失败,则存在其他问题。


如果第一个提交存在问题,用第二个提交的SHA2代替“HEAD”会更好(在我看来)。 - rufo
1
@rufo 正如我在其他地方评论的那样,痛苦地发现用 REV2..HEAD 替换 HEAD 不是一个通用的解决方案。 - Ryan
4
对我来说,解决方法是添加 if [ -f "$GIT_INDEX_FILE.new" ]; then mv...EX_FILE"; fi -- 由于某种原因,在 svn 中有一个合法的提交(在一个 build.info 文件上),但在 git svn 克隆后没有被包含到 git 中。而且,出于某种原因,删除空提交并没有捕获到这个提交。 - Ryan
1
@Ryan,你能告诉我你把它放在哪里了吗?我也遇到了完全相同的问题,真是令人沮丧。 - user4964330
1
如果 [ -f "$GIT_INDEX_FILE.new" ]; then mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"; fi - Patrick Beard

1

看起来你在一些多行断点处缺少了反斜杠。


尝试将所有内容转换为一行,以避免使用\,但问题仍然存在。 - Exodist
其他反斜杠符号怎么样?你尝试转义它们了吗?此外,“”可能会引起问题。从比你现在的脚本更简单的脚本开始,并逐渐增加复杂性(使用\和)。 - Adam Dymitruk
有意思,我以前没有像这样遇到过filter-branch的问题。你在#git irc频道上问过那些人了吗?我通常在那里得到很好的帮助。同时,我会尝试自己重新创建这个。 - Adam Dymitruk
是的,Shell 可以有不同的解释和转义。尝试省略脚本文件。只专注于更新索引无法工作的问题。做一些非常简单的事情来练习它。 - Adam Dymitruk
1
我已经完全解决了我的问题。由于我的声誉,我无法在另外几个小时内发布答案。我有一个非常漂亮和详细的解释所有问题和解决方案,并将在允许时发布它们。 - Exodist
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接