【Git】多人协作 -- 详解
一、多人协作(1)
⽬前,我们所完成的工作如下:
-
基本完成 Git 的所有本地库的相关操作,git 基本操作,分支理解,版本回退,冲突解决等等。
-
申请码云账号,将远端信息 clone 到本地,以及推送和拉取。
是时候做最重要的一件事情了,实现多人协作开发。
为了做这件事情,需要先做一些准备工作。我们之前已经将项目 clone 到了指定目录,如:
完成任务:
在 Windows 环境下,再 clone 同一个项目仓库,来模拟和我们⼀起协作开发的另一名小伙伴:
找一个新的文件夹,进入文件夹后右键:
clone 成功:
注意:这里是模拟了两个用户。但在实际开发中,每个用户都有属于自己的 gitee/github 账号,如果要多人进行协同开发,必须要将用户添加进开发者,用户才有权限进行代码提交:
邀请用户:
到此,相当于有了两个用户,分别在 Linux 和 Windows 上针对于同个项目进行协作开发,我们的准备工作到此结束。
目前,我们的仓库中只有一个 master 主分支,但在实际的项目开发中,在任何情况下其实都是不允许直接在 master 分支上修改代码的,这是为了保证主分支的稳定。所以在开发新功能时,常常会新建其他分支,供开发时进行迭代使用。那么接下来,就让我们在 gitee 上新建 dev 远程分支供我们使用:

创建成功:

创建成功的远程分支是可以通过 Git 拉取到本地来,以实现完成本地开发工作。接下来让我们和另一名开发的小伙伴都将远程仓库进行一次拉取操作。
对于我们要操作的是:
注意 :之前讲的 git branch 只能查看本地分支,要查看远程分⽀需要加上 -r 选项。但前提是要 pull ⼀下拉取最新的远端仓库,才能看到最新的内容。
拉取后便可以看到远程的 dev 分支,接着切换到 dev 分支供我们进行本地开发。要说明的是,我们切换到的是本地的 dev 分支,根据示例中的操作,会将本地分支和远程分支的进行关系链接。
对于另一名小伙伴要操作的是:
现在,我们就可以和小伙伴在 dev 上完成开发。
首先,让我们在 dev 分支上进行一次开发,并 push 到远程:
来看看码云上目前仓库的状态:
至此,我们已经将代码成功推送至码云,接下来假如小伙伴要和我们协同开发,碰巧也要对 file.txt 文件做修改,并试图推送:
这时推送失败,因为小伙伴的最新提交和你推送的提交有冲突,解决办法也很简单,Git 已经给出了提示,先用 git pull 把最新的提交从 origin/dev 抓下来,然后再在本地进行合并,并解决冲突,再推送。操作如下:
解决冲突,重新推送:
此时,在远端的码云就能够看到我们的新提交了:
由此,两名开发者已经开始可以进行协同开发了,不断的 git pull/add/commit/push,遇到冲突就使用之前讲的冲突处理解决掉冲突。
对于我们来说,要想看到小伙伴的代码,只需要 pull 一下即可:
最后不要忘记,虽然我们是在分支上进行多人协作开发,但最终的目的是要将开发后的代码合并到 master 上去,让我们的项目运行最新的代码。接下来我们就需要做这件事情了:
切换至 master 分支,pull 一下,保证本地的 master 是最新内容,合并前这么做是一个好习惯。
切换至 dev 分支,合并 master 分⽀,这么做是因为如果有冲突的话,可以在 dev 分支上进行处理,而不是在 master 上解决冲突,这么做也是一个好习惯。
切换至 master 分支,合并 dev:
将 master 分支推送到远端:
此时再查看远端仓库,master 已经是最新代码了:
此时,dev 分支对于我们来说就没用了, 那么 dev 分支就可以被删除掉。我们可以直接在远程仓库中将 dev 分支删除掉:
总结一下,在同一分支下进行多人协作的工作模式通常是这样:
- 首先,可以试图用 git push origin branch-name 推送自己的修改。
- 如果推送失败,是因为远程分支比我们的本地更新,需要先用 git pull 试图合并。
- 如果合并有冲突,就解决冲突,并在本地提交。(解决冲突是一件很麻烦的事情)
- 没有冲突或者解决掉冲突后,再用 git push origin branch-name 推送就能成功。
- 功能开发完毕,将分支 merge 进 master,最后删除分支。
二、多人协作(2)
完成任务:
一般情况下,如果有多需求需要多人同时进行开发,是不会在一个分支上进行多人开发,而是一个需求或一个功能点就要创建一个 feature 分支。现在同时有两个需求需要我们和小伙伴进行开发,那么我俩便可以各自创建一个分支来完成自己的工作。前面我们已经了解了可以从码云上直接创建远程分支,其实在本地创建的分子也可以通过推送的方式发送到远端。在这个部分我们就来用一下这种方式。
对于我而言,可以进行以下操作:
- 新增本地分支 feature-1 并切换
- 新增需求内容 —— 创建 feature1 文件
- 将 feature-1 分支推送到远端
对于小伙伴来说,可以进行以下操作:
- 创建并切换到 feature-2 分支
- 在分支下为需求新增 function2 文档
- 将 feature-2 分支推送至远端
此时在本地看不见伙伴新建的文档,他也看不见我们新建的文档,并且推送各自的分支时,并没有任何冲突,我俩不受对方的影响,用起来就很舒服。
再来看下远端码云上此时的状态:
对于我们的 feature-1 分支:
对于小伙伴的 feature-2 分支:

