利用 gitee 平台,线上一键部署项目。

场景

  1. 代码托管在本地局域网服务器上创建的 git 服务。
  2. 本地局域网服务器上已经部署自动构建脚本,可正常发布到开发和测试环境。
  3. 生产环境获取不到本地局域网 git 托管的代码。
  4. 偶尔在非上班时间需要紧急修复 Bug 并上线,那么即使不在办公室,也可以照样获取到项目的源码,且有全部提交历史。

解决方案

借助码云免费私有项目来中转,每次在测试服务器上构建的时候,把获取到的最新代码同步 push 至码云上的项目。
每天下班之后,测试服务器定时关机之前,再执行一次代码同步至码云项目的任务。

那么,问题来了,怎么样才能从一个 git 仓库提交代码到另一个 git 仓库?
如何让本地代码提交更新之后,在需要发布到线上的时候,将本地所有代码同步至码云上去呢?
为达此目的,网上查看了好多文章,均不全。经过反复测试,正确的步骤如下:

以下以 gitee 上的 demo 项目为例

  1. 在 gitee 上创建一个新项目 demo,0 提交。如果有提交,push 的时候会报错,不能同步更新。
  2. 在 gitee 账户下,配置 ssh 个人私钥,只有个人私钥才能 push,项目公钥,只能 pull。

    作用:用公钥,git 操作,如 push/clone/pull 都免用户名和密码

在测试服务器上运行:

1
2
3
4
5
ssh-keygen -t rsa -C "xxxxx@xxxxx.com"
# Generating public/private rsa key pair...
# 三次回车即可生成 ssh key
# 查看你的 public key,并把他添加到码云(Gitee.com)。SSH key添加地址:https://gitee.com/profile/sshkeys
cat ~/.ssh/id_rsa.pub

添加到码云后,在终端(Terminal)中输入

1
ssh -T git@gitee.com

若返回

1
Welcome to Gitee.com, yourname!

则证明添加成功。

关于如何操作,请看官方教程

  1. 这里引用官方文档:项目的 ssh key 和用户的 ssh key 两处地方有什么不同?

    项目的 sshkey 只针对项目,且我们仅对项目提供了部署公钥,即项目下的公钥仅能拉取项目,这通常用于生产服务器拉取仓库的代码。
    而用户的 key 则是针对用户的,用户添加了 key 就对用户名下的项目和用户参加了的项目具有权限,一般而言,用户的key具有推送和拉取的权限,而项目的 key 则只具有拉取权限。

  2. 在本地项目的工作目录添加 remote 项目 demo,这里 demo 是需要从本地局域网同步的远端项目。
    1
    git remote add demo git@gitee.com:elsafly/demo.git

上述代码对 .git/config 文件的修改是,添加了

