在这里插入图片描述

个人头像
✨ 孤廖: 个人主页

🎯 个人专栏: 《C++:从代码到机器》

🎯 个人专栏: 《Linux系统探幽:从入门到内核》

🎯 个人专栏: 《算法磨剑:用C++思考的艺术》

折而不挠,中不为下


在这里插入图片描述

前言:

在上篇博客中,我们跟着 “工具喵” 掌握了 Git 本地仓库的核心操作 —— 从文件的 add/commit、版本回退,到分支创建与冲突解决,搞定了单人开发时的版本管理需求。但实际企业开发中,光有本地仓库远远不够,多人协作时如何同步代码、避免冲突?远程仓库该怎么和本地链接?主流的开发模型又该如何落地?

本篇就聚焦这些问题,一边手把手教你用 HTTPS/SSH 链接本地与远程仓库,实操git push/git pull等交互指令;一边拆解 Git Flow、GiteeHub Flow 等企业级开发模型,帮你打通 “本地开发→远程协作” 的全流程,为团队协同打下基础

正文:

远程操作

我们⽬前所说的所有内容(⼯作区,暂存区,版本库等等),都是在本地!也就是在你的笔记本或者计算机上。⽽我们的 Git 其实是分布式版本控制系统!什么意思呢?

可以简单理解为,我们每个⼈的电脑上都是⼀个完整的版本库,这样你⼯作的时候,就不需要联⽹了,因为版本库就在你⾃⼰的电脑上。既然每个⼈电脑上都有⼀个完整的版本库,那多个⼈如何协作呢?⽐⽅说你在⾃⼰电脑上改了⽂件A,你的同事也在他的电脑上改了⽂件A,这时,你们俩之间只需把各⾃的修改推送给对⽅,就可以互相看到对⽅的修改了

在这里插入图片描述
分布式版本控制系统的安全性要⾼很多,因为每个⼈电脑⾥都有完整的版本库,某⼀个⼈的电脑坏掉了不要紧,随便从其他⼈那⾥复制⼀个就可以了

在实际使⽤分布式版本控制系统的时候,其实很少在两⼈之间的电脑上推送版本库的修改,因为可能你们俩不在⼀个局域⽹内,两台电脑互相访问不了。也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有⼀台充当“中央服务器”的电脑,但这个服务器的作⽤仅仅是⽤来⽅便“交换”⼤家的修改,没有它⼤家也⼀样⼲活,只是交换修改不⽅便⽽已。有了这个“中央服务器”的电脑,这样就不怕本地出现什么故障了(⽐如运⽓差,硬盘坏了,上⾯的所有东西全部丢失,包括git的所有内容)

新建远程仓库

搭建Gitee 平台下的远程仓库

新建远程项⽬仓库:

在这里插入图片描述

填写基本信息:

在这里插入图片描述
创建成功

在这里插入图片描述

从创建好的远程仓库中我们便能看到,之前在本地学习过的分⽀,也存在于远程仓库中并被管理起来了。刚创建的仓库有且只有⼀个默认的master分⽀

在这里插入图片描述

克隆远程仓库

克隆/下载远端仓库到本地,需要使⽤ git clone 命令,后⾯跟上我们的远端仓库的链接,远端仓库的链接可以从仓库中找到:选择“克隆/下载”获取远程仓库链接:

在这里插入图片描述
在这里插入图片描述

SSH 协议和 HTTPS 协议是 Git 最常使⽤的两种数据传输协议。SSH 协议使⽤了公钥加密和公钥登陆机制,体现了其实⽤性和安全性,使⽤此协议需要将我们的公钥放上服务器,由 Git 服务器进⾏管理。使⽤ HTTPS ⽅式时,没有要求,可以直接克隆下来。

  • 使⽤ HTTPS ⽅式:
[twg@VM-24-16-centos ~]$ ll
total 4
drwxrwxr-x 3 twg twg 4096 Oct 12 18:39 test
[twg@VM-24-16-centos ~]$ git clone https://gitee.com/Mr_Tangtang/boke.git
Cloning into 'boke'...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (8/8), done.
[twg@VM-24-16-centos ~]$ ll
total 8
drwxrwxr-x 4 twg twg 4096 Oct 12 20:02 boke
drwxrwxr-x 3 twg twg 4096 Oct 12 18:39 test

  • 使⽤ SSH ⽅式
[twg@VM-24-16-centos ~]$ ll
total 4
drwxrwxr-x 3 twg twg 4096 Oct 12 18:39 test
[twg@VM-24-16-centos ~]$ git clone git@gitee.com:Mr_Tangtang/boke.git
Cloning into 'boke'...
Permission denied (publickey).
fatal: Could not read from remote repository.

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

使⽤ SSH ⽅式克隆仓库,由于我们没有添加公钥到远端库中,服务器拒绝了我们的 clone 链接。需要我们设置⼀下

第⼀步:创建SSH Key。在⽤⼾主⽬录下,看看有没有.ssh⽬录,如果有,再看看这个⽬录下有没有id_rsa 和 id_rsa.pub 这两个⽂件,如果已经有了,可直接跳到下⼀步。如果没有,需要创建
SSH Key:
在这里插入图片描述

此时有 .ssh 但是.ssh 里没有id_rsa 和id_rsa.pub

//输入此命令,填写正确邮箱后 一直按回车即可
ssh-keygen -t rsa -C "your email"//注意这里的email 要是Gitee 你账号绑定的邮箱

