远程仓库

远程( remote )版本库也叫上游( origin )版本库。

通常我们并不常亲自建立远程仓库,而是委托给『第三方』。

常见的操作是,先在第三方上创建『远程 Git Repository』,然后复制( Clone )出一个『本地 Git Repository』。

1. 在托管网站上创建远程仓库

常见的代码托管仓库有:

  • 国外:github、gitlab
  • 国内:gitee、coding、云效
  • 自建私服:gogs、gitea、gitlab

在托管网站上创建项目后,通常项目目录下是空的。

托管网站上所创建的项目就是所谓的「远程( remote )仓库」、也叫「上游( origin )仓库」。

从它所扮演的角色、承担的功能来讲,也有人习惯性称之为「中央仓库*」。

逻辑上,远程仓库的仓库名( 项目名 )和你的本地仓库的仓库名( 项目名 )应该是一样的。这虽然看起来是一句废话,但是,实际上你如果硬是要弄得不一样,也是可以的...

远程仓库作为一个中间的「桥梁」就可以在多台电脑之间「传递」项目文件。无论,这多台电脑是你一个人的,还是不同人的。

关联本地仓库和远程仓库

  • 第 1 步:创建远程仓库

    在托管网站上创建一个和你本地仓库同名的仓库。

    略。

  • 第 2 步:为本地仓库添加远程仓库地址

    进入你的本地的 git 仓库(也就是你的项目目录),为它添加远程仓库( 也就是上游仓库 )的网址。然后执行 git push 命令将本地仓库的内容( 和历史记录 )「上传」到远程仓库。

    cd <本地仓库目录>
    # git remote remove origin
    git remote add origin <远程仓库中的网址>
    git push -u origin "master"
    

    上面 git push 命令中的 -u--set-upstream 的简写。

本地仓库和远程仓库之间的「关系」体现在 Git 的配置项的 origin 属性上。使用 git config -l 可以看到:

...
remote.origin.url=远程Git文档库地址
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
...

2. 远程仓库的网址

提前说明,远程仓库的网址有 2 种格式。

http/https 地址

一般情况下,上面的「远程仓库中的网址」是一个 http/https 的地址。http/https 地址形如:

https://gitee.com/hemiao3000/java-note-dist-vuepress2.git

当你执行 git push 命令「上传」你的本地内容时,为了证明你自己的身份,托管网站会要求你提供「用户名/密码」来决定是否允许你的上传行为。

未来,每当你执行 git push 命令( 不光是它,还有其它一些命令也需要 )的时候,理论上你都要输入你的托管网站的用户名和密码。

图形化客户端有「记住密码」功能

绝大多数图形化的客户端工具( 例如,GitKraken、SourceTree 等 )都有记住密码的功能,能够在你执行相关操作时「帮」你输入密码,而无需你亲自、反复输入。

不过,你要记得,本质上这里每次 git push 命令是需要提供用户名/密码的,只不过不是你亲自输入罢了。

当然,你使用有 RememberMe 功能的客户端倒还好,如果你使用的是命令行,隔三岔五地就需要输入一次托管网站的用户名/密码也是很令人烦躁的事情。

SSH 地址

第二种远程网址格式是一个 SSH 的地址,它能「从根本上」帮你省掉输入托管网站用户名密码的环节。ssh 地址形如:

git@gitee.com:hemiao3000/java-note-dist-vuepress2.git

这种情况下你要通过,ssh-keygen 命令生成一对 SSH 公钥和私钥,并将公钥( 的内容 )「告知」托管网站。

这样,当你再执行 git push( 或其它需要认证 )的命令时,托管网站能判断地出当前的请求是来自于「你的电脑」,从而无需你输入托管网站的用户名和密码。

# 理论上『备注』的内容任意。不过通常是 2 种风格:
# - 你的邮箱,例如:hemiao3000@126.com
# - username@hostname,例如:root@192.172.0.16
ssh-keygen -t rsa -b 4096 -C "<备注>"

# 一路回车、回车、回车、回车...

查看生成的内容。复制粘贴它,后面要用到这个内容。

# 或者在你的用户加目录下找到它,用任意文本编辑器打开它也行。
cat ~/.ssh/id_rsa.pub

sshkey-gen

在托管网站上进行配置,将 id_rsa.pub 的内容配置到托管网站的对应设置中。

