GitHub:如何将公共仓库分叉变为私有?

509

我如何将一个公共代码库 fork 到我的账户下,并把我的 fork 保持为私有状态?我已经购买了支持私有代码库的订阅。

7个回答

725
答案是正确的,但没有提到如何同步公共代码库和 fork 之间的代码。
以下是完整工作流程(我们在开源 React Native 之前就已经这样做过):
首先,像其他人说的那样复制存储库(详细信息请参见此处):
通过Github UI创建一个新的存储库(让我们称其为private-repo),然后:
git clone --bare https://github.com/exampleuser/public-repo.git
cd public-repo.git
git push --mirror https://github.com/yourname/private-repo.git
cd ..
rm -rf public-repo.git

克隆私有仓库以便您可以对其进行操作:

git clone https://github.com/yourname/private-repo.git
cd private-repo
make some changes
git commit
git push origin master

从公共存储库中拉取最新的代码:

cd private-repo
git remote add public https://github.com/exampleuser/public-repo.git
git pull public master # Creates a merge commit
git push origin master

太棒了,你的私有仓库现在已经包含来自公共仓库的最新代码以及你所做的更改。


最后,要创建私有仓库 -> 公共仓库的拉取请求:

使用 GitHub 的用户界面创建公共仓库的 fork(在公共仓库页面右上方有一个小的“Fork”按钮),然后:

git clone https://github.com/yourname/the-fork.git
cd the-fork
git remote add private_repo_yourname https://github.com/yourname/private-repo.git
git checkout -b pull_request_yourname
git pull private_repo_yourname master
git push origin pull_request_yourname

现在,您可以通过Github UI为public-repo创建拉取请求,如此处所述。

一旦项目所有者审核您的拉取请求,他们可以将其合并。

当然,整个过程可以重复执行(只需跳过添加远程步骤即可)。


12
为什么不能将空的私有仓库作为公共仓库的新远程添加到普通克隆中,然后推送到远程?这样做会有什么区别? - Falko Menge
2
@FalkoMenge 我有同样的问题。阅读 https://www.git-scm.com/docs/git-clone,它听起来像是一个普通的 git clone 会设置远程跟踪分支和可能一些其他配置在克隆的仓库中,这些你并不需要。而 --bare 克隆只是从远程直接复制 .git 目录。 - bennlich
1
@Sukhjinder Singh 是的,最后一步会将私有提交历史推送到公共存储库。如果您不想这样做,可以在将它们合并到公共存储库时压缩您的提交,并推送一个包含所有更改的单个提交。例如,请参见 https://dev59.com/dm435IYBdhLWcg3woRjG - Martin Konicek
4
@FalkoMenge 因为使用镜像路线会复制所有分支、标签等内容。在最简单的情况下,如果仓库只有一个分支、没有标签,也没有其他特殊内容,那么我认为你的方法可以奏效。但在其他所有情况下,最好使用镜像。 - Mike B
1
这太棒了!但是推送可能会失败,因为“2021年8月13日已删除对密码身份验证的支持”。相反,请使用类似于git push --mirror git@github.com:yourname/private-repo.git的东西。 - ariels
显示剩余4条评论

178

现在有一个更多的选项(截至2015年1月):

  1. 创建一个新的私人 repo
  2. 在空的repo屏幕上,有一个“导入”选项/按钮 输入图像描述
  3. 点击它并放置现有的github repo URL,虽然没有提到github选项,但它也适用于github repos。 输入图像描述
  4. 完成

28
这个方法可以实现,只是稍有不同(我在2015年8月尝试过)。我没有找到导入选项/按钮,于是搜索了一下,最后进入了这个网址https://import.github.com/new。在这里,你可以输入现有的Github链接并点击“检查”按钮。一旦验证成功,你可以输入新仓库的名称,然后点击私有按钮,再点击“开始导入”。 - Shiva
2
我相信@MattvanAndel的意思是评论是正确的,而不是原始答案。我也遵循Shiva的评论,它起作用了。请注意,您不应首先创建本地私有存储库! - David H
@Shiva,我在空仓库页面的底部找到了按钮。我想这是因为我创建了一个没有README、LICENSE或.gitignore的仓库,完全是空的。 - Burak
3
不支持:根据GitHub支持,导入仅用于将外部项目转换为GitHub,并在GitHub存储库上使用可能会产生意想不到的后果。显然,对于某些项目来说是有效的,基于这里的答案,但我在使用导入大型项目时遇到了问题(这就是我联系GitHub支持的原因)。在我看来,当复制存储库很简单时,冒这个风险是不值得的。 - cb4
3
根据本文编写时间,URL 应该为 https://github.com/new/import。 - Erik Finnman
显示剩余2条评论