[twg@VM-24-16-centos .ssh]$ clear
[twg@VM-24-16-centos .ssh]$ ls
known_hosts
[twg@VM-24-16-centos .ssh]$ ssh-keygen -t rsa -C "2248706487@qq.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/twg/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/twg/.ssh/id_rsa.
Your public key has been saved in /home/twg/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:qCQZdHNeN7WvRIH1BuAPUv/2BAHf/XHZf3MWrJFb1Qo 2248706487@qq.com
The key's randomart image is:
+---[RSA 2048]----+
|  . o . . ==*.. o|
| . . + . +.oE*oo*|
|  .   . . o ++=B=|
|   o   . . + +*.*|
|  o . . S   oo+.B|
|   o .     . o ++|
|    .       .   .|
|                 |
|                 |
+----[SHA256]-----+
[twg@VM-24-16-centos .ssh]$ ls -all
total 20
drwx------  2 twg twg 4096 Oct 12 21:00 .
drwx------ 10 twg twg 4096 Oct 12 20:42 ..
-rw-------  1 twg twg 1675 Oct 12 21:00 id_rsa
-rw-r--r--  1 twg twg  399 Oct 12 21:00 id_rsa.pub
-rw-r--r--  1 twg twg  536 Oct 11 20:54 known_hosts
[twg@VM-24-16-centos .ssh]$ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCs2j8o1cCmVbK+Z8WBi7tssbQI1klNPN21vE/hB6xaq1DuYmfYGkhPpNdlvj9oLEfC9w3/JWmAh3w6oS0uXxP7E6vsKZxd2i+CVwHrfOoNwoiL2Ki1Odom1GbcmJ1omwGubhHb3BISRrvj5708QWeBNkfOKkHfumlel3pIRzS2XI9wpU6/xzX2/CQVU5FDMWKsRo8kJCAlkQ0QchM8HX5RyqHI5yB8aKeiYvDPPvFHZskuv9oWPdjpmhLvEzn76wUUmwYtm2nuk7q6nBdjLjPhkZmgY0cCmQLkzZj/qhWN4inwgThUbM9eDucTldVNizf1RQRUYR+MHZU7eR1Bvdhl 2248706487@qq.com
[twg@VM-24-16-centos .ssh]$ 

顺利的话,可以在⽤⼾主⽬录⾥找到 .ssh ⽬录,⾥⾯有 id_rsa 和 id_rsa.pub 两个⽂件,这两个就是SSH Key的秘钥对, id_rsa 是私钥,不能泄露出去, id_rsa.pub 是公钥,可以放⼼地告诉任何⼈

在这里插入图片描述
在这里插入图片描述
点击确认后,需要对你进⾏认证,输⼊你的账号密码即可。⾄此,我们的准备⼯作全部做完,欢快的clone吧

[twg@VM-24-16-centos ~]$ ll
total 4
drwxrwxr-x 3 twg twg 4096 Oct 12 18:39 test
[twg@VM-24-16-centos ~]$ git clone git@gitee.com:Mr_Tangtang/boke.git
Cloning into 'boke'...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 8 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Receiving objects: 100% (8/8), done.
[twg@VM-24-16-centos ~]$ ll
total 8
drwxrwxr-x 4 twg twg 4096 Oct 12 21:04 boke
drwxrwxr-x 3 twg twg 4096 Oct 12 18:39 test


配置完公钥后 一定不要忘记 完成我们的目标 克隆远程仓库

done, 成功!如果有多个⼈协作开发,GitHub/Gitee 允许添加多个公钥,只要把每个⼈的电脑上的Key 都添加到 GitHub/Gitee,就可以在每台电脑上往 GitHub/Gitee 上提交推送了。当我们从远程仓库克隆后,实际上 Git 会⾃动把本地的 master 分⽀和远程的 master 分⽀对应起来,并且,远程仓库的默认名称是 origin 。在本地我们可以使⽤ git remote 命令,来查看远程库的信息,

twg@VM-24-16-centos ~]$ cd boke 
[twg@VM-24-16-centos boke]$ git remote
origin


或者,⽤ git remote -v 显⽰更详细的信息

[twg@VM-24-16-centos boke]$ git remote -v
origin	git@gitee.com:Mr_Tangtang/boke.git (fetch)
origin	git@gitee.com:Mr_Tangtang/boke.git (push)

上⾯显⽰了可以抓取和推送的origin的地址。如果没有推送权限,就看不到 push 的地址。推送是什么意思呢,我们继续往下看

向远程仓库推送

本地已经 clone 成功远程仓库后,我们便可以向仓库中提交内容,例如新增⼀个 file.txt ⽂件:

//新建文件
[twg@VM-24-16-centos boke]$ ll
total 8
-rw-rw-r-- 1 twg twg  948 Oct 12 21:04 README.en.md
-rw-rw-r-- 1 twg twg 1309 Oct 12 21:04 README.md
[twg@VM-24-16-centos boke]$ vim file.txt
[twg@VM-24-16-centos boke]$ git add .
//提交文件
[twg@VM-24-16-centos boke]$ git commit -m "creat file.txt"
[master a97658b] creat file.txt
 1 file changed, 1 insertion(+)
 create mode 100644 file.txt


提交时要注意,如果我们之前设置过全局的 name 和 e-mail,这两项配置需要和 gitee 上配置的⽤⼾名和邮箱⼀致,否则会出错。或者从来没有设置过全局的 name 和 e-mail,那么我们第⼀次提交时也会报错。这就需要我们重新配置下了,同样要注意需要和 gitee 上配置的⽤⼾名和邮箱⼀致。如何配置已讲过,在这⾥就不再赘述。到这⾥我们已经将内容提交⾄本地仓库中,如何将本地仓库的内容推送⾄远程仓库呢,需要使⽤ git push 命令,该命令⽤于将本地的分⽀版本上传到远程并合并,命令格式如下:

如何配置 已经在上篇讲过
萌系学 Git:从提交规范到团队协作,工具喵教你玩转企业级工具

git push <远程主机名> <本地分⽀名>:<远程分⽀名>
# 如果本地分⽀名与远程分⽀名相同,则可以省略冒号:
git push <远程主机名> <本地分⽀名>

此时我们要将本地的 master 分⽀推送到 origin 主机的 master 分⽀,则可以:

