我在一个名为XXX的文件夹中有一个Git存储库,还有一个名为YYY的Git存储库。
我想将XXX存储库作为名为ZZZ的子目录导入到YYY存储库中,并将所有XXX的更改历史添加到YYY中。
之前的文件夹结构:
├── XXX
│ ├── .git
│ └── (project files)
└── YYY
├── .git
└── (project files)
文件夹结构后:
YYY
├── .git <-- This now contains the change history from XXX
├── ZZZ <-- This was originally XXX
│ └── (project files)
└── (project files)
这可以做到吗,或者我必须使用子模块?
Git仓库本身就有一个著名的实例,在Git社区中被统称为“有史以来最酷的合并”(以Linus Torvalds在给Git邮件列表中描述这次合并的电子邮件的主题行命名)。在这种情况下,gitk Git GUI现在是Git的一部分,实际上曾经是一个单独的项目。Linus设法将该存储库合并到Git存储库中
它出现在Git存储库中,就好像它一直是作为Git的一部分开发的一样,
所有的历史都保存完好
它仍然可以在旧的存储库中独立开发,只需通过git提取更改即可。
电子邮件包含了复制所需的步骤,但不适合胆小的人:首先,Linus写了Git,所以他可能比你我知道得多一些;其次,这是近5年前的事情了,Git从那时起已经有了很大的改进,所以现在可能要容易得多。
特别是,我猜现在人们会在这种特定情况下使用gitk子模块。
我当时在找-s他们的,当然,这个策略不存在。我的历史是我在GitHub上分叉了一个项目,现在由于某种原因,我的本地master不能与上游/master合并,尽管我没有对这个分支做任何本地更改。(真的不知道那里发生了什么——我猜上游在幕后做了一些肮脏的推动,可能吧?)
我最后做的是
# as per https://help.github.com/articles/syncing-a-fork/
git fetch upstream
git checkout master
git merge upstream/master
....
# Lots of conflicts, ended up just abandonging this approach
git reset --hard # Ditch failed merge
git checkout upstream/master
# Now in detached state
git branch -d master # !
git checkout -b master # create new master from upstream/master
所以现在我的master再次与upstream/master同步(你可以对任何其他分支重复上面的步骤,你也想进行类似的同步)。
根据这篇文章,使用子树对我来说是有效的,只转移了适用的历史。在这里发布,以防有人需要这些步骤(确保将占位符替换为适用于你的值):
在源存储库中将子文件夹拆分为一个新的分支
Git子树拆分——prefix=<source-path-to-merge> -b subtree-split-result
在你的目标repo合并在拆分结果分支
git remote add merge-source-repo <path-to-your-source-repository>
git fetch merge-source-repo
git merge -s ours --no-commit merge-source-repo/subtree-split-result
git read-tree --prefix=<destination-path-to-merge-into> -u merge-source-repo/subtree-split-result
验证您的更改并提交
git status
git commit
别忘了
通过删除子树拆分结果分支进行清理
git branch -D subtree-split-result
删除为从源repo获取数据而添加的远程
Git远程rm merge-source-repo
没有足够的代表给x-yuri的回答加上评论,但它工作得很漂亮,保存了历史。
我正在与两个工作的本地回购工作,并收到这个错误:
中止:拒绝破坏性地覆盖此后的回购历史
这看起来不像一个新的克隆体。
(预计新包装的回购)
请改用一个新的克隆体做手术。如果你想继续,那就用武力。
与其担心——force标志的含义,我先在本地克隆了这个repo:
cd tempDir
git clone <location of repo to be merged> --no-local
用这个新克隆的拷贝来执行x-尤里布置的一系列命令。
最后,在:git filter-repo——to-subdirectory-filter a中,a是你要导入的repo根文件夹的名称。