如何将一个git仓库导入到另一个新分支的仓库中

4

我已经阅读了多个类似的SO问题,但没有找到一个足够接近我的问题。

我有两个基于相同初始代码A的离线存储库。这些存储库已经各自发展:

存储库foo位于/home/foo/git/

        o--o--o A2
       /
A--o--o--o master 
    \
     o A1

位于 /home/bar/git/ 的代码库 bar

        o--------o--o A2
       /          \
A--o--o--o master  o--o--o A3
    \
     o--o--o A1

这个想法是将bar的所有内容导入到一个名为B的新分支bar上:

完成后,在foo上应该如下所示:

        o--o--o A2
       /
A--o--o--o master
 \  \      o--o--o B2
  \  o A1 /    \
   B--o--o B4   o--o--o B3
    \
     o--o--o B1

有没有一种简单的方法来做这件事?

例子

首先,我们想要像上面那样创建foobar

初始化示例:

#!/usr/bin/env bash

DUMMY=dummy

commit ()
{
  openssl rand -hex 3 >> $DUMMY
  git commit -m "$1" .
}

# Create foo
mkdir foo && cd $_ && git init
touch dummy && git add $DUMMY
git commit -m "0" .
git branch A
commit 1
git checkout -b A1
commit 2
git checkout master
commit 3
commit 4
git checkout head~1 -b A2
commit 5
commit 6
commit 7

# Create bar
cd ..
mkdir bar && cd $_ && git init
touch dummy && git add $DUMMY
git commit -m "0" .
git branch A
commit 1
git checkout -b A1
commit 2 && commit 3 commit 4
git checkout master
commit 5 && commit 6
git checkout head~1 -b A2
commit 7 && commit 8 && commit 9
git checkout head~1 -b A3
commit a && commit b && commit c

# Show foo and bar
cd ../foo
echo "foo:"
git log --all --graph --abbrev-commit --decorate --date=relative --format=format:'[%s]%d'

cd ../bar
echo "bar:"
git log --all --graph --abbrev-commit --decorate --date=relative --format=format:'[%s]%d'

这是针对 foo 的解决方案

* [7] (HEAD, A2)
* [6]
* [5]
| * [2] (A1)
| | * [4] (master)
| |/
|/|
* | [3]
|/
* [1]
* [0] (A)

对于 bar

* [9] (A2)
| * [c] (HEAD, A3)
| * [b]
| * [a]
|/
* [8]
* [7]
| * [3] (A1)
| * [2]
| | * [6] (master)
| |/
|/|
* | [5]
|/
* [1]
* [0] (A)

Svlasov的解决方案:

然后我尝试应用svlasov的解决方案。

cd ../bar
git remote add foo ../foo
git push foo A:B
git push foo A1:B1
git push foo A2:B2
git push foo A3:B3

* [9] (B2)
| * [c] (B3)
| * [b]
| * [a]
|/
* [8]
* [7]
* [5]
| * [3] (B1)
| * [2]
|/
* [1]
* [0] (B)
* [7] (HEAD, A2)
* [6]
* [5]
| * [2] (A1)
| | * [4] (master)
| |/
|/|
* | [3]
|/
* [1]
* [0] (A)

结果并不是我们期望的那样。此外,我们需要手动进行合并。我们能否自动完成它?


我认为这篇文章会有所帮助:http://gbayer.com/development/moving-files-from-one-git-repository-to-another-preserving-history/。 - john smith
@UtsabNeupane 不确定,因为在这个例子中,我们正在移动目录。在我的情况下,我有相同的源在相同的文件结构中。或者我没有理解这个例子。 - nowox
1个回答

2
这应该可以做到:
cd /home/bar/git/
git remote add foo /home/foo/git/
git push foo A1:B1
git push foo A2:B2
git push foo A3:B3

             o----o--o A1
            /      \
bar: o--o--o        o--o--o A2
         \
          o--o--o A3

           +

           o--o--o A1
          /
foo: o--o--o--o A2
       \
        o A3

          |
          V

             o--o--o A1
            /
foo: o--o--o--o A2
      \  \        o--o--o B1
       \  o A3   /    \
        o--o----o      o--o--o B2
         \
          o--o--o B3

使用你的具体示例

这是我的bar

enter image description here

这是我如何推送分支的:

git remote add foo ~/foo
git push foo origin:bar-origin
git push foo bar1:bar1
git push foo bar2:bar2
git push foo bar3:bar3
# I forgot to push master :(

然后是我之后的 foo

enter image description here

bar 图表很容易识别。更通用的解决方案是遍历所有分支,并为每个新分支名称添加一些前缀,就像我用 bar-origin 做的那样,但我更喜欢手工操作并完全掌控。


A:B是提交引用吗?其中A是目标(foo)上的根节点,B是其基础的裁剪树吗?如果是,我会收到错误 error: src refspec 477b142 does not match any. - nowox
Abarfoo 中现有的分支名称,B 是将在 foo 中创建的新分支名称。 - svlasov
我进行了一些测试,但它并没有真正起作用。在 foo 上,我没有得到所有的 bar 树,而只有分支 A 上的提交。 - nowox
你需要重复这个过程来处理其余的分支。但是每次都需要使用不同的分支名称,以避免覆盖现有的分支。 - svlasov
我更新了我的问题。同时我注意到你修改了你的答案。能否将其更加通用化?在现实世界中,“bar”存储库有很多分支... - nowox

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