[twg@VM-24-16-centos boke]$ git push origin master
Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 274 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag e342b3a2
To git@gitee.com:Mr_Tangtang/boke.git
   56c9875..a97658b  master -> master

推送成功!这⾥由于我们使⽤的是 SSH 协议,是不⽤每⼀次推送都输⼊密码的,⽅便了我们的推送操作。如果你使⽤的是 HTTPS 协议,有个⿇烦地⽅就是每次推送都必须输⼊⼝令。

HTTP 虽然克隆方便 不需要公钥 但是每次 push都要输入 用户名和密码

在这里插入图片描述
代码已经被推送⾄远端了

拉取远程仓库

为了更好的演示该操作 我直接在远程仓库更改文件 但是这种做法不推荐

在 gitee 上点击 README.md ⽂件并在线修改它

在这里插入图片描述

此时,远程仓库是要领先于本地仓库⼀个版本,为了使本地仓库保持最新的版本,我们需要拉取下远
端代码,并合并到本地。Git 提供了 git pull 命令,该命令⽤于从远程获取代码并合并本地的版本。格式如下:

git pull <远程主机名> <远程分⽀名>:<本地分⽀名>
# 如果远程分⽀是与当前分⽀合并,则冒号后⾯的部分可以省略。
git pull <远程主机名> <远程分⽀名>

在这里插入图片描述

配置 Git

忽略特殊⽂件

在⽇常开发中,我们有些⽂件不想或者不应该提交到远端,⽐如保存了数据库密码的配置⽂件,那怎么让 Git 知道呢?在 Git ⼯作区的根⽬录下创建⼀个特殊的 .gitignore ⽂件,然后把要忽略的⽂件
名填进去,Git 就会⾃动忽略这些⽂件了

不需要从头写 .gitignore ⽂件,gitee 在创建仓库时就可以为我们⽣成,不过需要我们主动勾选⼀下:

在这里插入图片描述
如果当时没有选择这个选择,在⼯作区创建⼀个也是可以的。⽆论哪种⽅式,最终都可以得到⼀个完整的 .gitignore ⽂件,例如我们想忽略以 .so 和 .ini 结尾所有⽂件, .gitignore 的内容
如下:

# 省略选择模本的内容
...
# My configurations:
*.ini
*.so

在 .gitignore ⽂件中也可以指定某个确定的⽂件。

最后⼀步就是把 .gitignore 也提交到远端,就完成了

在这里插入图片描述
在这里插入图片描述
检验 .gitignore 的标准就是 git status 命令是不是说 working tree clean 。我们发现Git 并没有提⽰在⼯作区中有⽂件新增,果然 .gitignore ⽣效了!

但有些时候,你就是想添加⼀个⽂件到 Git,但由于这个⽂件被 .gitignore 忽略了,根本添加不了,那么可以⽤ -f 强制添加:

$ git add -f [filename]

或者你发现,可能是 .gitignore 写得有问题,需要找出来到底哪个规则写错了,⽐如说 a.so ⽂件是要被添加的,可以⽤ git check-ignore 命令检查:

hyb@139-159-150-152:~/git_teaching$ git check-ignore -v a.so
.gitignore:3:*.so a.so

Git 会告诉我们, .gitignore 的第3⾏规则忽略了该⽂件,于是我们就可以知道应该修订哪个规则。
还有些时候,当我们编写了规则排除了部分⽂件时,例如:

# 排除所有.开头的隐藏⽂件:
.*

但是我们发现 .* 这个规则把 .gitignore 也排除了。虽然可以⽤ git add -f 强制添加进去,但有强迫症的童鞋还是希望不要破坏 .gitignore 规则,这个时候,可以添加⼀条例外规则


# 排除所有.开头的隐藏⽂件:
.*
# 不排除.gitignore
!.gitignore

把指定⽂件排除在 .gitignore 规则外的写法就是 ! +⽂件名,所以,只需把例外⽂件添加进去即可

给命令配置别名

在我们使⽤ Git 期间,有些命令敲的时候着实让⼈头疼(太⻓了。。),幸运的是,git⽀持对命令进⾏简化!

举个例⼦,将 git status 简化为 git st ,对应的命令为:

$ git config --global alias.st status

在这里插入图片描述
–global 参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有⽤。如果不加,那只针对当前的仓库起作⽤。

标签管理

理解标签

标签 tag ,可以简单的理解为是对某次 commit 的⼀个标识,相当于起了⼀个别名。例如,在项⽬发布某个版本的时候,针对最后⼀次 commit 起⼀个 v1.0 这样的标签来标识⾥程碑的意义。

这有什么⽤呢?相较于难以记住的 commit id , tag 很好的解决这个问题,因为 tag ⼀定要给⼀个让⼈容易记住,且有意义的名字。当我们需要回退到某个重要版本时,直接使⽤标签就能很快定位
到。

创建标签
  • 在Git中打标签⾮常简单,⾸先,切换到需要打标签的分⽀上
  • 然后,敲命令 git tag [name] 就可以打⼀个新标签
[twg@VM-24-16-centos boke]$ git branch 
* master
[twg@VM-24-16-centos boke]$ git tag v1.0
[twg@VM-24-16-centos boke]$ git tag
v1.0


默认标签是打在最新提交的 commit 上的。那如何在指定的commit上打标签呢?⽅法是找到历史提交的commit id,然后打上就可以了,⽰例如下

git log --pretty=oneline --abbrev-commit
# 历史记录
hyb@139-159-150-152:~/git_teaching$ git log --pretty=oneline --abbrev-commit
97811ab (HEAD -> master, tag: v1.0, origin/master, origin/HEAD) add .gitignore
60e6b0a update README.md.
7ce3183 create file.txt
c6ce3f0 Initial commit
# 对 Initial commit 这次提交打标签
hyb@139-159-150-152:~/git_teaching$ git tag v0.9 c6ce3f0
hyb@139-159-150-152:~/git_teaching$ git tag
v0.9
v1.0

