Git Filter Repo可以从多个仓库中交织日期的提交记录创建单一代码库吗?

6
使用git-filter-repo,可以将 N 个存储库合并为单一存储库,并重新编写提交,以便按日期交织或“拉链”起来。目前,我正在测试每个存储库都有自己的子目录的两个存储库。操作后,每个存储库的提交位于彼此“顶部”,而不是交织在一起。我真正想要的是能够拥有完全线性的历史记录,根据作者数据排序,而没有添加合并提交。

history


rm -rf ___x
mkdir ___x
cd ___x

echo "creating the monorepo"
git init
touch "README.md"
git add .
git commit -am "Hello World!"

declare -A data
data=( 
    ["foo"]="https://github.com/bcanzanella/foo.git"
    ["bar"]="https://github.com/bcanzanella/bar.git"
)

for d in "${!data[@]}"; 
do  {
    REPO_NAME=$d
    REPO_REMOTE=${data[$d]}

    # since we can use a foo/bar as the repo identifier, replace the / with a -
    REPO_DIR_TMP="$(mktemp -d -t "${REPO_NAME/\//-}.XXXX")"

    echo "REPO REMOTE: $REPO_REMOTE"
    echo "REPO NAME: $REPO_NAME"
    echo "REPO TMP DIR: $REPO_DIR_TMP"
    echo ""

    echo "Cloning..."
    git clone "$REPO_REMOTE" "$REPO_DIR_TMP"

    echo "filtering into ..."
    cd $REPO_DIR_TMP && git-filter-repo --to-subdirectory-filter "$REPO_NAME"
    # cat .git/filter-repo/commit-map

    ## merge the rewritten repo
    git remote add "$REPO_NAME" "$REPO_DIR_TMP"

    echo "fetching..."
    git fetch "$REPO_NAME"

    echo "merging..."
    git merge --allow-unrelated-histories "$REPO_NAME/master" --no-edit

    ## delete the rewritten repo
    echo "Removing temp dir $REPO_DIR_TMP..."
    rm -rf "$REPO_DIR_TMP"

    echo "Removing remote $REPO_NAME..."
    # git remote rm "$REPO_NAME"

    echo "$REPO_NAME done!"
} 
done

1
这个 - https://dev59.com/81gR5IYBdhLWcg3wtfLX#41190478 - 看起来是一个可能的解决方案,但我自己没有尝试过。 - tmr232
1
在将修订版应用于分支时重新排序可能会很容易地导致冲突。 - eftshift0
1个回答

3
强调eftshift0的评论:rebase和重写历史可能导致提交按照看似荒谬的时间顺序排序。
如果你确信所有的提交都是有序的(例如:父提交的提交日期总是早于其子提交的提交日期),那么你可以生成正确的提交列表以在git rebase -i脚本中使用。
[编辑]经过思考,这可能足以满足您的用例:
使用--date-order查看您的仓库历史记录:
git log --graph --oneline --date-order

如果提交的顺序符合您的期望,您可以使用git log生成一个rebase -i序列脚本:

# --reverse   : 'rebase -i' asks for entries starting from the oldest
# --no-merges : do not mention the "merge" commits
# sed -e 's/^/pick /' : use any way you see fit to prefix each line with 'pick '
#        (another valid way is to copy paste the list of commits in an editor,
#         and add 'pick ' to each line ...)
git log --reverse --no-merges --oneline --date-order |\
  sed -e 's/^/pick /' > /tmp/rebase-apply.txt

然后重新定义您的存储库的完整历史记录:

git rebase -i --root

在编辑器中,复制/粘贴您使用第一个命令创建的脚本,保存并关闭。
希望您能够得到一个非冲突的统一历史记录。

有趣的解决方案,我没有想到通过编程创建一个有序的提交集来进行变基。 - brianc

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