场景
- 代码托管在本地局域网服务器上创建的 git 服务。
- 本地局域网服务器上已经部署自动构建脚本,可正常发布到开发和测试环境。
- 生产环境获取不到本地局域网 git 托管的代码。
- 偶尔在非上班时间需要紧急修复 Bug 并上线,那么即使不在办公室,也可以照样获取到项目的源码,且有全部提交历史。
解决方案
借助码云免费私有项目来中转,每次在测试服务器上构建的时候,把获取到的最新代码同步 push 至码云上的项目。
每天下班之后,测试服务器定时关机之前,再执行一次代码同步至码云项目的任务。
那么,问题来了,怎么样才能从一个 git 仓库提交代码到另一个 git 仓库?
如何让本地代码提交更新之后,在需要发布到线上的时候,将本地所有代码同步至码云上去呢?
为达此目的,网上查看了好多文章,均不全。经过反复测试,正确的步骤如下:
以下以 gitee 上的 demo 项目为例
- 在 gitee 上创建一个新项目 demo,0 提交。如果有提交,push 的时候会报错,不能同步更新。
- 在 gitee 账户下,配置 ssh 个人私钥,只有个人私钥才能 push,项目公钥,只能 pull。
作用:用公钥,git 操作,如 push/clone/pull 都免用户名和密码
在测试服务器上运行:1
2
3
4
5ssh-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!
则证明添加成功。
关于如何操作,请看官方教程
- 这里引用官方文档:项目的 ssh key 和用户的 ssh key 两处地方有什么不同?
项目的 sshkey 只针对项目,且我们仅对项目提供了部署公钥,即项目下的公钥仅能拉取项目,这通常用于生产服务器拉取仓库的代码。
而用户的 key 则是针对用户的,用户添加了 key 就对用户名下的项目和用户参加了的项目具有权限,一般而言,用户的key具有推送和拉取的权限,而项目的 key 则只具有拉取权限。 - 在本地项目的工作目录添加 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
2git checkout master
git push demo同步 branch-v1.0,以下指令会自动在远端创建相同分支。
1
2git 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 指令
- 将仓库 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 的远程路径
- 将代码推送到远程 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 提交的代码必须一致。
- 将远程 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 这个名字下面管理
- 将代码同时提交到远程仓库 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
2sudo chmod 644 ~/.ssh/authorized_keys
sudo chmod 700 ~/.ssh
git 官方文档
git 语法
-
1
2
3
4
5
6git [--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>] -
1
2
3
4
5
6
7git 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 上?
- 在本地 git 命令中用 git remote add 增加一个分支来跟踪 RTT 官方的 git。
- 把 RTT 官方的更新 git fetch 下来,再然后用 git merge 合并到本地的 master 分支上。
- 用 git push 提交到自己的远程 git 上。
git clone 三种用法
- git clone
- 将
指向的版本库创建一个克隆到 目录。 - 目录
相当于克隆版本库的工作区,文件都会检出,版本库位于工作区下的 .git 目录中
- 将
- git clone –bare
<directory.git> - git clone –mirror
<directory.git>
区别
【–bare】和【–mirror】创建的克隆版本库都不包含工作区,直接就是版本库的内容,这样的版本库称为裸版本库。一般约定俗成裸版本库的目录名以 .git 为后缀。
【–mirror】区别于【–bare】之处在于【–mirror】克隆出来的裸版本库对上游版本库进行了注册,这样可以在裸版本库中使用 git fecth 命令和上游版本库进行持续同步。