将Git仓库的内容移动到另一个仓库并保留历史记录

281

我正在尝试使用以下命令将一个存储库(repo1)的内容移动到另一个现有的存储库(repo2):

git clone repo1
git clone repo2
cd repo1
git remote rm origin
git remote add repo1
git push

但它没有起作用。我查阅了一个类似的帖子,但我只找到了一个移动文件夹而不是其内容的方法。


你想把repo1的内容作为repo2上的一个分支,还是作为master的一部分,这样两个repo的文件夹都存在于你的工作目录中? - Chronial
我想将它作为主程序的一部分移动。 - Mario
5
这篇教程非常棒!http://www.smashingmagazine.com/2014/05/19/moving-git-repository-new-server/ - Idemax
不是重复的,这是一个不同的问题 - Liam
2
对于GitHub用户,您可以通过https://github.com/new/import导入另一个存储库。 - Noam Manos
15个回答

441

我认为你正在寻找的命令是:

cd repo2
git checkout master
git remote add r1remote **url-of-repo1**
git fetch r1remote
git merge r1remote/master --allow-unrelated-histories
git remote rm r1remote

之后,repo2/master将包含来自repo2/masterrepo1/master的所有内容,并且还将拥有它们两者的历史记录。


1
Chronial,上面的命令不起作用了!它没有复制历史记录。 - Mario
2
好的,现在它可以工作了。我使用了以下命令: cd repo2, git remote rm origin, git remote add origin repo1的url, git fetch r1remote, git push origin master。 - Mario
3
@Chronial 有没有办法将repo1的代码提取/合并到repo2的特定目录中?目前,它正在提取repo2根目录中的所有内容。 - abhijithda
5
最简单的解决方案是在进行合并之前,将“repo1”中的所有内容移动到一个子文件夹(在“repo1”内部)中。 - Chronial
请注意,--allow-unrelated-histories 是在 git-2.9.0 中引入的,旧版本的 git 不需要该选项(例如 centos 7 :D)。 - Samveen
显示剩余12条评论

146

这里完美地描述了:https://www.smashingmagazine.com/2014/05/moving-git-repository-new-server/

首先,我们需要将现有存储库中的所有远程分支和标签拉取到本地索引中:

git fetch origin

我们可以检查是否有任何缺失的分支需要创建本地副本:

git branch -a

使用我们新仓库的SSH克隆URL,在现有本地仓库中创建一个新的远程仓库:

git remote add new-origin git@github.com:manakor/manascope.git

现在,我们已经准备好将所有本地分支和标签推送到名为new-origin的新远程仓库:

git push --all new-origin 
git push --tags new-origin

让new-origin成为默认远程源:

git remote rm origin
将new-origin重命名为origin,以便它成为默认远程版本库:

将new-origin重命名为origin,以便它成为默认远程版本库:

git remote rename new-origin origin

12
可以确认这个操作会复制整个历史记录和标签。非常好,谢谢。 - Alex
5
如果新来源没有任何提交,它将正常工作。然而,如果新来源中有任何提交,本文提到的方法将不能按预期工作。 - caot
你需要使用 git checkout BranchName 命令切换分支,然后再用 git push --all new-origin 命令将分支推送到远程仓库。非常感谢。 - Raad Altaie
1
将所有分支获取到本地,然后添加远程:https://dev59.com/ymkv5IYBdhLWcg3w1kSr#21189710 - marcuse
如果您已经使用了LFS,似乎这个功能无法正常工作。 - YaP

57

如果您想保留现有的分支和提交历史记录,这是我成功实践过的一种方法。

git clone --mirror https://github.com/account/repo.git cloned-repo
cd cloned-repo
git push --mirror {URL of new (empty) repo}

# at this point only remote cloned-repo is correct, local has auto-generated repo structure with folders such as "branches" or "refs"
cd ..
rm -rf cloned-repo
git clone {URL of new (empty) repo}
# only now will you see the expected user-generated contents in local cloned-repo folder