56

只需访问https://github.com/new/import

GitHub Import

在“Your old repository's clone URL”部分粘贴您想要导入的仓库URL,在“Privacy”中选择Private


9
如果你不说遇到了什么问题,那么基本上就没有增加价值。 - Luk Aron
@LukAron 我有点同意,并且很抱歉在我制定支持GitHub答案的过程中没有捕捉到具体细节。如果我有时间重新创建原始条件,我一定会更新我的评论。 - cb4
2
使用这个,我将像往常一样收到主分支的更改通知,然后将它们合并到我的代码中吗? - gianni

51

当前的答案有点过时,所以为了清晰明了:

简短的回答是:

  1. 对公共仓库进行裸克隆(bare clone)
  2. 创建一个新的私有仓库。
  3. 对新的私有仓库进行镜像推送(mirror push)

GitHub 上已有相应文档:duplicating-a-repository


8
有没有一种方法可以拉取上游的更改?这对于一个有宽松许可证的仓库非常重要 - 我已经将我的仓库设为私有,但仍然想合并上游的更改。 - amarprabhu
4
可以将另一个代码库添加为新的“追踪”远程库(例如 'other-repo'),然后定期从中获取并合并更改(例如 'git merge other-repo/stable')。 - stefano

39

你需要复制这个仓库

你可以看一下这个文档(来自于github)

为了创建一个没有 fork 的仓库的副本,你需要运行一个特殊的克隆命令以对原始仓库进行镜像推送到新仓库。

在以下情况下,你正在尝试推送的仓库 - 如 exampleuser/new-repository 或 exampleuser/mirrored - 在 GitHub 上应该已经存在。有关更多信息,请参见 "创建新存储库"。

镜像一个仓库

要创建一个完全相同的副本,你需要执行 bare-clone 和 mirror-push 两个操作。

打开命令行,并输入以下命令:

$ git clone --bare https://github.com/exampleuser/old-repository.git
# Make a bare clone of the repository

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

$ cd ..
$ rm -rf old-repository.git
# Remove our temporary local repository
如果您想在另一个位置对存储库进行镜像操作,包括从原始存储库获取更新,您可以克隆一个镜像,并定期推送更改。
$ git clone --mirror https://github.com/exampleuser/repository-to-mirror.git
# Make a bare mirrored clone of the repository

$ cd repository-to-mirror.git
$ git remote set-url --push origin https://github.com/exampleuser/mirrored
# Set the push location to your mirror

就像裸克隆一样,镜像克隆包括所有远程分支和标签,但每次获取时所有本地引用都将被覆盖,因此它始终与原始存储库相同。设置推送的URL可以简化向您的镜像推送。要更新镜像,请获取更新并推送,这可以通过运行cron作业自动完成。

$ git fetch -p origin
$ git push --mirror

https://help.github.com/articles/duplicating-a-repository


1
这将创建一个存储库的克隆,但它不会在GitHub中创建一个分叉。当您在GitHub中创建一个实际的分叉时,它会在分叉名称下显示文本“forked from exampleuser/repository-to-mirror”。当您导航到github.com/exampleuser/new-repository/network/members时,它还显示所有其他分叉的树形结构。 - apaatsio

28

Github现在有一个导入选项,让你可以选择新导入的代码仓库是公开的还是私有的。

Github 代码仓库导入


