git 把不相关的历史放在一起

xmakbtuz  于 2023-09-29  发布在  Git
关注(0)|答案(2)|浏览(125)

由于某些原因(由于从SVN转换的复杂性),我有两个Git仓库:

  • git repo A包含截至2021年12月31日的所有历史
  • git repo B包含2022年1月1日以来的所有历史

现在,我想以一种我拥有整个历史的方式“合并”它们,即。首先是repo A的main分支,然后是repo B的main分支。
我还没有真正理解如何正确地做到这一点。

  • 如果我只是合并两个repo,那么我会在最后得到一个合并提交,这也是非常没有意义的,因为我不想让repo A的内容合并到B中,因为B是最近的。
  • 如果我在A的main上重基B的main,我得到了我想要的东西,但我不确定新生成的提交(来自repo B的提交)是否有我不想要的内容,例如。旧档案

有人能告诉我怎么做才合适吗?

u3r8eeie

u3r8eeie1#

创建工作存储库。

git init foo
cd foo

将这两个分支提取到存储库中。

git fetch <url_to_A> BranchA:BranchA
git fetch <url_to_B> BranchB:BranchB

将BranchB重定基到BranchA上,保留BranchB的日志图。

# WARNING, THIS MIGHT NOT WORK
git switch BranchA
git rebase --onto BranchA --root BranchB --empty=keep --rebase-merges

当前BranchB包含BranchA和旧BranchB的历史。
假设分支A的头是X,分支B的根是Y。上面的git rebase可能无法按预期工作。它仍然可以合并XY。我不知道你的分支是什么样的。如果它不起作用,这里有另一个方法,我相信可以工作。
获取2个分支后,首先在BranchA上创建一个等价的Y

git switch BranchA
git merge $(git commit-tree -p BranchA -m blah Y^{tree})
# reuse the commit message of Y
git commit --amend -C Y

然后将Y之后直到BranchB的头部的提交重定基到BranchA上,保留BranchB的原始日志图。

git rebase --empty=keep --rebase-merges --onto BranchA Y BranchB

第二种方法首先基于X创建一个提交Y'。它不会合并XY。它与Y具有相同的内容。git checkout Ygit checkout Y'生成相同的文件。

ldfqzlk8

ldfqzlk82#

你需要
1.从第二个历史的根提交创建一个新的提交:将第一个也是唯一的父节点设置为第一个历史的最后一次提交(git-replace(1))
1.重新计算第二个历史的图形(git-filter-repo(1))
然后你将有一个历史/图表。

# Assuming branches `a` and `b` from the two repositories
first_commit_b=$(git log --reverse --format='%H' b | head -1)
git replace --graft $first_commit_b a
# Third-party tool https://github.com/newren/git-filter-repo
git filter-repo --force
# Should show the whole history
git log b

演示

cd /tmp
tmp=$(mktemp -d)
cd $tmp
git init
git commit --allow-empty -m1
git commit --allow-empty -m2
git commit --allow-empty -m3
git switch --orphan other
git commit --allow-empty -m4
git commit --allow-empty -m5
git commit --allow-empty -m6
git replace --graft ':/4' ':/3'
git filter-repo --force
# Expected: 6
git log --oneline other | wc -l

相关问题