首先,很抱歉问这个问题。关于它的主题已经很多了。但我和他们在一起运气不好。我对git不熟悉并没有多大帮助。
我正在将一个文件夹从一个git repo移动到另一个(已经存在)。例如
repo-1
---- dir1
---- dir2
---- dir3
---- dir-to-move
---- dir5
repo-2
---- dir1
---- dir2
---- dir3
最后,我希望回购看起来像
repo-1
---- dir1
---- dir2
---- dir3
---- dir-to-move
---- dir5
repo-2
---- dir1
---- dir2
---- dir3
---- dir-to-move
i、 e.在一段时间内,dir to move将存在于两个回购中。但最终我会将最新的更改迁移到repo-2,并删除dir以从repo-1移动。
我最初的研究让我相信我需要使用filter分支。例如
How to move files from one git repo to another preserving history using git format-patch
and git am
升
从那以后,我了解到“子树”取代了这种方法。然而,它并没有达到我的预期。我想我能做点什么
在repo-1工作区中
git subtree split -P dir-to-move -b split
将split分支向下过滤到只有dir才能移动,这就是历史。然后在repo-2工作区中
git remote add repo-1 repo-1-url.git
git subtree add --prefix dir-to-move split
这确实会移动代码。它还包括历史
例如
cd repo-2
git log
显示来自repo-1的提交
但是
cd repo-2
git log dir-to-move
仅显示“Add dir to move from commit…”
i、 e.包含历史记录,但在检查特定文件/目录时不显示。
我怎样才能正确地做到这一点?
9条答案
按热度按时间xxls0lw81#
我帮不了你
git subtree
,但有了filter-branch
这是可能的。首先,您需要创建一个包含源分支和目标分支的公共存储库。这可以通过在“源”旁边添加一个新的“远程”并从新的远程获取来完成。
在源分支上使用
filter-branch
到rm -rf
所有目录(dir-to-move
除外)。之后,您将拥有一个提交历史记录,该历史记录可以完全重新设置基址或合并到目标分支中。我认为最简单的方法是从源分支cherry-pick
所有非空提交。这些提交的列表可以通过运行git rev-list --reverse source-branch -- dir-to-move
获得当然,如果
dir-to-move
的历史是非线性的(已经包含合并提交),那么它将不会被cherry-pick保留,因此可以使用git merge
。创建公共存储库的示例:
过滤器分支示例
目标主控器中的樱桃拾取示例
elcex8rz2#
FWIW,经过多次迭代后,以下内容对我有效。
将这两个存储库克隆到临时工作区。
现在切换到目标存储库并从源获取所有内容。
以上步骤假设主分支同时用于源和目标。但是,标记和分支被忽略。
ugmeyewa3#
使用
git subtree
确实可以做到这一点。在repo-1中创建子树:
split
分支现在只包含dir-to-move
目录。现在需要将分支从repo-1拉到repo-2中的分支。如果repo-2碰巧是一个新的存储库(例如,就在
git init
之后),只需 checkout 一个没有历史记录的分支并从repo-1中提取即可。但是,如果repo-2是一个已经提交的现有repo(如本问题中的情况),则需要从repo-2中的孤立分支合并:
9cbw7uwe4#
我将
dir-to-move
移动到repo 2
的方法。首先在新位置克隆repo 1
,然后cd到m1n 3o1p文件夹。在我的例子中,我将文件夹从repo 1
分支develop
移动到repo 2
,其中develop
还不存在。每行的说明:
1.清理所有与
dir-to-move
无关的提交,删除该文件夹之外的所有文件,移动根文件夹repo 1
中的所有内容。从git docs:只查看与给定子目录相关的历史记录。结果将包含该目录(并且仅包含该目录)作为其项目根目录
1.您仍然指向源
repo 1
url1.将当前文件夹的源url替换为指向
repo 2
1.检查URL是否已正确更新
1.将(本例中新创建的)
develop
分支推送到repo 2
现在,您可以克隆或提取
repo 2
存储库。您将在repo 2
文件夹下拥有dir-to-move
的内容以及预期的相关历史记录。gudnpqoy5#
另一种解决方案是使用
git filter-branch
官方推荐的git-filter-repo。在我关于如何push commits affecting a given path to a new origin?的回答中找到一个完整的示例,包括windows用户的安装提示
2fjabf4q6#
我最喜欢的解决方案是http://blog.neutrino.es/2012/git-copy-a-file-or-directory-from-another-repository-preserving-history/,我已经使用多年了。然而,它似乎正在从谷歌搜索中消失,所以我担心它有一天会消失,因此我在这里复制它:
lxkprmvk7#
您甚至可以通过在本地删除除
dir-to-move
之外的所有目录(通过这种方式,无需使用fitler-branch
),然后拉到repo-2
来对repo-1
进行提交。注:确保
git
版本为2.9
或更高,以便使用--allow-unrelated-histories
选项o2g1uqev8#
git:在保留历史记录的同时将文件夹从一个存储库移动到另一个存储
qzwqbdag9#
哑解决方案手动解决方案(如果所有其他解决方案都失败):
1.从第一个存储库下载所有文件
1.创建新的回购
1.将第二个存储库克隆到磁盘。
1.打开要保留的第一个回购文件(新结构)
1.将更改推至第二个回购。
1.确认你有你想要的
1.从第一个存储库中删除您不想要的文件/文件夹。
你当然失去了可追溯性。。。