导入仍在大型存储库(5天)上运行,检出速度更快,但可能需要更多步骤来保持最新状态。我想这种缓慢是可以理解的,因为它导入的不仅是主分支,而是所有内容,但我希望它能更快一些... - Liam Mitchell
1
不支持:根据GitHub支持,导入仅用于将外部项目转换为GitHub,并在GitHub存储库上使用可能会产生意想不到的后果。显然,根据这里的答案,对某些项目有效,但我在使用导入大型项目时遇到了问题(这就是我联系GitHub支持的原因)。在我看来,在复制存储库很简单的情况下,冒这个风险是不值得的。 - cb4
GitHub如果复制自己的仓库,就会崩溃,但为什么不阻止呢?那真是非常优秀的设计。 - Matthew Read
GitHub如果复制了自己的存储库,就会出现故障,但却不会阻止这种情况发生?这真是一个非常出色的设计。 - undefined

6

2021更新

我是git的新手,所以想尽可能地在eclipse GUI中完成(v2020-12; EGit v5.11)。详情如下。

---> 其他答案中的导入方法仅适用于Subversion、Mercurial或TFS项目。 GitHub不支持git项目的此方法,我第一手了解到。它可能有效,但为什么要冒险呢?


仓库和GitHub连接

eclipse/org.aspectj原始的公共仓库upstream用于获取
cb4/org.aspectj分叉(fork)并且origin用于推送
cb4/remPrivAJ远程私人仓库并且private用于推送
I:\local本地仓库

对于github认证,我使用了一个ed25519密钥的ssh (此SO答案中的步骤),因此我的连接URI看起来像这样:ssh://git@github.com/<user>/<repo>

注释:-> 是鼠标单击或选择;right->是右键单击。


步骤

  1. 在GitHub上,将原始公共仓库fork到您的GitHub账户
  2. 在GitHub上,创建空的远程私人仓库
  3. 在eclipse Git Perspective中,将fork克隆到一个新的本地仓库并进行配置
  • 3.1-> 克隆Git存储库并将其添加到此视图 -> 克隆URI -> 下一步
    • 3.1.1 根据需要输入URI、连接和身份验证信息 -> 下一步
    • 3.1.2 选择所需的分支(我只选择了主分支) -> 下一步
    • 3.1.3 输入本地repo的目标目录
    • 3.1.4 立即导入项目或稍后进行操作,然后 -> 完成 以填充本地repo
  • 3.2 将原始公共repo配置为一个名为upstream的新远程仓库,以便拉取更新
    • 3.2.1. 右键-> Remotes -> Create Remote -> 并输入名称upstream
    • 3.2.2. -> 配置提取 -> 创建 -> 更改 -> 输入原始repo URI -> 完成
    • 3.2.3. -> 保存并提取 -> 所有分支都被下载 -> 关闭
    • 3.2.4. 注意:我只想要主分支,所以执行此而不是步骤3.2.3
    • 3.2.5. -> 高级要提取的规范下,删除那里唯一的条目
    • 3.2.6. 在添加创建/更新规范 -> 源参考:下拉菜单下选择master [branch] -> +添加规范 -> 强制更新
    • 3.2.7. -> 保存规范至upstream配置 -> 完成 -> 保存并提取 -> 仅下载了主分支 -> 关闭
  • 4.将远程公共repo复制到您的远程私有repo并进行配置。这是唯一不能在eclipse中完成的步骤,因此我安装了Git for Windows并使用GitCMD。

  1. 复制远程公共repo到您的远程私有repo并进行配置。这是唯一不能在eclipse中完成的步骤,因此我安装了Git for Windows并使用GitCMD。

如下所示:

git clone --bare git://github.com/eclipse/org.aspectj.git tmpRepo
<if prompted, enter ssh passphrase>
cd tmpRepo    
git push --mirror ssh://git@github.com:cb4/private.git
<if prompted, enter ssh passphrase>
cd ..    
rmdir tmpRepo /s /q
  • 将远程私有仓库配置为名为private的新推送远程仓库。
    • 5.1. 右键 -> 远程 -> 创建远程 -> 输入名称private
    • 5.2. -> 配置推送 -> 创建 -> 更改 -> 输入远程私有仓库URI -> 完成
    • 5.3. -> 高级选项 -> 添加所有分支规范 -> 强制更新 -> 保存在原始配置中 -> 完成
    • 5.4. -> 保存并推送主分支被推送。-> 关闭

    此时,您已经将公共仓库fork到了您的私有仓库。要查看如何将私有更改推送到您的fork,然后打开针对原始公共仓库的拉取请求,请参见我的答案。生成的配置如下所示:
    config


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