注意,标签不是按时间顺序列出,⽽是按字⺟排序的。
可以⽤ git show [tagname] 查看标签信息。


[twg@VM-24-16-centos boke]$ git show v1.0
commit 3420e96bba3778209f5635a5013a16f5aaf38a0d
Author: twg <2248706487@qq.com>
Date:   Sun Oct 12 21:29:00 2025 +0800

    test ignore

diff --git a/.gitignore b/.gitignore
index 259148f..9badcbb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*.so
 # Prerequisites
 *.d

Git 还提供可以创建带有说明的标签,⽤-a指定标签名,-m指定说明⽂字,格式为

git tag -a [name] -m "XXX" [commit_id]

另外,打完标签之后,使⽤ tree .git 命令查看⼀下你的本地库有什么变化,肯定能帮助你理解!

在这里插入图片描述

操作标签

如果标签打错了,也可以删除:

[twg@VM-24-16-centos boke]$ git tag
show
v1.0
[twg@VM-24-16-centos boke]$ git tag -d show
Deleted tag 'show' (was 3420e96)
[twg@VM-24-16-centos boke]$ git tag
v1.0

因为创建的标签都只存储在本地,不会⾃动推送到远程。所以,打错的标签可以在本地安全删除。如果要推送某个标签到远程,使⽤命令 git push origin

[twg@VM-24-16-centos boke]$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag 0c4d2fa0
To git@gitee.com:Mr_Tangtang/boke.git
 * [new tag]         v1.0 -> v1.0

此时,查看远端码云,看到了标签已经被更新!完美!

在这里插入图片描述
当然,如果你本地有很多标签,也可以⼀次性的全部推送到远端:

git push origin --tags

如果标签已经推送到远程,要删除远程标签就⿇烦⼀点,先从本地删除:

[twg@VM-24-16-centos boke]$ git tag -d v1.0
Deleted tag 'v1.0' (was 3420e96)

然后,从远程删除。删除命令也是push,但是格式如下:

[twg@VM-24-16-centos boke]$ git push origin :refs/tags/v1.0
remote: Powered by GITEE.COM [1.1.5]
remote: Set trace flag da494ea3
To git@gitee.com:Mr_Tangtang/boke.git
 - [deleted]         v1.0

注意 这句命令 有个 :

删除 本身也是一种修改 所以可以更新 git维护的文件

在这里插入图片描述

码云看已经删除了

多⼈协作

多⼈协作⼀

⽬前,我们所完成的⼯作如下:

  • 基本完成 Git 的所有本地库的相关操作,git基本操作,分⽀理解,版本回退,冲突解决等等
  • 申请码云账号,将远端信息clone到本地,以及推送和拉取。
    是时候⼲最重要的⼀件事情了,实现多⼈协作开发!为了做这件事情,我们需要先做⼀些准备⼯作。我们之前已经将项⽬ clone 到了指定⽬录,如
[twg@VM-24-16-centos boke]$ pwd
/home/twg/boke

我们在 windows 环境下,再 clone 同⼀个项⽬仓库,来模拟和你⼀起协作开发的另⼀名⼩伙伴:
在这里插入图片描述
在这里插入图片描述
Clone 成功~!

在这里插入图片描述
注意,课件中是模拟了两个⽤⼾,实际开发中,每个⽤⼾都有⾃⼰的gitee/github账号,如果要多⼈进⾏协同开发,必须要将⽤⼾添加进开发者,⽤⼾才有权限进⾏代码提交

在这里插入图片描述
在这里插入图片描述
到此,相当于有了两个⽤⼾,分别在 linux 和 windows 上针对于同项⽬进⾏协作开发,我们的准备⼯作到此结束。
⽬前,我们的仓库中只有⼀个 master 主分⽀,但在实际的项⽬开发中,在任何情况下其实都是不允许直接在 master 分⽀上修改代码的,这是为了保证主分⽀的稳定。所以在开发新功能时,常常会新建其他分⽀,供开发时进⾏迭代使⽤。
那么接下来,就让我们在 gitee 上新建 dev 远程分⽀供我们使⽤

在这里插入图片描述
创建成功的远程分⽀是可以通过 Git 拉取到本地来,以实现完成本地开发⼯作。
接下来让我们和另⼀名开发的⼩伙伴都将远程仓库进⾏⼀次拉取操作,并观察结果:

  • 对于我们要操作的是:
[twg@VM-24-16-centos boke]$ pwd
/home/twg/boke
[twg@VM-24-16-centos boke]$ ^C
[twg@VM-24-16-centos boke]$ git pull
From gitee.com:Mr_Tangtang/boke
 * [new branch]      dev        -> origin/dev
Already up-to-date.
[twg@VM-24-16-centos boke]$ git checkout -b deb origin/dev
Branch deb set up to track remote branch dev from origin.
Switched to a new branch 'deb'
[twg@VM-24-16-centos boke]$ git branch
* deb
  master
[twg@VM-24-16-centos boke]$ git branch -vv
* deb    3420e96 [origin/dev] test ignore
  master 3420e96 [origin/master] test ignore


拉取后便可以看到远程的 dev 分⽀,接着切换到 dev 分⽀供我们进⾏本地开发。要说明的是,我们切换到的是本地的 dev 分⽀,根据⽰例中的操作,会将本地分⽀和远程分⽀的进⾏关系链接。

git pull 的作用

1,拉取远程仓库与本地仓库关联的当前分支的所有改变文件
2.拉取远程仓库的内容 即 各个新的分支 但是不建立联系 想要建立链接还要手动操作

在这里插入图片描述
现在,你和你的⼩伙伴就可以在 dev 上完成开发。
⾸先,让我们在 dev 分⽀上进⾏⼀次开发,并 push 到远程例如:

hyb@139-159-150-152:~/git_teaching$ vim file.txt 
hyb@139-159-150-152:~/git_teaching$ cat file.txt 
hello git
complete the first function!
hyb@139-159-150-152:~/git_teaching$ git add file.txt
hyb@139-159-150-152:~/git_teaching$ git commit -m "first function"
[dev 305f78a] first function
 1 file changed, 1 deletion(-)
hyb@139-159-150-152:~/git_teaching$ git push origin dev # 将dev分⽀推送到远端
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 287 bytes | 287.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
 cc3be59..305f78a dev -> dev

让我们来看看码云上⽬前仓库的状态:

dev 分支上
在这里插入图片描述
⾄此,我们已经将代码成功推送⾄码云,接下来假如你的⼩伙伴要和你协同开发,碰巧也要对 file.txt⽂件作修改,并试图推送,例如:
在这里插入图片描述
这时推送失败,因为你的⼩伙伴的最新提交和你推送的提交有冲突,解决办法也很简单,Git已经提⽰我们,先⽤ git pull 把最新的提交从 origin/dev 抓下来,然后,在本地进⾏合并,并解决冲突,再推送。操作如下

在这里插入图片描述
解决冲突,重新推送:

在这里插入图片描述
此时,我们看到远端的码云已经能看到我们的新提交了

最后不要忘记,虽然我们是在分⽀上进⾏多⼈协作开发,但最终的⽬的是要将开发后的代码合并到master上去,让我们的项⽬运⾏最新的代码。接下来我们就需要做这件事情了:

# 切换⾄ master分⽀, pull ⼀下,保证本地的master是最新内容。
# 合并前这么做是⼀个好习惯
hyb@139-159-150-152:~/git_teaching$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
hyb@139-159-150-152:~/git_teaching$ git pull
Already up to date.
# 切换⾄ dev 分⽀, 合并 master 分⽀
# 这么做是因为如果有冲突,可以在dev分⽀上进⾏处理,⽽不是在在master上解决冲突。
# 这么做是⼀个好习惯
hyb@139-159-150-152:~/git_teaching$ git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.
hyb@139-159-150-152:~/git_teaching$ git merge master
Already up to date.
# 切换⾄ master 分⽀,合并 dev 分⽀
hyb@139-159-150-152:~/git_teaching$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
hyb@139-159-150-152:~/git_teaching$ git merge dev
Updating 7388a31..72c5345
Fast-forward
 file.txt | 2 ++
 1 file changed, 2 insertions(+)
hyb@139-159-150-152:~/git_teaching$ cat file.txt
hello git
complete the first function!
complete the second function!
# 将 master 分⽀推送⾄远端
hyb@139-159-150-152:~/git_teaching$ git status
On branch master
Your branch is ahead of 'origin/master' by 4 commits.
 (use "git push" to publish your local commits)
nothing to commit, working tree clean
hyb@139-159-150-152:~/git_teaching$ git push origin master 
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
 7388a31..72c5345 master -> master
hyb@139-159-150-152:~/git_teaching$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean

此时,查看远端仓库,master已经是最新代码了
此时,dev 分⽀对于我们来说就没⽤了, 那么 dev 分⽀就可以被删除掉。我们可以直接在远程仓库中将dev分⽀删除掉:

总结⼀下,在同⼀分⽀下进⾏多⼈协作的⼯作模式通常是这样

  • ⾸先,可以试图⽤ git push origin branch-name 推送⾃⼰的修改;
  • 如果推送失败,则因为远程分⽀⽐你的本地更新,需要先⽤ git pull 试图合并
  • 如果合并有冲突,则解决冲突,并在本地提交;
  • 没有冲突或者解决掉冲突后,再⽤git push origin branch-name推送就能成功!
  • 功能开发完毕,将分⽀ merge 进 master,最后删除分⽀
多⼈协作⼆

⼀般情况下,如果有多需求需要多⼈同时进⾏开发,是不会在⼀个分⽀上进⾏多⼈开发,⽽是⼀个需求或⼀个功能点就要创建⼀个 feature 分⽀。
现在同时有两个需求需要你和你的⼩伙伴进⾏开发,那么你们俩便可以各⾃创建⼀个分⽀来完成⾃⼰的⼯作。在上个部分我们已经了解了可以从码云上直接创建远程分⽀,其实在本地创建的分⽀也可以通过推送的⽅式发送到远端。在这个部分我们就来⽤⼀下这种⽅式。

  • 对于你来说,可以进⾏以下操作:
# 新增本地分⽀ feature-1 并切换
hyb@139-159-150-152:~/git_teaching$ git branch 
 dev
* master
hyb@139-159-150-152:~/git_teaching$ git checkout -b feature-1
Switched to a new branch 'feature-1'
# 新增需求内容-创建function1⽂件
hyb@139-159-150-152:~/git_teaching$ vim function1
hyb@139-159-150-152:~/git_teaching$ cat function1 
Done!
# 将 feature-1 分⽀推送到远端
hyb@139-159-150-152:~/git_teaching$ git add function1
hyb@139-159-150-152:~/git_teaching$ git commit -m"add function1"
[feature-1 12ed0db] add function1
 1 file changed, 1 insertion(+)
 create mode 100644 function1
hyb@139-159-150-152:~/git_teaching$ git push origin feature-1 
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 270 bytes | 270.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
remote: Create a pull request for 'feature-1' on Gitee by visiting:
remote: https://gitee.com/hyb91/git_teaching/pull/new/hyb91:feature-
1...hyb91:master
To gitee.com:hyb91/git_teaching.git
 * [new branch] feature-1 -> feature-1
  • 对于⼩伙伴来说,可以进⾏以下操作:
    在这里插入图片描述
    此时,在本地,你看不⻅他新建的⽂档,他看不⻅你新建的⽂档。并且推送各⾃的分⽀时,并没有任何冲突,你俩互不影响,⽤起来很舒服!!