1
2
3
[remote "demo"]
url = git@gitee.com:elsafly/demo.git
fetch = +refs/heads/*:refs/remotes/demo/*

  1. 同步主分支代码

    1
    2
    git checkout master
    git push demo
  2. 同步 branch-v1.0,以下指令会自动在远端创建相同分支。

    1
    2
    git checkout branch-v1.0
    git push demo

操作日志

以 utomcat 的身份执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[utomcat@centOS7BasicForTest ~]$ ssh-keygen -t rsa -C "1614923608@qq.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/utomcat/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/utomcat/.ssh/id_rsa.
Your public key has been saved in /home/utomcat/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:92cdC1dfr5XkUm5K3NDiWieJHpCaz2aKsuEw8vfm/pQ 1614923608@qq.com
The key's randomart image is:
+---[RSA 2048]----+
| |
| . . |
| o o +o|
| o . + X *|
| oS .o X X+|
| oo..= O+o|
|.o . E= o..+..|
|..+.o o.+ o |
| .+o*+o. |
+----[SHA256]-----+
[utomcat@centOS7BasicForTest ~]$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDb4K+3HTCT9Kowo/2D3Nq69gSBC+/H7fMGZtNyqbkmnXIOBxQhQx1o9HM8sJvFWgiJ99ev2a49X5fuZm3Mm6osFNRYAtmajnl9VU/zaFX0sXzh6f60Z847gjh5bWwBKzV1TPejCVMVNmq3TDwf8nbEX9/o2JIihWHAowyqgCUTLQySQkK1pAcjPuYtNTKAQ8wpaFC0ssquGTggGegC2J/HMjQGgHz6XxFUhEHNBLGhleSSIP9dNqe5LypPyeYdHXI63+0K6kBEoUbwt7eh1uy/Vw7oOcJLpPJISr+qZXbbLNyIW8GV3Js73FDWXNN8tRj0yF9q5VlCthfGPrMxwxmD 1614923608@qq.com

将上面 cat 得到的内容复制到 giree 添加 ssh 公钥的页面公钥栏。

所用到的 git 指令

参考文章:从一个 git仓库提交代码到另一个git仓库

  1. 将仓库 repo_b 的 URL 添加到工作仓库的 remote。
    1
    git remote add origin_repo_b git@server_ip:/path/repo_b.git

origin_repo_b:自己起的名字,只要不与现有的 remote 名重复即可
git@server_ip:/path/repo_b.git:repo_b 的远程路径

  1. 将代码推送到远程 repo_b
    1
    git push origin_repo_b branch_a

origin_repo_b:远程仓库 repo_b 的名字
branch_a:仓库 repo_a 的的 branch_a 分支

将一份相同的代码提交到多个不同的 git 托管服务器(多个git仓库)

方法非常相似,就是用到了下面的指令

1
git remote set-url --add [--push] <name> <newurl>

现在,假设在远程的 git 服务器上又新增了一个仓库 repo_c,要求 repo_b、repo_c 提交的代码必须一致。

  1. 将远程 repo_c 配置到当前的工作的本地 git 仓库中
    1
    git remote set-url --add origin_repo_b git@192.168.1.101:~/project/repo_c.git

 这句话的意思是,将远程仓库 git@192.168.1.101:~/project/repo_c.git 也加入到 origin_repo_b 这个名字下面管理

  1. 将代码同时提交到远程仓库 repo_b 和远程仓库 repo_c
    1
    git push origin_repo_b branch_a

在多个 git 仓库同步代码,注意事项

以 utomcat 的身份生成公钥:

1
ssh-keygen -t rsa -C "1614923608@qq.com" -f ~/.ssh/forGitee # -f参数:指定文件名。但这里不能指定,需要用默认的,否则将不会生效。后面会说明。

配置个人私钥和项目公钥,尝试 clone 项目,都提示:

1
2
3
4
5
6
7
[utomcat@hjweb01 gitCode]$ git clone git@gitee.com:elsafly/projectName.git
Cloning into 'hjz'...
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

经测试,发现,为 gitee.com 配置公钥时,要添加默认名即:id_rsa,否则不能与 gitee 通信

重点:可以用不同的用户创建不同目的的公钥,然后以这用户的身份来操作 git 项目。

同样的,在本地用 Gitolite 搭建的 git Server,在 CentOS 上创建公钥,将 id_rsa 改名,git clone,也会提示:fatal: Could not read from remote repository.

authorized_keys

拷贝ssh公钥到 authorized_keys 后仍然无法免密登录。

解决

修改修改.ssh目录的权限以及authorized_keys 的权限(这个必须修改,要不然还是需要密码)

1
2
sudo chmod 644 ~/.ssh/authorized_keys
sudo chmod 700 ~/.ssh

git 官方文档

官方文档

git 语法

  • git 基本语法

    1
    2
    3
    4
    5
    6
    git [--version] [--help] [-C <path>] [-c <name>=<value>]
    [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
    [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
    [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
    [--super-prefix=<path>]
    <command> [<args>]
  • git clone 基本语法

    1
    2
    3
    4
    5
    6
    7
    git clone [--template=<template_directory>]
    [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
    [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
    [--dissociate] [--separate-git-dir <git dir>]
    [--depth <depth>] [--[no-]single-branch] [--no-tags]
    [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
    [--jobs <n>] [--] <repository> [<directory>]

从一个远程仓库拉取更新同步到另外一个远程仓库

典型应用场景:
我 fork 了一个 RTT 到我的 git 下,然后从我的远程仓库中 git clone 到了本地。一段时间之后,RTT 官方的 git 上有了更新,如何把 RTT 官方 git 上的更新同步到我的远程 git 上?

  1. 在本地 git 命令中用 git remote add 增加一个分支来跟踪 RTT 官方的 git。
  2. 把 RTT 官方的更新 git fetch 下来,再然后用 git merge 合并到本地的 master 分支上。
  3. 用 git push 提交到自己的远程 git 上。

git clone 三种用法

  1. git clone
    • 指向的版本库创建一个克隆到 目录。
    • 目录相当于克隆版本库的工作区,文件都会检出,版本库位于工作区下的 .git 目录中
  2. git clone –bare <directory.git>
  3. git clone –mirror <directory.git>

区别

【–bare】和【–mirror】创建的克隆版本库都不包含工作区,直接就是版本库的内容,这样的版本库称为裸版本库。一般约定俗成裸版本库的目录名以 .git 为后缀。
【–mirror】区别于【–bare】之处在于【–mirror】克隆出来的裸版本库对上游版本库进行了注册,这样可以在裸版本库中使用 git fecth 命令和上游版本库进行持续同步。