这篇讲只用一个源地址把公开仓库导入 AngusGit 时,会得到什么,以及什么时候该改用推送。看完你可以填写 导入仓库 完成导入,并知道结果只有默认分支当时的文件和一条新提交;源仓库是私有的,或要保留完整历史、其他分支和标签,就先建空仓库,再用 git clone --bare 推送。

先登录 AngusGit。导入在侧栏 仓库 右上角的 导入仓库。要克隆导入后的私有仓库,或改用推送保留历史,先准备凭据。走 SSH:本机没有 ~/.ssh/id_ed25519.pub 时执行 ssh-keygen -t ed25519 -C "you@example.com",路径直接回车,再 cat ~/.ssh/id_ed25519.pub,把以 ssh-ed25519 开头的一整行贴到 我的 → SSH密钥 的 添加SSH密钥。地址用 ssh://git@主机:2222/所有者/仓库.git,用户名是 git。走 HTTPS:到 我的 → 访问令牌 点 生成新令牌,密码验证 填登录密码。只克隆勾 git:read、仓库权限 READ;要推送则勾 git:write、权限 WRITE。生成后马上复制。用户名填 AngusGit 登录名,密码填令牌。

文中以 git.anguskit.com 上的一次真实导入对照:源地址是 https://github.com/octocat/Hello-World.git,所有者是当前账号 Angus / xlliu,仓库名是 hello-world-import,并打开了 设为私有仓库,导入完成后代码页地址是 https://git.anguskit.com/code/xlliu/hello-world-import。

这台实例上已有的 anguskit/AngusRepo 是制品库产品自己的仓库,并不是从 GitHub 导入的快照,不要用它的名字再导入一次,否则会提示 仓库「anguskit/AngusRepo」已存在。

导入只留下源仓库默认分支当时的文件

1. 导入会带过来什么

动手之前,先弄清导入会得到什么,再决定用导入还是推送。下表前两列是导入的规则,最后一列是 Hello-World 导入后的实际表现,可以对照着看。

内容 是否带过来 Hello-World 的表现
源仓库默认分支当前的全部文件 带过来 只有 README,13 B,内容是 Hello World!
原来的提交历史 不带 只有 1 条提交,说明是 Initial commit from https://github.com/octocat/Hello-World.git,短哈希 25861fe
默认分支以外的分支 不带 页签是 分支 1,名字是 main
标签(Tag) 不带 标签 0,发布 0
子模块(Submodule) 不带 Hello-World 没有子模块
Issue、合并请求、Wiki、CI、成员权限 不带 问题 0,Wiki 0
导入之后源仓库的新提交 不自动同步 导入是一次性操作

还有一处细节:Hello-World 在 GitHub 上的默认分支叫 master,导入后文件都在,但 AngusGit 上的分支名是平台默认的 main,不会沿用 master 这个名字。

所以,导入适合只需要代码当前版本的场景,例如拿一个开源项目做内部二次开发,或者旧仓库的历史本来就不重要。如果要保留每一次提交,或者要带上其他分支和标签,请直接看第 5 节。

2. 导入之前确认两件事

第一,源仓库要不登录就能读。 可见性决定谁能看到仓库,导入表单里没有填写源站账号或令牌的地方,AngusGit 只能以匿名身份去拉代码。因此公开仓库没有问题,私有仓库则会在提交表单时报 源仓库URL「…」无效或无法正常访问。也不要把账号或令牌拼进 URL 来绕过这个限制,因为这个地址会原样写进导入生成的提交说明,留在新仓库的历史里,所有能看到仓库的人都看得到。源仓库是私有的,请用第 5 节的推送方式。

第二,AngusGit 所在的服务器要能连上源站。 真正去拉代码的是 AngusGit 服务器,跟你自己的电脑能不能上外网无关,所以内网服务器访问不了 github.com 时,导入同样会失败。想提前确认,可以在那台服务器上执行一次 git ls-remote <源地址>,这条命令会列出源仓库的分支,能打印出来就说明网络是通的。以 Hello-World 为例,它能导进来,就说明那台服务器当时访问得到 github.com。