补充

ssh-keygen 的参数除了 -t rsa 之外,还可以其他的( 代表使用不同的加密算法 ),例如 -t ed25519

3. 克隆远程仓库至本地

如果作为项目团队成员,你需要去『初次下载』组长在托管网站( 也就是逻辑上的中央仓库 )上所所创建的项目时,你要执行的是 git clone 命令。

git clone <远程文档库的路径> <本地文档库的文件夹名称>

更具体的的格式为:

git clone <http://Web服务器地址/远程文档库路径> <本地文档库名称>

例如:

git clone <项目的 http 网址>
# 或
git clone <项目的 ssh 网址>

理论上,git clone 命令一个项目通常只会执行一次,因为它代表的是从无到有的「第一次下载」,后续的「下载」实际上是「更新、拉取」,使用的是 git pull / git fetch 命令。

4. 推送

当我们完成对本地文档库的修改,可以将这些修改『推送』到远程 Git 仓库:

git push origin [分支名称]

git push 有 2 种模式:

  • 推送『当前』分支,而非本地仓库的所有分支。配置:

    # 推荐这种模式,更安全、稳妥,不会手滑出错。
    git config --global push.default simple
    
  • 推送本地『所有』分支,而不仅仅是当前分支。配置:

    git config --global push.default matching
    

另外,无论哪种传送模式,只要执行 git push --all 都是推送所有分支,无视你的全局配置。

5. fetch 和 pull

如果你有一个远程 Git 分支,比如在 GitHub 上的分支,当远程分支上包含当前分支没有的提交时,可以使用取回。

比如,当合并了另一个分支或你的同事推送了一个快速修复时。

通过在这个远程分支上执行 git fetch ,我们就可在本地获取这些修改。这不会以任何方式影响你的本地分支:fetch 只是单纯地下载新的数据而已

git-fetch

现在我们可以看到自上次推送以来的所有修改了。这些新数据也已经在本地了,我们可以决定用这些新数据做什么了。

git pull 逻辑上是两个命令的组合:git fetch + git merge

git-pull

6. 大道理、小细节和套话

  1. xxx 只和 xxx 玩,yyy 只和 yyy 玩:

    当你要推送( push,逻辑上就是上传 )本地的 xxx 分支时,你上传的目的地一定是远程的 xxx 分支;

    当你要拉取( push,逻辑上就是下载 )远程的 yyy 分支时,你下载的目的地一定是本地的 yyy 分支;

    理论上虽然可以,但是实际上我们并不会让本地的 xxx 分支和远程的 yyy 分支有推拉关系。即,本地 xxx 分支只和远程 xxx 分支『玩』,本地 yyy 分支只和远程的 yyy 分支『玩』。

  2. 推拉( push / pull )都是在更新:

    推送(push)操作的执行的潜在前提是:你的本地 xxx 分支上的代码一定更『新』(版本更高),否则,你为什么要上传呢?

    拉取(pull)操作的执行的潜在前提是:你的远程 xxx 分支上的代码一定更『新』(版本更高),否则,你为什么要下载呢?

    推拉都是在更新,只是『方向』不同:推送,是用本地 xxx 分支更新远程 xxx 分支;拉取,是用远程 xxx 分支更新本地 xxx 分支。

  3. 合理使用『简称』少费口舌:

    通过 git push 命令推送本地 xxx 分支代码到远程 xxx 分支,实现远程 xxx 分支的代码的更新,简称:通过推送 xxx 分支来更新远程 xxx 分支。

    通过 git pull 命令拉取远程 yyy 分支代码到本地 yyy 分支,实现本地 yyy 分支的代码的更新,简称:通过拉取 yyy 分支来更新本地 yyy 分支。

  4. 故意推拉『旧代码』是为了放弃:

    可以推送( 上传 )旧代码,在此之前,你的远程 xxx 分支的代码更新,版本更高,而你推送( 上传 )的旧代码会覆盖掉远程的新代码;

    也可以拉取( 下载 )旧代码,在此之前,你的本地 yyy 分支的代码更新,版本更高,而你拉取( 下载 )的旧代码会覆盖掉本地新代码;

    通常情况下,你不太可能会用旧代码更新新代码,如果你这么干了,意味着你是想废弃新代码中『新』的那部分内容。

Last Updated:
Contributors: hemiao