
🌈 个人主页:Zfox_
🔥 系列专栏:Git 企业级应用
目录
- [一:🔥 理解分布式版本控制系统](#一:🔥 理解分布式版本控制系统)
- [二:🔥 远程仓库](#二:🔥 远程仓库)
-
- [🦋 新建远程仓库](#🦋 新建远程仓库)
- [🦋 克隆远程仓库](#🦋 克隆远程仓库)
- [🦋 向远程仓库推送](#🦋 向远程仓库推送)
- [🦋 拉取远程仓库](#🦋 拉取远程仓库)
- [三:🔥 配置Git](#三:🔥 配置Git)
-
- [🦋 忽略特殊⽂件](#🦋 忽略特殊⽂件)
- [🦋 给命令配置别名](#🦋 给命令配置别名)
- [四:🔥 标签管理](#四:🔥 标签管理)
-
- [🦋 理解标签](#🦋 理解标签)
- [🦋 创建标签](#🦋 创建标签)
- [🦋 操作标签](#🦋 操作标签)
- [五:🔥 多⼈协作](#五:🔥 多⼈协作)
-
- [🦋 多⼈协作⼀](#🦋 多⼈协作⼀)
- [🦋 多⼈协作⼆](#🦋 多⼈协作⼆)
-
- [🎀 远程分⽀删除后,本地gitbranch-a依然能看到的解决办法](#🎀 远程分⽀删除后,本地gitbranch-a依然能看到的解决办法)
- [六:🔥 共勉](#六:🔥 共勉)
一:🔥 理解分布式版本控制系统
🦈 我们⽬前所说的所有内容(⼯作区
,暂存区
,版本库
等等),都是在本地!也就是在你的笔记本或者计算机上。⽽我们的Git
其实是分布式版本控制系统!什么意思呢?
可以简单理解为,我们每个⼈的电脑上都是⼀个完整的版本库,这样你⼯作的时候,就不需要联⽹了,因为版本库就在你⾃⼰的电脑上。既然每个⼈电脑上都有⼀个完整的版本库,那多个⼈如何协作呢?⽐⽅说你在⾃⼰电脑上改了⽂件A,你的同事也在他的电脑上改了⽂件A,这时,你们俩之间只需把各⾃的修改推送给对⽅,就可以互相看到对⽅的修改了 。
分布式版本控制系统的安全性要⾼很多,因为每个⼈电脑⾥都有完整的版本库,某⼀个⼈的电脑坏掉了不要紧,随便从其他⼈那⾥复制⼀个就可以了。
在实际使⽤分布式版本控制系统的时候,其实很少在两⼈之间的电脑上推送版本库的修改,因为可能你们俩不在⼀个局域⽹内,两台电脑互相访问不了。也可能今天你的同事病了,他的电脑压根没有开机。因此,分布式版本控制系统通常也有⼀台充当"中央服务器"的电脑,但这个服务器的作⽤仅仅是⽤来⽅便"交换"⼤家的修改,没有它⼤家也⼀样⼲活,只是交换修改不⽅便⽽已
。有了这个"中央服务器"的电脑,这样就不怕本地出现什么故障了(⽐如运⽓差,硬盘坏了,上⾯的所有东西全部丢失,包括git的所有内容)
二:🔥 远程仓库
🐳 Git
是分布式版本控制系统,同⼀个Git
仓库,可以分布到不同的机器上。怎么分布呢?最早,肯定只有⼀台机器有⼀个原始版本库,此后,别的机器可以"克隆"这个原始版本库,⽽且每台机器的版本库其实都是⼀样的,并没有主次之分。
你肯定会想,⾄少需要两台机器才能玩远程库不是?但是我只有⼀台电脑,怎么玩?其实⼀台电脑上也是可以克隆多个版本库的,只要不在同⼀个⽬录下。不过,现实⽣活中是不会有⼈这么傻的在⼀台电脑上搞⼏个远程库玩,因为⼀台电脑上搞⼏个远程库完全没有意义,⽽且硬盘挂了会导致所有库都挂掉,所以我也不告诉你在⼀台电脑上怎么克隆多个仓库。
实际情况往往是这样,找⼀台电脑充当服务器的⻆⾊,每天24⼩时开机,其他每个⼈都从这个"服务器"仓库克隆⼀份到⾃⼰的电脑上,并且各⾃把各⾃的提交推送到服务器仓库⾥,也从服务器仓库中拉取别⼈的提交。
完全可以⾃⼰搭建⼀台运⾏Git
的服务器,不过现阶段,为了学Git先搭个服务器绝对是⼩题⼤作。好在这个世界上有个叫GitHub
的神奇的⽹站,从名字就可以看出,这个⽹站就是提供Git
仓库托管服务的,所以,只要注册⼀个 GitHub
账号,就可以免费获得Git
远程仓库。
Github
是国外的⽹站,速度⽐较慢,我们课堂上同统⼀采⽤码云来托管代码。下来,我们从零开始,使⽤⼀下码云远程仓库。
🦋 新建远程仓库
- 新建远程项⽬仓库:

- 填写基本信息

-
创建成功
-
创建成功后,我们可以对远程仓库进⾏⼀个基本的设置:开源or私有

🧑💻 从创建好的远程仓库中我们便能看到,之前在本地学习过的分⽀,也存在于远程仓库中并被管理起来了。刚创建的仓库有且只有⼀个默认的 master
分⽀。
🦋 克隆远程仓库
💍 克隆/下载远端仓库到本地,需要使⽤ git clone
命令,后⾯跟上我们的远端仓库的链接,远端仓库的链接可以从仓库中找到:选择 "克隆/下载" 获取远程仓库链接:
🐬 SSH
协议和HTTPS
协议是Git
最常使⽤的两种数据传输协议。SSH
协议使⽤了公钥加密和公钥登陆机制,体现了其实⽤性和安全性,使⽤此协议需要将我们的公钥放上服务器,由Git
服务器进⾏管理。使⽤HTTPS
⽅式时,没有要求,可以直接克隆下来。
- 使⽤
HTTPS
⽅式:
csharp
$ git clone https://gitee.com/zfox-f/git_teaching.git
Cloning into 'git_teaching'...
Username for 'https://gitee.com': hyb91
Password for 'https://[email protected]':
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 1.80 KiB | 1.80 MiB/s, done.
$ ls
gitcode git_teaching
$ ls git_teaching/
README.en.md README.md
- 使⽤
SSH
⽅式:
csharp
$ git clone [email protected]:hyb91/git_teaching.git
Cloning into 'git_teaching'...
The authenticity of host 'gitee.com (212.64.63.215)' can't be established.
ECDSA key fingerprint is SHA256:FQGC9Kn/eye1W8icdBgrQp+KkGYoFgbVr17bmjey0Wc.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'gitee.com,212.64.63.215' (ECDSA) to the list of
known hosts.
[email protected]: 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
链接。需要我们设置⼀下:
第⼀步:创建 SSHKey
。在⽤⼾主⽬录下,看看有没有 .ssh⽬录
,如果有,再看看这个⽬录下有没有 id_rsa
和 id_rsa.pub
这两个⽂件,如果已经有了,可直接跳到下⼀步。如果没有,需要创建SSHKey:
csharp
# 注意要输⼊⾃⼰的邮箱,然后⼀路回⻋,使⽤默认值即可
$ ssh-keygen -t rsa -C "[email protected]"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hyb/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/hyb/.ssh/id_rsa
Your public key has been saved in /home/hyb/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:sepKZUwKIXjJxYcot49tvOW+Aa+pEhdsRqVDFSmgQZo [email protected]
The key's randomart image is:
+---[RSA 3072]----+
|*+oB=+ |
|==Oo+ . |
|E*+o .. . |
| *o + o |
| o *o + S |
|. o ==.. |
| o ..++ |
|. ..+.. |
| ...+o+. |
+----[SHA256]-----+
顺利的话,可以在⽤⼾主⽬录⾥找到 .ssh ⽬录
,⾥⾯有 id_rsa
和 id_rsa.pub
两个⽂件,这两个就是 SSHKey
的秘钥对, id_rsa
是私钥,不能泄露出去, id_rsa.pub
是公钥,可以放⼼地告诉任何⼈。

点击 ssh公钥
选项,进⾏设置:

🌶️ 点击确认后,需要对你进⾏认证,输⼊你的账号密码即可。⾄此,我们的准备⼯作全部做完,欢快的 clone
吧。
csharp
$ git clone [email protected]:zfox-f/git_teaching.git
Cloning into 'git_teaching'...
Warning: Permanently added the ECDSA host key for IP address '212.64.63.190'
to the list of known hosts.
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
Receiving objects: 100% (4/4), done.
hyb@139-159-150-152:~$ ls
gitcode git_teaching
$ ls git_teaching/
README.en.md README.md
done
,成功!如果有多个⼈协作开发,GitHub/Gitee
允许添加多个公钥,只要把每个⼈的电脑上的Key
都添加到GitHub/Gitee
,就可以在每台电脑上往GitHub/Gitee
上提交推送了。
当我们从远程仓库克隆后,实际上Git
会⾃动把本地的master
分⽀和远程的master
分⽀对应起来,并且,远程仓库的默认名称是origin
。在本地我们可以使⽤git remote
命令,来查看远程库的信息,如:
csharp
$ git remote
origin
- 或者,⽤
git remote -v
显⽰更详细的信息:
csharp
$ git remote -v
origin [email protected]:hyb91/git_teaching.git (fetch)
origin [email protected]:hyb91/git_teaching.git (push)
上⾯显⽰了可以抓取和推送的 origin
的地址。如果没有推送权限,就看不到push
的地址。推送是什么意思呢,我们继续往下看。
🦋 向远程仓库推送
🍔 本地已经 clone
成功远程仓库后,我们便可以向仓库中提交内容,例如新增⼀个 file.txt
⽂件:
csharp
# 新建⽂件
$ ls
README.en.md README.md
$ vim file.txt
$ cat file.txt
hello git
# 提交⽂件
$ git add .
$ git commit -m"create file.txt"
[master 7ce3183] create file.txt
1 file changed, 1 insertion(+)
create mode 100644 file.txt
提交时要注意,如果我们之前设置过全局的name
和e-mail
,这两项配置需要和gitee
上配置的⽤⼾名和邮箱⼀致,否则会出错。或者从来没有设置过全局的name
和e-mail
,那么我们第⼀次提交时也会报错。这就需要我们重新配置下了,同样要注意需要和gitee
上配置的⽤⼾名和邮箱⼀致。如何配置已讲过,在这⾥就不再赘述。
到这⾥我们已经将内容提交⾄本地仓库中,如何将本地仓库的内容推送⾄远程仓库呢,需要使⽤ git push
命令,该命令⽤于将本地的分⽀版本上传到远程并合并,命令格式如下:
csharp
git push <远程主机名> <本地分⽀名>:<远程分⽀名>
# 如果本地分⽀名与远程分⽀名相同,则可以省略冒号:
git push <远程主机名> <本地分⽀名>
此时我们要将本地的master
分⽀推送到origin
主机的master
分⽀,则可以:
csharp
$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 308.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
c6ce3f0..7ce3183 master -> master
推送成功!这⾥由于我们使⽤的是SSH
协议,是不⽤每⼀次推送都输⼊密码的,⽅便了我们的推送操作。如果你使⽤的是HTTPS
协议,有个⿇烦地⽅就是每次推送都必须输⼊⼝令。
-
接下来,看看码云远端:
-
代码已经被推送⾄远端了:

🦋 拉取远程仓库
🛫 在gitee
上点击README.md⽂件并在线修改它:
修改内容:

此时,远程仓库是要领先于本地仓库⼀个版本,为了使本地仓库保持最新的版本,我们需要拉取下远端代码,并合并到本地。Git
提供了 git pull
命令,该命令⽤于从远程获取代码并合并本地的版本。格式如下:
cpp
git pull <远程主机名> <远程分⽀名>:<本地分⽀名>
# 如果远程分⽀是与当前分⽀合并,则冒号后⾯的部分可以省略。
git pull <远程主机名> <远程分⽀名>
使⽤⼀下:
csharp
# 拉取远程分⽀,并与当前分⽀进⾏合并
$ git pull origin master
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 1.02 KiB | 1.02 MiB/s, done.
From gitee.com:hyb91/git_teaching
* branch master -> FETCH_HEAD
7ce3183..60e6b0a master -> origin/master
Updating 7ce3183..60e6b0a
Fast-forward
README.md | 2 ++
1 file changed, 2 insertions(+)
$ cat README.md
...
第⼀次修改内容
我们发现,拉取成功了!
三:🔥 配置Git
🦋 忽略特殊⽂件
在⽇常开发中,我们有些⽂件不想或者不应该提交到远端,⽐如保存了数据库密码的配置⽂件,那怎么让Git
知道呢?在Git
⼯作区的根⽬录下创建⼀个特殊的 .gitignore
⽂件,然后把要忽略的⽂件名填进去,Git
就会⾃动忽略这些⽂件了。
不需要从头写 .gitignore
⽂件,gitee
在创建仓库时就可以为我们⽣成,不过需要我们主动勾选⼀下:

如果当时没有选择这个选择,在⼯作区创建⼀个也是可以的。⽆论哪种⽅式,最终都可以得到⼀个完整的 .gitignore
⽂件,例如我们想忽略以 .so
和 .ini
结尾所有⽂件, .gitignore
的内容如下:
csharp
# 省略选择模本的内容
...
# My configurations:
*.ini
*.so
在 .gitignore
⽂件中也可以指定某个确定的⽂件。
最后⼀步就是把 .gitignore
也提交到远端,就完成了:
csharp
$ vim .gitignore
$ git add .
$ git commit -m"add .gitignore"
[master 97811ab] add .gitignore
1 file changed, 3 insertions(+)
create mode 100644 .gitignore
hyb@139-159-150-152:~/git_teaching$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 362 bytes | 362.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
60e6b0a..97811ab master -> master
接着我们就来验证⼀下 .gitignore
⽂件的能⼒,在⼯作区新增两个⽂件 a.so
b.ini
:
csharp
$ touch a.so b.ini
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
检验 .gitignore
的标准就是 git status
命令是不是说 working tree clean
。我们发现Git
并没有提⽰在⼯作区中有⽂件新增,果然 .gitignore
⽣效了!
但有些时候,你就是想添加⼀个⽂件到Git
,但由于这个⽂件被 .gitignore
忽略了,根本添加不了,那么可以⽤ -f
强制添加:
csharp
$ git add -f [filename]
或者你发现,可能是 .gitignore
写得有问题,需要找出来到底哪个规则写错了,⽐如说a.so
⽂件是要被添加的,可以⽤ git check-ignore
命令检查:
csharp
$ git check-ignore -v a.so
.gitignore:3:*.so a.so
Git
会告诉我们, .gitignore
的第3⾏规则忽略了该⽂件,于是我们就可以知道应该修订哪个规则。
还有些时候,当我们编写了规则排除了部分⽂件时,例如:
csharp
# 排除所有.开头的隐藏⽂件:
.*
但是我们发现 .*
这个规则把 .gitignore
也排除了。虽然可以⽤ git add -f
强制添加进去,但有强迫症的童鞋还是希望不要破坏 .gitignore
规则,这个时候,可以添加⼀条例外规则:
csharp
# 排除所有.开头的隐藏⽂件:
.*
# 不排除.gitignore
!.gitignore
⚠️ 把指定⽂件排除在 .gitignore
规则外的写法就是 ! +⽂件名
,所以,只需把例外⽂件添加进去即可。
🦋 给命令配置别名
在我们使⽤Git
期间,有些命令敲的时候着实让⼈头疼(太⻓了。。),幸运的是,git ⽀持对命令进⾏简化!
举个例⼦,将 git status
简化为 git st
,对应的命令为:
csharp
$ git config --global alias.st status
--global
参数是全局参数,也就是这些命令在这台电脑的所有 Git
仓库下都有⽤。如果不加,那只针对当前的仓库起作⽤。
好了,现在敲 git st
看看效果:
csharp
$ git st
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
再来配置⼀个 git last ,让其显⽰最后⼀次提交信息:
csharp
$ git config --global alias.last 'log -1'
这样,⽤ git last
就能显⽰最近⼀次的提交:
csharp
hyb@139-159-150-152:~/git_teaching$ git last
commit 97811abd1d43774aeb54fee32bf4fc76b2b08170 (HEAD -> master,
origin/master, origin/HEAD)
Author: hyb91 <[email protected]>
Date: Fri May 12 17:27:06 2023 +0800
add .gitignore
不过,我个⼈还是不推荐⼤家现在去使⽤他,等⼤家⼯作了,再去简化⾃⼰的⼯作吧,⽬前所有的命令都要⼿动完成,尽快适应Git
。
四:🔥 标签管理
🦋 理解标签
⌚️ 标签 tag
,可以简单的理解为是对某次 commit
的⼀个标识,相当于起了⼀个别名。例如,在项⽬发布某个版本的时候,针对最后⼀次 commit
起⼀个 v1.0 这样的标签来标识⾥程碑的意义。
这有什么⽤呢?相较于难以记住的 commit id
, tag
很好的解决这个问题,因为 tag
⼀定要给⼀个让⼈容易记住,且有意义的名字。当我们需要回退到某个重要版本时,直接使⽤标签就能很快定位到。
🦋 创建标签
在 Git
中打标签⾮常简单,⾸先,切换到需要打标签的分⽀上
csharp
$ git branch
* master
然后,敲命令 git tag [name]
就可以打⼀个新标签:
csharp
$ git tag v1.0
可以⽤命令 git tag
查看所有标签:
csharp
$ git tag
v1.0
默认标签是打在最新提交的 commit
上的。那如何在指定的 commit
上打标签呢?⽅法是找到历史提交的 commitid
,然后打上就可以了,⽰例如下:
csharp
# 历史记录
$ 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 这次提交打标签
$ git tag v0.9 c6ce3f0
$ git tag
v0.9
v1.0
注意,标签不是按时间顺序列出,⽽是按字⺟排序的。
可以⽤ git show [tagname]
查看标签信息。
csharp
$ git show v1.0
commit 97811abd1d43774aeb54fee32bf4fc76b2b08170 (HEAD -> master, tag: v1.0,
origin/master, origin/HEAD)
Author: hyb91 <[email protected]>
Date: Fri May 12 17:27:06 2023 +0800
add .gitignore
diff --git a/.gitignore b/.gitignore
...
Git
还提供可以创建带有说明的标签,⽤ -a
指定标签名,-m
指定说明⽂字,格式为:
csharp
git tag -a [name] -m "XXX" [commit_id]
另外,打完标签之后,使⽤ tree .git
命令查看⼀下你的本地库有什么变化,肯定能帮助你理解!
🦋 操作标签
🎁 如果标签打错了,也可以删除:
csharp
$ git tag
v0.9
v1.0
$ git tag -d v0.9
Deleted tag 'v0.9' (was c6ce3f0)
$ git tag
v1.0
因为创建的标签都只存储在本地,不会⾃动推送到远程。所以,打错的标签可以在本地安全删除。
如果要推送某个标签到远程,使⽤命令 git push origin <tagname>
csharp
$ git tag
v1.0
$ git push origin v1.0
Total 0 (delta 0), reused 0 (delta 0)
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
* [new tag] v1.0 -> v1.0
此时,查看远端码云,看到了标签已经被更新!完美!

当然,如果你本地有很多标签,也可以⼀次性的全部推送到远端:
csharp
git push origin --tags
请⾃⾏验证。
如果标签已经推送到远程,要删除远程标签就⿇烦⼀点,先从本地删除:
csharp
$ git tag
v1.0
$ git tag -d v1.0
Deleted tag 'v1.0' (was 97811ab)
然后,从远程删除。删除命令也是 push
,但是格式如下:
csharp
$ git push origin :refs/tags/v1.0
remote: Powered by GITEE.COM [GNK-6.4]
To gitee.com:hyb91/git_teaching.git
- [deleted] v1.0
🚀 在码云上查看确实删除成功:

五:🔥 多⼈协作
🦋 多⼈协作⼀
🍝 ⽬前,我们所完成的⼯作如下:
- 基本完成Git的所有本地库的相关操作,git 基本操作,分⽀理解,版本回退,冲突解决等等
- 申请码云账号,将远端信息 clone 到本地,以及推送和拉取。
是时候⼲最重要的⼀件事情了,实现多⼈协作开发!为了做这件事情,我们需要先做⼀些准备⼯作。
我们之前已经将项⽬clone到了指定⽬录,如:
csharp
$ pwd
/home/git_teaching
我们在windows环境下,再clone同⼀个项⽬仓库,来模拟和你⼀起协作开发的另⼀名⼩伙伴:
Clone成功

注意,是模拟了两个用户,实际开发中,每个用户都有⾃⼰的 gitee/github 账号,如果要多⼈进⾏协同开发,必须要将用户添加进开发者,⽤⼾才有权限进⾏代码提交:

邀请用户:

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

创建成功的远程分⽀是可以通过Git拉取到本地来,以实现完成本地开发⼯作。
接下来让我们和另⼀名开发的⼩伙伴都将远程仓库进⾏⼀次拉取操作,并观察结果:
- 对于我们要操作的是:
csharp
$ git pull
From gitee.com:hyb91/git_teaching
* [new branch] dev -> origin/dev
Already up to date.
# 注:之前讲的 git branch 其实只能查看本地分⽀,要查看远程分⽀需要加上-r选项。
# 但前提是要pull⼀下拉取最新的远端仓库,才能看到最新的内容。
~/git_teaching$ git branch -r
origin/HEAD -> origin/master
origin/dev
origin/master
$ git checkout -b dev origin/dev
Branch 'dev' set up to track remote branch 'dev' from 'origin'.
Switched to a new branch 'dev'
拉取后便可以看到远程的dev
分⽀,接着切换到dev
分⽀供我们进⾏本地开发。要说明的是,我们切换到的是本地的dev
分⽀,根据⽰例中的操作,会将本地分⽀和远程分⽀的进⾏关系链接。
- 对于⼩伙伴要操作的是:
现在,你和你的⼩伙伴就可以在dev
上完成开发。
⾸先,让我们在 dev
分⽀上进⾏⼀次开发,并 push
到远程。例如:
csharp
$ vim file.txt
$ cat file.txt
hello git
complete the first function!
$ git add file.txt
$ git commit -m "first function"
[dev 305f78a] first function
1 file changed, 1 deletion(-)
$ 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
让我们来看看码云上⽬前仓库的状态:
⾄此,我们已经将代码成功推送⾄码云,接下来假如你的⼩伙伴要和你协同开发,碰巧也要对file.txt ⽂件作修改,并试图推送,例如:

这时推送失败,因为你的⼩伙伴的最新提交和你推送的提交有冲突,解决办法也很简单,Git
已经提⽰我们,先⽤ git pull
把最新的提交从 origin/dev
抓下来,然后,在本地进⾏合并,并解决冲突,再推送。操作如下:

解决冲突,重新推送:

此时,我们看到远端的码云已经能看到我们的新提交了

由此,两名开发者已经开始可以进⾏协同开发了,不断的 git pull/add/commit/push
,遇到了冲突,就使⽤我们之前讲的冲突处理解决掉冲突。
对于你来说,要想看到⼩伙伴的代码,只需要 pull ⼀下即可,例如:
csharp
$ cat file.txt
hello git
complete the first function!
$ git pull
Updating 305f78a..72c5345
Fast-forward
file.txt | 1 +
1 file changed, 1 insertion(+)
$ cat file.txt
hello git
complete the first function!
complete the second function!
最后不要忘记,虽然我们是在分⽀上进⾏多⼈协作开发,但最终的⽬的是要将开发后的代码合并到 master
上去,让我们的项⽬运⾏最新的代码。接下来我们就需要做这件事情了:
csharp
# 切换⾄ master分⽀, pull ⼀下,保证本地的master是最新内容。
# 合并前这么做是⼀个好习惯
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git pull
Already up to date.
# 切换⾄ dev 分⽀, 合并 master 分⽀
# 这么做是因为如果有冲突,可以在dev分⽀上进⾏处理,⽽不是在在master上解决冲突。
# 这么做是⼀个好习惯
$ git checkout dev
Switched to branch 'dev'
Your branch is up to date with 'origin/dev'.
$ git merge master
Already up to date.
# 切换⾄ master 分⽀,合并 dev 分⽀
$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git merge dev
Updating 7388a31..72c5345
Fast-forward
file.txt | 2 ++
1 file changed, 2 insertions(+)
$ cat file.txt
hello git
complete the first function!
complete the second function!
# 将 master 分⽀推送⾄远端
$ 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
$ 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
$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
此时,查看远端仓库,master
已经是最新代码了:

此时,dev
分⽀对于我们来说就没⽤了,那么dev
分⽀就可以被删除掉。我们可以直接在远程仓库中将 dev
分⽀删除掉:


总结⼀下,在同⼀分⽀下进⾏多⼈协作的⼯作模式通常是这样:
- ⾸先,可以试图⽤
gitpushoriginbranch-name
推送⾃⼰的修改;- 如果推送失败,则因为远程分⽀⽐你的本地更新,需要先⽤
gitpull
试图合并;- 如果合并有冲突,则解决冲突,并在本地提交;
- 没有冲突或者解决掉冲突后,再⽤
gitpushoriginbranch-name
推送就能成功!- 功能开发完毕,将分⽀
merge
进master
,最后删除分⽀。
🦋 多⼈协作⼆
🍟 ⼀般情况下,如果有多需求需要多⼈同时进⾏开发,是不会在⼀个分⽀上进⾏多⼈开发,⽽是⼀个需求或⼀个功能点就要创建⼀个 feature
分⽀。
现在同时有两个需求需要你和你的⼩伙伴进⾏开发,那么你们俩便可以各⾃创建⼀个分⽀来完成⾃⼰的⼯作。在上个部分我们已经了解了可以从码云上直接创建远程分⽀,其实在本地创建的分⽀也可以通过推送的⽅式发送到远端。在这个部分我们就来⽤⼀下这种⽅式。
- 对于你来说,可以进⾏以下操作:
csharp
# 新增本地分⽀ feature-1 并切换
~/git_teaching$ git branch
dev
* master
~/git_teaching$ git checkout -b feature-1
Switched to a new branch 'feature-1'
# 新增需求内容-创建function1⽂件
~/git_teaching$ vim function1
~/git_teaching$ cat function1
Done!
# 将 feature-1 分⽀推送到远端
~/git_teaching$ git add function1
~/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
分⽀帮忙继续开发,要做的操作如下:
csharp
# 必须先拉取远端仓库内容
~/git_teaching$ git pull
...
From gitee.com:hyb91/git_teaching
305f78a..72c5345 dev -> origin/dev
* [new branch] feature-2 -> origin/feature-2
...
# 可以看到远程已经有了feature-2
~/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 推送内容会失败
~/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'
~/git_teaching$ ls
a.so b.ini file.txt function2 README.en.md README.md
切换成功后,便可以看⻅feature-2分⽀中的function2⽂件了,接着就可以帮⼩伙伴进⾏开发:
csharp
# 继续开发
~/git_teaching$ vim function2
~/git_teaching$ cat function2
Done!
Help done!
# 推送内容
~/git_teaching$ git add function2
~/git_teaching$ git commit -m"modify function2"
[feature-2 1079ae7] modify function2
1 file changed, 2 insertions(+), 1 deletion(-)
~/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
查看远程状态,推送成功了:

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

Pull
⽆效的原因是⼩伙伴没有指定本地feature-1
分⽀与远程origin/feature-2
分⽀的链接,根据提⽰,设置 feature-2
和 origin/feature-2
的链接即可:
⽬前,⼩伙伴的本地代码和远端保持严格⼀致。你和你的⼩伙伴可以继续在不同的分⽀下进⾏协同开发了。
各⾃功能开发完毕后,不要忘记我们需要将代码合并到 master
中才算真正意义上的开发完毕。
由于你的⼩伙伴率先开发完毕,于是开始 merge
:

此时远程仓库的状态:

当你的⼩伙伴将其代码 merge
到 master
后,这是你也开发完成了,也需要进⾏ merge
到 master
操作,于是你:
csharp
# 切换⾄ master分⽀, pull ⼀下,保证本地的master是最新内容。
# 合并前这么做是⼀个好习惯
~/git_teaching$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
~/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上解决冲突。
# 这么做是⼀个好习惯
~/git_teaching$ git checkout feature-1
Switched to branch 'feature-1'
Your branch is up to date with 'origin/feature-1'.
~/git_teaching$ git merge master
Merge made by the 'recursive' strategy.
function2 | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 function2
~/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!!
~/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
~/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'.
~/git_teaching$ git merge feature-1
Updating 29006bd..4b4c3d4
Fast-forward
function1 | 1 +
1 file changed, 1 insertion(+)
create mode 100644 function1
~/git_teaching$ ls
a.so b.ini file.txt function1 function2 README.en.md README.md
# 将 master 分⽀推送⾄远端
~/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
~/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
此时远程仓库的状态:

此时, feature-1
和 feature-2
分⽀对于我们来说就没⽤了,那么我们可以直接在远程仓库中将 dev
分⽀删除掉:

这就是多⼈协作的⼯作模式,⼀旦熟悉了,就⾮常简单。
🎀 远程分⽀删除后,本地gitbranch-a依然能看到的解决办法
🦈 当前我们已经删除了远程的⼏个分⽀,使⽤ git branch -a
命令可以查看所有本地分⽀和远程分⽀,但发现很多在远程仓库已经删除的分⽀在本地依然可以看到。例如:
csharp
~/git_teaching$ git pull
Already up to date.
~/git_teaching$ git branch -a
dev
feature-1
feature-2
* master
remotes/origin/HEAD -> origin/master
remotes/origin/dev
remotes/origin/feature-1
remotes/origin/feature-2
remotes/origin/master
使⽤命令 git remote show origin
,可以查看 remote
地址,远程分⽀,还有本地分⽀与之相对应关系等信息
csharp
~/git_teaching$ git remote show origin
* remote origin
Fetch URL: [email protected]:hyb91/git_teaching.git
Push URL: [email protected]: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
命令:
csharp
~/git_teaching$ git remote prune origin
Pruning origin
URL: [email protected]: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
这样就删除了那些远程仓库不存在的分⽀。对于本地仓库的删除,之前的博客已经学过了,⼤家可以⾃⾏从操作。
六:🔥 共勉
😋 以上就是我对 Git 远程操作全攻略:从基础到实战
的理解, 觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~ 😉