# note: all non-master branches are avaialable, but git branch will not show them until you git checkout each of them
# to automatically checkout all remote branches use this loop:
for b in `git branch -r | grep -v -- '->'`; do git branch --track ${b##origin/} $b; done

现在,假设您想在一段时间内保持源代码库和目标代码库同步。例如,当前远程代码库仍有活动,您希望将其转移到新的/替换代码库。

git clone -o old https://github.com/account/repo.git my-repo
cd my-repo
git remote add new {URL of new repo}

要拉取最新更新(假设您没有本地更改):

git checkout {branch(es) of interest}
git pull old
git push --all new

注意:我还没有使用子模块,所以如果您使用了它们,可能需要额外的步骤。


1
这对我来说非常简单易行。我认为它应该是被选中的答案。如果你有60个分支,这就是正确的方法。 - rickfoosusa
有用的内容包括提及远程分支和获取它们的命令。 - Paul
能否在不使用本地磁盘的情况下,将一个远程仓库中的镜像克隆到另一个远程仓库? - Pradeep

24

这个方法成功地将我的本地仓库(包括历史记录)移动到我的远程 github.com 仓库中。在 GitHub.com 上创建新的空仓库后,我按照下面第三步的 URL 使用方法,效果非常好。

git clone --mirror <url_of_old_repo>
cd <name_of_old_repo>
git remote add new-origin <url_of_new_repo>
git push new-origin --mirror

我在这里找到了:https://gist.github.com/niksumeiko/8972566


2
这是让原始存储库最简单的方法,它还会复制所有分支。 - Guillermo
2
这也会复制所有的标签。 - raven
1
这是从一个git深度克隆到另一个git的最佳方法。 - Nischal Revooru
1
很棒的答案,它按预期工作。 - Kris

23
如果代码已经由Git进行跟踪,那么最简单的方法就是将新的存储库设置为你要推送到的"origin"。

如果代码已被Git跟踪,则将新存储库设置为要推送到的“origin”即可。

cd existing-project
git remote set-url origin https://clone-url.git
git push -u origin --all
git push origin --tags

1
我犯了一个错误,删除了原始仓库远程并添加了新的仓库远程,但没有复制提交历史记录。因此,我在原始仓库上所做的所有更改都在新仓库中丢失了。这个方法非常有效,新仓库包含了我所有的更改。干杯,伙计! - Yohanelly

22

镜像仓库

根据@Dan-Cohn的回答,Mirror-push是在这里最好的选择。 这是我用于迁移仓库的工具:

1. 打开 Git Bash。

2. 创建仓库的裸克隆。

$ git clone --bare https://github.com/exampleuser/old-repository.git

3. 将镜像推送到新存储库。

$ cd old-repository.git
$ git push --mirror https://github.com/exampleuser/new-repository.git

4. 删除你在步骤1中创建的临时本地代码库。

$ cd ..
$ rm -rf old-repository.git

参考和致谢:https://help.github.com/en/articles/duplicating-a-repository


问题是如何“移动”,而不是“迁移”。您的答案似乎是将存储库镜像,以便原始存储库继续存在?(我不确定“镜像”是什么意思) - ekkis
如果我想将旧的仓库放到新仓库的特定文件夹中,应该如何操作? - ekkis
1
问题是如何复制一个仓库并保留历史记录。您需要使用 --allow-unrelated-histories https://johno.com/move-directory-between-repos-with-git-history 如果这不能解决您的问题,请提出一个单独的问题。 - DalSoft
一切都很顺利,除了一个小问题。默认分支从主分支更改为具有最新更改的分支。我的存储库在一个组织中,我不得不发送电子邮件请求将其更改回来。 - jeffry copps

5
如果您正在从一个github存储库迁移到另一个github存储库,我建议使用以下命令进行迁移:git clone --bare <URL>而不是git clone --mirror。因为如果您镜像了一个github存储库,它将不仅克隆与源代码相关的内容,还会克隆剩余的拉取请求和github引用,导致推送时出现![remote rejected]错误。 我在谈论这个问题 我推荐的步骤如下:
1. git clone --bare <旧仓库URL> 2. cd <克隆仓库的路径> 3. git push --mirror <新仓库URL> 成功将所有分支、历史记录和源代码迁移到github新存储库,没有任何错误!

5

这种方法似乎只在新存储库不存在时有效。在我的情况下,我想将几个存储库合并成一个,所以我似乎不能使用这个 :( - ekkis

3

我做的事情:

  1. 将存储库克隆到文件夹中
  2. cd existing-project
  3. 在此处打开git终端
  4. git remote set-url origin <NEW_GIT_REPO>
  5. git push -u origin --all
  6. git push origin --tags

2
我使用以下方法将我的GIT Stash迁移到GitLab并保留所有分支和提交历史记录。
将旧存储库克隆到本地。
git clone --bare <STASH-URL>

在GitLab中创建一个空仓库。原始答案翻译成"最初的回答"。
git push --mirror <GitLab-URL>

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