再来看下远端码云上此时的状态:
在这里插入图片描述

  • 对于你的feature-1:
    在这里插入图片描述
  • 对于⼩伙伴的 feature-2 分⽀:
    在这里插入图片描述
    正常情况下,你俩就可以在⾃⼰的分⽀上进⾏专业的开发了!
    但天有不测⻛云,你的⼩伙伴突然⽣病了,但需求还没开发完,需要你帮他继续开发,于是他便把feature-2 分⽀名告诉你了。这时你就需要在⾃⼰的机器上切换到 feature-2 分⽀帮忙继续开发,要做的操作如下
    在这里插入图片描述
# 可以看到远程已经有了feature-2
hyb@139-159-150-152:~/git_teaching$ git branch -a
 dev
* feature-1
 master
 remotes/origin/HEAD -> origin/master
 remotes/origin/dev
 remotes/origin/feature-1
 remotes/origin/feature-2
 remotes/origin/master
 
# 切换到feature-2分⽀上,可以和远程的feature-2分⽀关联起来,
# 否则将来只使⽤ git push 推送内容会失败
hyb@139-159-150-152:~/git_teaching$ git checkout -b feature-2 origin/feature-2
Branch 'feature-2' set up to track remote branch 'feature-2' from 'origin'.
Switched to a new branch 'feature-2'
hyb@139-159-150-152:~/git_teaching$ ls
a.so b.ini file.txt function2 README.en.md README.md

切换成功后,便可以看⻅ feature-2 分⽀中的 function2 ⽂件了,接着就可以帮⼩伙伴进⾏开发:

# 继续开发
hyb@139-159-150-152:~/git_teaching$ vim function2 
hyb@139-159-150-152:~/git_teaching$ cat function2 
Done!
Help done!
# 推送内容
hyb@139-159-150-152:~/git_teaching$ git add function2
hyb@139-159-150-152:~/git_teaching$ git commit -m"modify function2"
[feature-2 1079ae7] modify function2
 1 file changed, 2 insertions(+), 1 deletion(-)
hyb@139-159-150-152:~/git_teaching$ git push origin feature-2
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 262 bytes | 262.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
 e1233f1..1079ae7 feature-2 -> feature-2

查看远程状态,推送成功了:

feature-2分支上:
在这里插入图片描述
这时,你的⼩伙伴已经修养的差不多,可以继续进⾏⾃⼰的开发⼯作,那么他⾸先要获取到你帮他开发的内容,然后接着你的代码继续开发。或者你已经帮他开发完了,那他也需要在⾃⼰的电脑上看看你帮他写的代码:

在这里插入图片描述

Pull ⽆效的原因是⼩伙伴没有指定本地 feature-2 分⽀与远程 origin/feature-2 分⽀的链接,根据提⽰,设置feature-2和origin/feature-2的链接即可:

在这里插入图片描述
⽬前,⼩伙伴的本地代码和远端保持严格⼀致。你和你的⼩伙伴可以继续在不同的分⽀下进⾏协同开发了。各⾃功能开发完毕后,不要忘记我们需要将代码合并到master中才算真正意义上的开发完毕。由于你的⼩伙伴率先开发完毕,于是开始 merge :

在这里插入图片描述
此时远程仓库的状态:

master分支上:
在这里插入图片描述
当你的⼩伙伴将其代码 merge 到 master 后,这是你也开发完成了,也需要进⾏ merge 到
master 操作,于是你:

# 切换⾄ master分⽀, pull ⼀下,保证本地的master是最新内容。
# 合并前这么做是⼀个好习惯
hyb@139-159-150-152:~/git_teaching$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
hyb@139-159-150-152:~/git_teaching$ git pull
From gitee.com:hyb91/git_teaching
 72c5345..29006bd master -> origin/master
Updating 72c5345..29006bd
Fast-forward
 function2 | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 function2
# 切换⾄ feature-1 分⽀, 合并 master 分⽀
# 这么做是因为如果有冲突,可以在feature-1分⽀上进⾏处理,⽽不是在在master上解决冲突。
# 这么做是⼀个好习惯
hyb@139-159-150-152:~/git_teaching$ git checkout feature-1
Switched to branch 'feature-1'
Your branch is up to date with 'origin/feature-1'.
hyb@139-159-150-152:~/git_teaching$ git merge master 
Merge made by the 'recursive' strategy.
 function2 | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 function2
hyb@139-159-150-152:~/git_teaching$ ls
a.so b.ini file.txt function1 function2 README.en.md README.md
# 1、由于feature-1分⽀已经merge进来了新内容,为了保证远程分⽀最新,所以最好push⼀下。
# 2、要 push 的另⼀个原因是因为在实际的开发中,master的merge操作⼀般不是由我们⾃⼰在本地
进⾏操作,
# 其他⼈员或某些平台merge时,操作的肯定是远程分⽀,所以就要保证远程分⽀的最新。
# 3、如果 merge 出现冲突,不要忘记需要commit才可以push!!
hyb@139-159-150-152:~/git_teaching$ git status
On branch feature-1
Your branch is ahead of 'origin/feature-1' by 4 commits.
 (use "git push" to publish your local commits)
nothing to commit, working tree clean
hyb@139-159-150-152:~/git_teaching$ git push origin feature-1
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 299 bytes | 299.00 KiB/s, done.
Total 2 (delta 1), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
 ea75a35..4b4c3d4 feature-1 -> feature-1
 
# 切换⾄ master 分⽀,合并 feature-1 分⽀
hyb@139-159-150-152:~/git_teaching$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
hyb@139-159-150-152:~/git_teaching$ git merge feature-1
Updating 29006bd..4b4c3d4
Fast-forward
 function1 | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 function1
hyb@139-159-150-152:~/git_teaching$ ls
a.so b.ini file.txt function1 function2 README.en.md README.md
# 将 master 分⽀推送⾄远端
hyb@139-159-150-152:~/git_teaching$ git status 
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
 (use "git push" to publish your local commits)