正常情况下,我俩就可以在自己的分支上进行专业的开发了。但万一有天小伙伴突然生病了,但需求还没开发完,需要我帮他继续开发,于是他就把 feature-2 分支名告诉我。这时我就需要在自己的机器上切换到 feature-2 分支帮忙继续开发,要做的操作如下:
- 必须先拉取远端仓库内容
- 可以看到远程已经有了 feature-2
- 切换到 feature-2 分支上,可以和远程的 feature-2 分支关联起来,否则将来只使用 git push 推送内容会失败
切换成功后,便可以看见 feature-2 分支中的 function2 文件了,接着就可以帮小伙伴进行开发:
- 继续开发
- 推送内容
查看远程状态,推送成功了:
这时小伙伴已经修养的差不多,可以继续进行自己的开发工作,那么他首先要获取到我们帮他开发的内容,然后接着我们的代码继续开发。或者我们已经帮他开发完了,那他也需要在自己的电脑上看看我们帮他写的代码:
可以发现代码没有 pull 下来。
Pull 无效的原因是:小伙伴没有指定本地 feature-2 分支与远程 origin/feature-2 分支的链接。
根据提示,设置 feature-2 和 origin/feature-2 的链接即可:
目前,小伙伴的本地代码和远端保持严格一直。我和小伙伴可以继续在不同的分支下进行协同开发了。
各自功能开发完毕后,我们需要将代码合并到 master 中才算真正意义上的开发完毕。
新建一个 Pull Request,让 feature-2 分支合并到 master 分支上:
让 feature-1 分支合并到 master 分支上:
- 切换至 master 分支,pull 一下,保证本地的 master 是最新内容,合并前这么做是⼀个好习惯
- 切换至 feature-1 分支,合并 master 分支。这么做是因为如果有冲突,可以在 feature-1 分支上进行处理,而不是在 master 上解决冲突,这么做也是⼀个好习惯
- (1)由于 feature-1 分支已经 merge 进来了新内容,为了保证远程分支最新,所以最好 push ⼀下。
- (2)要 push 的另⼀个原因是因为在实际的开发中,master 的 merge 操作一般不是由我们自己在本地进行操作,其他⼈员或某些平台 merge 时,操作的肯定是远程分支,所以就要保证远程分支的最新。
- (3)如果 merge 出现冲突,不要忘记需要 commit 才可以 push。
此时远程仓库的状态:
此时, feature-1 和 feature-2 分支对于我们来说就没用了, 那么我们可以直接在远程仓库中将 dev 分支删除掉:
以上就是多人协作的工作模式。
三、远程分支删除后,本地 git branch -a 依然能看到的解决办法
当前我们已经删除了远程的几个分支,使用 git branch -a 命令可以查看所有本地分支和远程分支,但发现很多在远程仓库已经删除的分支在本地依然可以看到。
使用命令 git remote show origin 可以查看 remote 地址,远程分支,还有本地分支与之相对应关系等信息。
此时我们可以看到那些远程仓库已经不存在的分支,根据提示,使用命令:git remote prune origin
相关文章:

【Git】多人协作 -- 详解
一、多人协作(1) ⽬前,我们所完成的工作如下: 基本完成 Git 的所有本地库的相关操作,git 基本操作,分支理解,版本回退,冲突解决等等。 申请码云账号,将远端信息 clone…...
Eureka和Nacos有哪些区别?
Eureka和Nacos都能起到注册中心的作用,用法基本类似。但还是有一些区别的,例如: Nacos支持配置管理,而Eureka则不支持。 而且服务注册发现上也有区别,我们来做一个实验: 我们停止user-service服务&#x…...

如何正确使用 include-what-you-use
简单地说,由 Google 开发的 include-what-you-use(IWYU)让源代码文件包含代码里用到的所有头文件。这种方法确保在改动了一些接口之后,代码依然最有可能编译成功。 之前我写了一篇关于 include-what-you-use 工具的文章ÿ…...

