考虑以下场景:
我在自己的Git repo中开发了一个小型实验项目a。它现在已经成熟,我希望A成为更大的项目B的一部分,该项目有自己的大仓库。现在我想将A添加为B的子目录。
我如何将A合并为B,而不丢失任何方面的历史?
考虑以下场景:
我在自己的Git repo中开发了一个小型实验项目a。它现在已经成熟,我希望A成为更大的项目B的一部分,该项目有自己的大仓库。现在我想将A添加为B的子目录。
我如何将A合并为B,而不丢失任何方面的历史?
当前回答
如果您想将来自存储库B分支的文件放在存储库a的子树中,并保留历史记录,请继续阅读。(在下面的示例中,我假设我们希望回购协议B的主分支合并为回购协议A的主分支。)
在回购协议A中,首先执行以下操作以使回购协议B可用:
git remote add B ../B # Add repo B as a new remote.
git fetch B
现在我们在回购a中创建了一个全新的分支(只有一个提交),我们称之为new_b_root。生成的提交将包含在repo B的主分支的第一次提交中提交的文件,但这些文件放在名为path/to/B-files/的子目录中。
git checkout --orphan new_b_root master
git rm -rf . # Remove all files.
git cherry-pick -n `git rev-list --max-parents=0 B/master`
mkdir -p path/to/b-files
git mv README path/to/b-files/
git commit --date="$(git log --format='%ai' $(git rev-list --max-parents=0 B/master))"
解释:checkout命令的--孤儿选项从A的主分支检出文件,但不创建任何提交。我们可以选择任何提交,因为接下来我们无论如何都要清除所有文件。然后,在尚未提交(-n)的情况下,我们从B的主分支中选择第一个提交。(cherry pick保留了原始的提交消息,而直接签出似乎无法做到这一点。)然后我们创建一个子树,将所有来自repo B的文件放在那里。然后我们必须将cherry stick中引入的所有文件移动到子树中。在上面的示例中,只有一个README文件可以移动。然后我们提交B-repo根提交,同时,我们还保留原始提交的时间戳。
现在,我们将在新创建的new_B_root上创建一个新的B/master分支。我们称新分支为b:
git checkout -b b B/master
git rebase -s recursive -Xsubtree=path/to/b-files/ new_b_root
现在,我们将b分支合并为A/master:
git checkout master
git merge --allow-unrelated-histories --no-commit b
git commit -m 'Merge repo B into repo A.'
最后,您可以删除B个远程和临时分支:
git remote remove B
git branch -D new_b_root b
最终图形的结构如下:
其他回答
当您希望在一次提交中合并三个或更多项目时,请执行其他答案中所述的步骤(远程添加-f,合并)。然后,(软)将索引重置为旧头(没有合并)。添加所有文件(git-Add-A)并提交它们(消息“将项目A、B、C和D合并到一个项目中”)。这现在是master的提交id。
现在,使用以下内容创建.git/info/places:
<commit-id of master> <list of commit ids of all parents>
运行gitfilter分支--head^。。头头^2.头头^3.头。如果你有三个以上的分支,就加上同样多的头。。当你有树枝的时候,就把头伸过去。要更新标记,请追加--tag-namefilter cat。不要总是添加,因为这可能会导致某些提交的重写。有关详细信息,请参阅过滤器分支的手册页,搜索“移植物”。
现在,你的最后一次承诺与正确的父母相关。
几天来我一直在尝试做同样的事情,我使用的是git2.7.2。子树不会保留历史。
如果不再使用旧项目,可以使用此方法。
我建议你先在B分支机构工作,然后在该分支机构工作。
以下是没有分支的步骤:
cd B
# You are going to merge A into B, so first move all of B's files into a sub dir
mkdir B
# Move all files to B, till there is nothing in the dir but .git and B
git mv <files> B
git add .
git commit -m "Moving content of project B in preparation for merge from A"
# Now merge A into B
git remote add -f A <A repo url>
git merge A/<branch>
mkdir A
# move all the files into subdir A, excluding .git
git mv <files> A
git commit -m "Moved A into subdir"
# Move B's files back to root
git mv B/* ./
rm -rf B
git commit -m "Reset B to original state"
git push
如果您现在在分区A中记录任何文件,您将获得完整的历史记录
git log --follow A/<file>
这是帮助我做到这一点的帖子:
http://saintgimp.org/2013/01/22/merging-two-git-repositories-into-one-repository-without-losing-file-history/
给定命令是我建议的最佳解决方案。
git subtree add --prefix=MY_PROJECT git://github.com/project/my_project.git master
我稍微手动合并项目,这使我可以避免处理合并冲突。
首先,从另一个项目中复制文件,无论您需要什么。
cp -R myotherproject newdirectory
git add newdirectory
历史上的下一次拉力
git fetch path_or_url_to_other_repo
告诉git在上次获取的历史记录中合并
echo 'FETCH_HEAD' > .git/MERGE_HEAD
现在按您通常的方式提交
git commit
我今天必须按如下方式解决:项目A在bitbucket中,项目B在代码提交中。。这两个项目都是相同的,但必须将A到B的更改合并。(诀窍是在项目A中创建同名分支,与在项目B中相同)
git签出项目Agit远程删除原点git远程添加源项目Bgit结帐分行git加法*gitcommit-m“我们已经移动了代码”数字推送