nothing to commit, working tree clean
hyb@139-159-150-152:~/git_teaching$ git push origin master 
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
 29006bd..4b4c3d4 master -> master
hyb@139-159-150-152:~/git_teaching$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean

此时远程仓库的状态:

master分支上:
在这里插入图片描述

此时, feature-1 和 feature-2 分⽀对于我们来说就没⽤了, 那么我们可以直接在远程仓库中将dev分⽀删除掉:
这就是多⼈协作的⼯作模式,⼀旦熟悉了,就⾮常简单。

远程分⽀删除后,本地 git branch -a 依然能看到的解决办法

当前我们已经删除了远程的⼏个分⽀,使⽤ git branch -a 命令可以查看所有本地分⽀和远程分⽀,但发现很多在远程仓库已经删除的分⽀在本地依然可以看到。例如:
在这里插入图片描述
在这里插入图片描述
使⽤命令 git remote show origin ,可以查看remote地址,远程分⽀,还有本地分⽀与之相
对应关系等信息


hyb@139-159-150-152:~/git_teaching$ git remote show origin 
* remote origin
 Fetch URL: git@gitee.com:hyb91/git_teaching.git
 Push URL: git@gitee.com:hyb91/git_teaching.git
 HEAD branch: master
 Remote branches:
 master tracked
 refs/remotes/origin/dev stale (use 'git remote prune' to remove)
 refs/remotes/origin/feature-1 stale (use 'git remote prune' to remove)
 refs/remotes/origin/feature-2 stale (use 'git remote prune' to remove)
 Local branches configured for 'git pull':
 dev merges with remote dev
 feature-1 merges with remote feature-1
 feature-2 merges with remote feature-2
 master merges with remote master
 Local ref configured for 'git push':
 master pushes to master (up to date)

此时我们可以看到那些远程仓库已经不存在的分⽀,根据提⽰,使⽤ git remote prune
origin 命令:

hyb@139-159-150-152:~/git_teaching$ git remote prune origin 
Pruning origin
URL: git@gitee.com:hyb91/git_teaching.git
 * [pruned] origin/dev
 * [pruned] origin/feature-1
 * [pruned] origin/feature-2
hyb@139-159-150-152:~/git_teaching$ git branch -a
 dev
 feature-1
 feature-2
* master
 remotes/origin/HEAD -> origin/master
 remotes/origin/master

这样就删除了那些远程仓库不存在的分⽀。对于本地仓库的删除,之前的课程已经学过了,⼤家可以⾃⾏从操作。

企业级开发模型

讲个故事
我们知道,⼀个软件从零开始到最终交付,⼤概包括以下⼏个阶段:规划、编码、构建、测试、发布、部署和维护。
最初,程序⽐较简单,⼯作量不⼤,程序员⼀个⼈可以完成所有阶段的⼯作。但随着软件产业的⽇益发展壮⼤,软件的规模也在逐渐变得庞⼤。软件的复杂度不断攀升,⼀个⼈已经hold不住了,就开始出现了精细化分⼯。如下图所⽰:

在这里插入图片描述
但在传统的 IT 组织下,开发团队(Dev)和运维团队(Ops)之间诉求不同:

  • 开发团队(尤其是敏捷团队)注重变化
  • 运维团队追求稳定
    双⽅往往存在利益的冲突。⽐如,精益和敏捷的团队把持续交付作为⽬标,⽽运维团队则为了线上的稳定⽽强调变更控制。部⻔墙由此建⽴起来,这当然不利于 IT 价值的最⼤化。
    为了弥合开发和运维之间的鸿沟,需要在⽂化、⼯具和实践⽅⾯的系列变⾰⸺DevOps正式登上舞台。
    DevOps(Development和Operations的组合词)是⼀种重视“软件开发⼈员(Dev)”和“IT运维技术⼈员(Ops)”之间沟通合作的⽂化、运动或惯例。透过⾃动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。在DevOps的软件开发过程包含计划、编码、构建、测试、预发布、发布、运维、监控,由此可⻅DevOps的强⼤。讲了这么多,这个故事到底和我们课程的主题 Git 有什么关系呢?
    举⼀个很简单的例⼦就能说明这个问题。⼀个软件的迭代,在我们开发⼈员看来,说⽩了就是对代码进⾏迭代,那么就需要对代码进⾏管理。如何管理我们的代码呢,那不就是 Git(分布式版本控制系统) !所以 Git 对于我们开发⼈员来说其重要性就不⾔⽽喻了。
系统开发环境

⾔归正传,对于开发⼈员来说,在系统开发过程中最常⽤的⼏个环境必须要了解⼀下:

  1. 开发环境:开发环境是程序猿们专⻔⽤于⽇常开发的服务器。为了开发调试⽅便,⼀般打开全部错误报告和测试⼯具,是最基础的环境。
  2. 测试环境:⼀个程序在测试环境⼯作不正常,那么肯定不能把它发布到⽣产机上。该环境是开发环境到⽣产环境的过渡环境
  3. 预发布环境:该环境是为避免因测试环境和线上环境的差异等带来的缺陷漏测⽽设⽴的⼀套环境。其配置等基本和⽣产环境⼀致,⽬的是能让我们发正式环境时更有把握!所以预发布环境是你的产品质量最后⼀道防线,因为下⼀步你的项⽬就要上线了。要注意预发布环境服务器不在线上集成服务器范围之内,为单独的⼀些机器。
  4. ⽣产环境:是指正式提供对外服务的线上环境,例如我们⽬前在移动端或PC端能访问到的APP都是⽣产环境
    在这里插入图片描述
    对于规模稍微⼤点的公司来说,可不⽌这么⼏个环境,⽐如项⽬正式上线前还存在仿真/灰度环境,再⽐如还存在多套测试环境,以满⾜不同版本上线前测试的需要。
    ⼀个项⽬的开始从设计开始,⽽⼀个项⽬的成功则从测试开始。⼀套良好的测试体系可以将系统中绝⼤部分的致命Bug 解决在系统上线之前。测试系统的完善和成熟也是衡量⼀个软件企业整体⽔平的重要指标之⼀,测试往往被忽视,因为它对可以的隐性、对软件开发企业不产⽣直接的效益,但是它却是软件质量的最终保障,乃⾄项⽬能否成功的重要因素!