企业内网安全软件分享,有什么内网安全软件
内网安全? 其实就是网络安全的一种。 什么是内网安全软件? 内网安全软件是企业保障内网安全的一种重要工具。 它主要帮助企业实现对网络设备、应用程序、用户行为等方面的监控和管理,以预防和应对各种网络攻击。 这类软件主要用于对内网中…...
【摘葡萄game】
您想要了解的“摘葡萄游戏”可能是一个编程项目或者是一个编程相关的练习。我可以提供一个简单的摘葡萄游戏的思路和代码示例。这个游戏可以用多种编程语言来实现,比如Python、Java等。这里我以Python为例,给出一个基础版本的摘葡萄游戏的概念和代码。 …...
java如何实现字符串连接
在java中,字符串与字符串连接可以用运算符和 比如有字符串a,字符串b 想要把a和b连接起来,定义一个字符串变量c cab 或者 ab 示例代码 public class Zifuchuanlianjie {public static void main(String[] args) {String a"我叫李狗蛋";S…...
流量卡选卡攻略,拯救不会选流量卡的小白!
家人们,你们知道不,选择一款性价比高的流量卡,真的超级省钱。 一、首先,说一说申请。 运营商推出线上流量卡,注意是线上的流量卡,都是免费领取,运营商包邮到家,在激活充值之前不…...
python class __format__ __bytes__区别
在Python中,__format__和__bytes__是两个特殊方法,它们允许对象自定义它们在特定情境下的字符串表示。以下是这两个方法的区别和作用: __format__ 作用:__format__方法用于定义对象在使用format()函数或格式化字符串(…...

C++ | Leetcode C++题解之第134题加油站
题目: 题解: class Solution { public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {int n gas.size();int i 0;while (i < n) {int sumOfGas 0, sumOfCost 0;int cnt 0;while (cnt < n) {int j (i …...

【Linux】ls命令
这个命令主要是用于显示指定工作目录下之内容(列出目前工作目录所含的文件及子目录)。 掌握几个重点的常使用的就可以: ls -l # 以长格式显示当前目录中的文件和目录 ls -a # 显示当前目录中的所有文件和目录&am…...
多态、虚函数表与动态绑定的深入解析
目录 多态简介 虚函数表与动态绑定 虚函数表 动态绑定机制 内存与性能影响 纯虚函数与抽象类 纯虚函数 抽象类 动态类型转换与typeid操作符 dynamic_cast typeid操作符 虚析构函数的重要性 在面向对象编程中,多态性是一种核心特性,它允许我们…...

VitePress+Docker+jenkins构建个人网站
VitePress官网 VitePress | 由 Vite 和 Vue 驱动的静态站点生成器 可以理解为一个前端脚手架:快速生成个人站点 最好先大概看一遍 快速开始 | VitePress 可以在线体验一下 安装条件 node -v 检查下node版本 在D盘创建一个文件夹 例如:VitePress 进入文件夹 cmd npm ini…...

Windows11下Docker使用记录(五)
目录 准备1. WSL安装cuda container toolkit2. win11 Docker Desktop 设置3. WSL创建docker container并连接cuda4. container安装miniconda(可选) Docker容器可以从底层虚拟化,使我们能够在 不降级 CUDA驱动程序的情况下使用 任何版本的CU…...

快速学习Java的多维数组技巧
哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一…...
C语言运算类型有哪些
C语言中的运算类型主要分为以下几类: 1. 算术运算符: - 加法运算符 - 减法运算符 - - 乘法运算符 * - 除法运算符 / - 取模运算符 %(取余数) 2. 关系运算符: - 大于 > - 小于 < - 大…...

【深度学习】Loss为Nan的可能原因
文章目录 1. 问题情境2. 原因分析3. 导致Loss为Nan的其他可能原因 1. 问题情境 在某个网络架构下,我为某个数据项引入了一个损失函数。 这个数据项是nn.Embedding类型的,我加入的损失函数是对nn.Embedding空间做约束。 因为我在没加入优化loss前&#x…...

解密!考研数学满分学霸的备考书单
这题我太会了,高数视频有是有真的又臭又长,我也不喜欢看 但是自己看教材,有的地方又比较难以理解,所以,这个时候一本通俗易懂的教材就显得格外重要,国内很多教材都讲的晦涩难懂,所以我给大家推…...
AI绘画工具介绍
AI绘画工具是利用人工智能技术帮助用户创作艺术作品的软件或平台。它们通常通过用户输入的描述性文字,自动解析并生成具有特定风格和主题的画作。以下是一些2024年流行的AI绘画工具的介绍: GitMind AI绘画2:一个提供多种语言界面的AI绘画生成…...

【APP逆向】央视频播放量增加,逆向全过程解密
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…...

三星系统因何而成?或许是因为吞噬了第四颗恒星
相比于其他的类似星体,这个特殊的三星系统拥有更大更紧密的星体。 三星 天文学家发现了前所未见的三星系统。相比于其他典型的三星系统,这一三星系统拥有更大的体积,并且排列也更加紧密,这也使得这一系统更加特别。科学家推测&am…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...