3. 导入一个仓库

  1. 打开导入页 在侧栏点 仓库,再点右上角的 导入仓库。打开的是一整页表单,标题是 导入仓库,下方说明是「从其他版本控制系统导入现有仓库」。
  2. 填写源地址 仓库 URL 填源仓库的 HTTPS 克隆地址,以 Hello-World 为例就是 https://github.com/octocat/Hello-World.git。表单提示写着支持 Github、Gitlab、Gitee、SourceForge;如果地址不是以 https://、http:// 或 git@ 开头,输入框下方会提示 请输入正确的仓库URL。
  3. 选所有者,填仓库名称 所有者 默认是当前登录账号,下拉里还能选你担任维护者的团队;示例保留了默认的 Angus / xlliu。仓库名称 不会根据地址自动填写,需要手动输入,示例填的是 hello-world-import,输入框前面会显示命名空间前缀 xlliu /。名称只能用中文、字母、数字、连字符和下划线,输入的点号会被直接去掉。描述 可以留空,示例就没有填;框里灰色的「从 GitHub 导入的仓库」只是占位文字,并不是已经填好的内容。
  4. 决定是否私有 设为私有仓库 默认是关闭的。代码只给团队内部看时,记得把它打开;示例打开了这个开关,所以导入得到的是私有仓库。
  5. 开始导入 仓库 URL、所有者 和 仓库名称 都填好之后,开始导入 按钮才能点击。点击后按钮会变成禁用状态,一直等到代码拉完;仓库较大时耗时更长,这期间不要关闭页面。导入完成后表单会自动关闭,新仓库出现在仓库列表里。Hello-World 很小,很快就回到了列表。

导入表单已填好:仓库 URL 是 Hello-World,所有者 Angus / xlliu,名称 hello-world-import,私有开关已打开

上图是点击 开始导入 之前的表单:描述留空,私有开关已经打开。

4. 验收:在代码页确认只有一条提交

导入完成后,打开仓库的代码页,以示例为例就是 https://git.anguskit.com/code/xlliu/hello-world-import,然后按下面几处核对。页头标着 私有,统计栏依次是 分支 1、标签 0、发布 0、问题 0、Wiki 0。分支选择器显示 main,旁边写着 1 提交;这条提交的作者是 Angus,说明是 Initial commit from https://github.com/octocat/Hello-World.git,短哈希(提交号的前几位)是 25861fe。文件列表里只有一个 README,大小 13 B。

私有仓库 hello-world-import:main 上 1 条初始提交,文件只有 README

需要克隆时,点右上角橙色的 代码 按钮打开克隆面板,面板说明是「使用 Web URL 克隆。」其中 HTTPS 页签里的地址是:

https://git.anguskit.com/xlliu/hello-world-import.git 

SSH 页签里的地址是:

ssh://git@git.anguskit.com:2222/xlliu/hello-world-import.git 

因为仓库是私有的,克隆时会要求输入用户名和访问令牌。用户名填 AngusGit 登录名,密码填开头生成的令牌:只克隆用 git:read,要推送用 git:write。不要把令牌写进页面或截图。到这里验收就完成了:代码页上有一条初始提交、一个文件,就说明导入成功。

导入之后,团队应当改从 AngusGit 拉代码。原来指向 GitHub 的本地仓库,执行一次 git remote set-url origin <新地址> 就能把远程地址换成 AngusGit。不过新仓库的历史和源仓库对不上,在旧的本地副本里直接 git push 会被拒绝,所以最稳妥的做法是每个人重新 clone 一份。

5. 要保留完整历史,或者源仓库是私有的

遇到这两种情况,导入仓库 就不够用了,要改走推送:先在自己的电脑上把源仓库完整克隆下来,再推到 AngusGit 上一个新建的空仓库。这样所有分支、标签和提交历史都会一起过去。

下面命令里的目标仓库 hello-world-history 只是示意名称,推送前要先在 AngusGit 上把它建成空仓库。不要推到已经导入的 xlliu/hello-world-import:两边的历史对不上,推送会被拒绝。

  1. 在 AngusGit 建一个空仓库 按「新建仓库」的步骤建一个仓库,添加 README 文件、添加 .gitignore、选择许可证 三项都不要勾选,这样建出来的才是空仓库。勾选任何一项,推送都会因为两边历史对不上而被拒绝。建好后复制这个空仓库的地址。
  2. 把源仓库完整克隆到本地 git clone --bare 得到的是一个裸仓库:它只保存 Git 的数据,也就是全部分支、标签和提交历史,不生成可以直接编辑的工作区文件,正适合原样转推。源仓库是私有的,这一步会要求你登录源站。
  3. 主分支不叫 main 时先改名 AngusGit 空仓库的默认分支是 main,而 Hello-World 的主分支叫 master,所以先在裸仓库里执行 git branch -m master main 改名。源仓库的主分支已经叫 main 时,跳过这一步。
  4. 推送所有分支和标签 --all 推送所有分支,--tags 推送所有标签。示例用的是 SSH 地址;改用 HTTPS 地址也可以,这时密码一栏填 AngusGit 的访问令牌。令牌只保存在你自己的密码管理器里。
git clone --bare https://github.com/octocat/Hello-World.git hello-world-history.git cd hello-world-history.git git branch -m master main git push ssh://git@git.anguskit.com:2222/xlliu/hello-world-history.git --all git push ssh://git@git.anguskit.com:2222/xlliu/hello-world-history.git --tags 

推送完成后,打开 AngusGit 仓库的 分支 页签,应该能看到源仓库的全部分支,提交记录也和源仓库一致。SSH 公钥和访问令牌按开头准备。

6. 一次导入很多个仓库