Git分支设计规范

环境有了概念后,那么对于开发⼈员来说,⼀般会针对不同的环境来设计分⽀,例如:
在这里插入图片描述
在这里插入图片描述
注:以上表格中的分⽀和环境的搭配仅是常⽤的⼀种,可视情况⽽定不同的策略。

master 分⽀:

  • master 为主分⽀,该分⽀为只读且唯⼀分⽀。⽤于部署到正式发布环境,⼀般由合并
    release 分⽀得到。
  • 主分⽀作为稳定的唯⼀代码库,任何情况下不允许直接在 master 分⽀上修改代码
  • 产品的功能全部实现后,最终在master分⽀对外发布,另外所有在master分⽀的推送应该打标签(tag)做记录,⽅便追溯。
  • master 分⽀不可删除

release 分⽀

  • release 为预发布分⽀,基于本次上线所有的 feature 分⽀合并到 develop 分⽀之后,基
    于 develop 分⽀创建。可以部署到测试或预发布集群
  • 命名以 release/ 开头,建议的命名规则: release/version_publishtime 。
  • release 分⽀主要⽤于提交给测试⼈员进⾏功能测试。发布提测阶段,会以 release 分⽀代码为基准进⾏提测
  • 如果在 release 分⽀测试出问题,需要回归验证 develop 分⽀看否存在此问题。
  • release 分⽀属于临时分⽀,产品上线后可选删除

develop 分⽀

  • develop 为开发分⽀,基于master分⽀创建的只读且唯⼀分⽀,始终保持最新完成以及bug 修复后的代码。可部署到开发环境对应集群。
  • 可根据需求⼤⼩程度确定是由 feature 分⽀合并,还是直接在上⾯开发(⾮常不建议)

feature 分⽀

  • feature 分⽀通常为新功能或新特性开发分⽀,以 develop 分⽀为基础创建 feature 分支
  • 命名。以 feature/ 开头,建议的命名规则: feature/user_createtime_feature 。
  • 新特性或新功能开发完成后,开发⼈员需合到 develop 分⽀
  • ⼀旦该需求发布上线,便将其删除。

hotfix 分⽀

  • hotfix 分⽀为线上 bug 修复分⽀或叫补丁分⽀,主要⽤于对线上的版本进⾏ bug 修复。当线上出现紧急问题需要⻢上修复时,需要基于 master 分⽀创建 hotfix 分⽀。
  • 命名以 hotfix/ 开头,建议的命名规则: hotfix/user_createtime_hotfix
  • 当问题修复完成后,需要合并到 master 分⽀和 develop 分⽀并推送远程。⼀旦修复上线,便将其删除

⼀张图总结:

在这里插入图片描述
其实,以上跟⼤家讲解的是企业级常⽤的⼀种 Git 分⽀设计规范:Git Flow 模型。但要说的是,该模型并不是适⽤于所有的团队、所有的环境和所有的⽂化。如果你采⽤了持续交付,你会想要⼀些能够尽可能简化交付过程的东西。有些⼈喜欢基于主⼲的开发模式,喜欢使⽤特性标志。然⽽,从测试的⻆度来看,这些反⽽会把他吓⼀跳。关键在于站在你的团队或项⽬的⻆度思考:这种分⽀模型可以帮助你们解决哪些问题?它会带来哪些
问题?这种模式为哪种开发提供更好的⽀持?你们想要⿎励这种⾏为吗?你选择的分⽀模型最终都是为了让⼈们更容易地进⾏软件协作开发。因此,分⽀模型需要考虑到使⽤者的需求,⽽不是盲⽬听信某些所谓的“成功的分⽀模型
”。所以对于不同公司,规范是会有些许差异,但万变不离其宗,是为了效率与稳定

企业级项⽬管理实战

Gitee企业版免费

在这里插入图片描述
企业名称可随意填写⼀个测试名称,只要能通过即可。注意,多⼈协作开发,需要将多⼈账号拉⼊⼀个企业下才⾏。如何添加成员后⾯会跟⼤家讲解。

创建项⽬

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建仓库

在这里插入图片描述
在这里插入图片描述

创建的仓库可以关联到某个项⽬中被管理

添加成员
  • 添加企业成员
    在这里插入图片描述
    在这里插入图片描述

申请后需要负责⼈审批通过

  • 添加项⽬成员
    在这里插入图片描述
    在这里插入图片描述
  • 添加仓库开发人员

在这里插入图片描述在这里插入图片描述

拓展阅读

其他DevOps研发平台
腾讯coding
阿里云效
拓展实践

阿⾥⻜流flow分⽀模型,及项⽬版本管理实践:

结语:

看到这里,你已经掌握了 Git 远程协作的关键技能 —— 从链接远程仓库、同步代码,到用标签管理版本、靠分支规范支撑多人开发,这些操作正是企业级项目中 “代码协同” 的核心环节。比如 SSH 免密配置让推送更高效,.gitignore 规避敏感文件提交,而 Git Flow 分支模型则像 “交通规则”,让多需求并行开发时既有序又安全。

如果在实操中遇到 “远程分支删除后本地仍显示”“push 时权限被拒” 等问题,不妨回头再梳理本文的git remote prune或公钥配置步骤。也欢迎在评论区分享你的协作故事,我们一起把 Git 从 “能用” 变成 “用得顺手”,让它成为团队开发的 “润滑剂”~

在这里插入图片描述

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