考虑以下场景:

我在自己的Git repo中开发了一个小型实验项目a。它现在已经成熟,我希望A成为更大的项目B的一部分,该项目有自己的大仓库。现在我想将A添加为B的子目录。

我如何将A合并为B,而不丢失任何方面的历史?


当前回答

合并2个回购

git clone ssh://<project-repo> project1
cd project1
git remote add -f project2 project2
git merge --allow-unrelated-histories project2/master
git remote rm project2

delete the ref to avoid errors
git update-ref -d refs/remotes/project2/master

其他回答

如果两个存储库都有相同类型的文件(就像两个Rails存储库用于不同的项目),您可以将辅助存储库的数据提取到当前存储库中:

git fetch git://repository.url/repo.git master:branch_name

然后将其合并到当前存储库:

git merge --allow-unrelated-histories branch_name

如果您的Git版本小于2.9,请删除--允许不相关的历史记录。

在此之后,可能会发生冲突。例如,可以使用gitmergetool来解析它们。kdiff3只能与键盘一起使用,因此在读取代码时仅需几分钟,就会产生5个冲突文件。

记住完成合并:

git commit

我遇到了类似的挑战,但在我的情况下,我们在回购协议a中开发了一个版本的代码库,然后将其克隆到新的回购协议B中,用于新版本的产品。修复了回购协议A中的一些错误后,我们需要将更改FI到回购协议B中

向指向回购a的回购B添加远程(git remote add…)拉动当前分支(我们没有使用master修复错误)(git pull-remoteForRepabugFixBranch)将合并推送到github

工作愉快:)

我在使用merge时不断丢失历史记录,所以我最终使用了rebase,因为在我的情况下,两个存储库的不同程度足以避免每次提交时合并:

git clone git@gitorious/projA.git projA
git clone git@gitorious/projB.git projB

cd projB
git remote add projA ../projA/
git fetch projA 
git rebase projA/master HEAD

=>解决冲突,然后根据需要继续。。。

git rebase --continue

这样做会导致一个项目具有来自projA的所有提交,然后是来自projB的提交

要在B中合并a:

1) 在项目A中

git fast-export --all --date-order > /tmp/ProjectAExport

2) 在项目B中

git checkout -b projectA
git fast-import --force < /tmp/ProjectAExport

在这个分支中,执行所有需要执行的操作并提交它们。

C) 然后回到主节点,两个分支之间进行经典合并:

git checkout master
git merge projectA

git子树很好,但它可能不是您想要的。

例如,如果projectA是在B中创建的目录,在git子树之后,

git log projectA

仅列出一个提交:合并。合并项目的提交针对不同的路径,因此不会显示。

格雷格·休吉尔(Greg Hewgill)的答案最接近,但实际上并没有说明如何重写路径。


解决方案出奇地简单。

(1) 在A中,

PREFIX=projectA #adjust this

git filter-branch --index-filter '
    git ls-files -s |
    sed "s,\t,&'"$PREFIX"'/," |
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info &&
    mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE
' HEAD

注意:这将重写历史;你可能想先备份a。

注意Bene:如果在文件名或路径中使用非ascii字符(或白色字符),则必须修改sed命令中的替代脚本。在这种情况下,“ls files-s”生成的记录中的文件位置以引号开头。

(2) 然后在B中,运行

git pull path/to/A

瞧!在B中有一个projectA目录。如果运行git-log-projectA,您将看到a中的所有提交。


在我的例子中,我需要两个子目录,projectA和projectB。在这种情况下,我也执行了步骤(1)到B。