要搬的仓库较多时,可以用 仓库 页右上角的 批量导入。打开后页面标题是 批量导入仓库,有 手动输入、待导入、已导入 三个页签。

在 手动输入 页签的 仓库地址列表 里每行填一个地址,选好 所有者,再点 添加到待导入列表,一次最多 100 个。批量导入和单个导入相比有三点不同:

  • 仓库名称自动取地址的最后一段,例如 https://github.com/octocat/Hello-World.git 会导入成 Hello-World,列表里不能逐个改名。
  • 页面上没有 设为私有仓库 开关,批量导入的仓库全部是公开的。需要私有时有两种办法:导入后到每个仓库的 设置 → 访问,在 可见性 里改成私有并点 保存可见性设置;或者改用第 3 节的单个导入,hello-world-import 就是单个导入时打开私有开关得到的。
  • 导入在后台排队进行,提交之后可以离开页面。进度在 待导入 页签查看,每一项会依次显示 等待中、处理中,结束时显示 成功 或 失败。成功的项目出现在 已导入 里;失败的不会自动重试,展开任务能看到原因,改好地址后重新添加即可。

除了这三点,批量导入的规则和单个导入一样:只带默认分支的文件,源仓库也必须不登录就能读。已经存在的 anguskit/AngusRepo 不要再放进列表。

7. 导入失败时

你看到的 原因 怎么处理
输入框下方 请输入正确的仓库URL,开始导入 点不了 地址不是 https://、http:// 或 git@ 开头,或者缺了路径 从源站仓库页重新复制 HTTPS 克隆地址
源仓库URL「…」无效或无法正常访问 地址拼错;源仓库是私有的;或 AngusGit 服务器连不上源站 先不登录在浏览器打开源仓库页,确认它是公开的;再在 AngusGit 服务器上执行 git ls-remote <源地址>。私有源仓库按第 5 节推送
仓库「xlliu/hello-world-import」已存在 同一个所有者下已有同名仓库,例如这个仓库已经导入过一次 换一个 仓库名称。anguskit/AngusRepo 同样已存在,不要用它当导入目标
克隆仓库异常:… 拉取过程中出错,例如网络中途断开 看冒号后面的原因。网络问题先重试一次;仓库很大、反复中断时改用第 5 节
批量导入里某一项 失败 和单个导入的原因相同 展开任务看这一项的错误信息,改好后重新添加到待导入列表

常见问题

导入之后,源仓库的新提交会同步过来吗?

不会。导入只在你点击 开始导入 的那一刻拉一次代码,之后源仓库的新提交不会自动过来。想拿到这些新提交,可以用一个新名字重新导入一次;或者改用第 5 节的推送方式,把源仓库连同新提交一起推到一个新建的空仓库。

为什么导入后只剩一条提交?

因为导入拿的是源仓库默认分支当时的文件,用这些文件在 AngusGit 上新建一个仓库并生成一条提交,原来的提交历史、其他分支和标签都不会带过来。以 Hello-World 为例,导入后只有这一条 Initial commit from https://github.com/octocat/Hello-World.git。要保留历史,请用第 5 节。

GitLab 和 Gitee 的仓库也是这样导入吗?

是的。仓库 URL 填 GitLab 或 Gitee 仓库页上的 HTTPS 克隆地址即可,步骤和规则完全一样。表单提示里列出的就是 Github、Gitlab、Gitee、SourceForge 这几家,GitBucket 等能用 Git 地址访问的平台也可以导入。

Issue 和合并请求能一起迁过来吗?

不能。导入和推送都只搬 Git 仓库里的内容,Issue 和合并请求不在其中。进行中的合并请求,建议先在源站合并或关闭再迁移;还没解决的 Issue,到 AngusGit 的 问题 里重新创建。

源仓库用了 Git LFS 怎么办?

Git LFS 是 Git 的大文件存储扩展,AngusGit 不支持它。导入或推送之后,LFS 管理的大文件只剩下指针文件(一小段记录文件位置的文本),原来的内容不会过来。这类文件需要改成普通文件提交,或者放到制品库里。

小结

导入仓库 适合只要代码当前版本的场景:源仓库必须公开,结果只有默认分支的文件和一条 Initial commit from …,不带历史、其他分支和标签,也不包括 Issue、合并请求和 CI。以 Hello-World 为例,它被导入成私有的 xlliu/hello-world-import,main 上只有一个 README。如果源仓库是私有的,或者要保留每一次提交、每一个分支和标签,就改走推送:先建一个空仓库,再用 git clone --bare 加 git push --all 和 --tags。推送目标必须是这个新建的空仓库,不要推到已经导入的仓库上。

结论: 导入仓库 只会把公开源仓库默认分支当时的文件做成一条 Initial commit from <源地址>(xlliu/hello-world-import 就是把 master 上的 README 落到了 main),要保留完整历史、全部分支和标签,就新建空仓库,再用 git clone --bare 加 git push --all / --tags 推送。

参考文章