Git版本控制器

发布于:2025-08-16 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

一. git 的基本操作

1.1 创建本地仓库 git init

1.2 配置git git config

1.3 工作区,暂存区,版本库

1.4 .git文件

1.5 版本回退 git reset

1.6 撤销修改

情况一:对于工作区的代码,还没有 add

情况二:已经add,还没有commit

情况三:已经add了,也commit了

1.7 删除版本库文件

二. 分支管理

2.1 创建分支 git branch

2.2 切换分支 git checkout

2.3 合并分支 git merge

2.4 删除分支 git branch -d

2.5 合并冲突

2.6 分支管理策略 git merge --no-ff -m

2.7 分支策略

2.8 bug分支 git stash

2.9 强制删除分支 git branch -D

三. 远程操作

3.1 克隆远程仓库 git clone

HTTPS远程登录

SSH远程登录

3.2 向远程仓库推送 git push

3.3 拉取远程仓库 git pull

3.4 忽略特殊文件 .gitignore

3.5 给命令配置别名 git config --global alias.

四. 标签管理

4.1 理解标签

4.2 创建标签 git tag

4.3 推送标签

五. 多人协作

5.1 多人协作一

准备工作

协作开发(dev分支)

协作开发(master分支)

5.2 多人协作二

准备工作

开发者一帮开发者二开发

合并到master

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

六. Git分支设计规范

Git分支管理表

master 分支

release 分支

develop 分支

feature 分支

hotfix 分支


有关于git的用法,主要针对快速上手git,与像gitee这样的代码托管平台快速认识与使用,可跳转链接:

Linux初识:【版本控制器Git】【调试器gdb/cgdb使用】_linux版本控制器-CSDN博客

一. git 的基本操作

1.1 创建本地仓库 git init

使用命令: git init

先创建一个新目录,输入完毕之后,在当前的目录下会有一个.git

注意 .git 目录录是Git来跟踪管理仓库的,不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了。

1.2 配置git git config

使用命令: git config user.name/user.email

安装完git首先就是要去设置自己的用户名和email

git config [--global] user.name "Your Name" 
git config [--global] user.email "email@example.com" 
# 把 Your Name 改成你的昵称
# 把 email@example.com 改成邮箱的格式,只要格式正确即可。

使用命令: git config -l

其中--global 是一个可选项。如果使用了该选项,表示这台机器上所有的Git仓库都会使用这个 配置。如果你希望在不同仓库中使用不同的name 或e-mail ,可以不要--global 选项,但要 注意的是,执行命令时必须要在仓库里。

使用命令: 【git config [--global] --unset user.name】【git config [--global] --unset user.email】

如果创建的时候带上了--global选项,删除的时候也要带上。

1.3 工作区,暂存区,版本库

• 工作区:是在电脑上你要写代码或文件的目录。

• 暂存区:英文叫stage或index。一般存放在.git 目录下的 index ⽂件(.git/index)中,我们 把暂存区有时也叫作索引(index)。

• 版本库:又名仓库,英文名 repository 。工作区有一个隐藏目录.git ,它不算工作区,而是Git的版本库。这个版本库里面的所有文件都可以被Git管理起来,每个文件的修改、删除,Git 都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻可以“还原”。

• 图中左侧为工作区,右侧为版本库。Git的版本库里存了很多东西,其中最重要的就是暂存区。 

• 在创建Git版本库时,Git会为我自动创建一个唯一的 master 分支,以及指向 master 的一个指 针叫HEAD。

• 当对工作区修改(或新增)的文件执行git add 命令时,暂存区目录树的文件索引会被更新。

• 当执行提交操作 git commit 时,master分支会做相应的更新,可以简单理解为暂存区的目录树才会被真正写到版本库中。

使用命令: 【git add】【git status】

git status就可以查看从工作区的修改,有没有什么变化,这里就添加了一个file4.

使用命令: 【git log】

git log可以查看时间由近到远的,更新到版本库里的文件。

使用命令: 【git commit】

更新到仓库区

使用命令:【git diff】

这里我是用vim在file4文件中添加了一行字母,使用git diff可以对比以前的跟修改后的变化。

在工作区变化的,add之后就不显示了

+1后面默认是1.

1.4 .git文件

查找object时要将commit id 分成2部分,其前2位是文件夹名称,后38位是文件名称。

找到这个文件之后,一般不能直接看到里面是什么,该类文件是经过sha (安全哈希算法)加密过的文件,好在我们可以使用git cat-file 命令来查看版本库对象的内容:

• index:暂存区, git add 后会更新该内容。

• HEAD:默认指向master分支的⼀个指针。

• refs/heads/master:文件里保存当前master 分支的最新 commit id 。

• objects:包含了创建的各种版本库对象及内容,可以简单理解为放了git维护的所有修改。

1.5 版本回退 git reset

执行 git reset 命令用于回退版本,可以指定退回某一次提交的版本。要解释一下“回退”本质是 要将版本库中的内容进行回退,工作区或暂存区是否回退由命令参数决定:

使用命令: 【git reset [--soft | --mixed | --hard] [HEAD] 】

• --mixed 为默认选项,使用时可以不用带该参数。该参数将暂存区的内容退回为指定提交版本内 容,工作区文件保持不变。

• --soft 参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本。

• --hard 参数将暂存区与工作区都退回到指定版本。切记工作区有未提交的代码时不要用这个命 令,因为工作区会回滚,你没有提交的代码就再也找不回了,所以使用该参数前一定要慎重。

• HEAD 说明:

        ◦ 可直接写成commit  id,表示指定退回的版本

        ◦ HEAD表示当前版本

        ◦ HEAD^ 上一个版本 

        ◦ HEAD^^上上一个版本

        ◦ 以此类推...

• 可以使⽤〜数字表示: 

        ◦ HEAD~0 表示当前版本

        ◦ HEAD~1上一个版本

        ◦ HEAD~2 上上一个版本

        ◦ 以此类推...

黄色字体的就是commit id

简单使用一下这个,我把我的代码退回到第一版,使用hard选项:

使用命令:【git reflog】

即使不小心把工作区的代码丢了也没事:

“加一行a”字样前面有一个短的commit id,也可以用于恢复。

值得说的是,Git的版本回退速度非常快,因为Git在内部有个指向当前分支(此处是master)的 HEAD指针, refs/heads/master 文件里保存当前 master 分支的最新 commit id 。当我们 在回退版本的时候,Git仅仅是给refs/heads/master 中存储一个特定的version,可以简单理解 成如下示意图:

1.6 撤销修改

情况一:对于工作区的代码,还没有 add

演示一下:

现在是加了一行,使用git diff与版本库中对比可以看出。

使用命令:git checkout --

这里的“--”意思就是回退到上一次add时候的状态。

情况二:已经add,还没有commit

先看当前状态:

此时是在暂存区有,是还没有commit的状态。

使用命令:git reset HEAD file4

命令还是上面1.5版本回退的命令,默认是模式是--mixed。

这里就可以看出回退到了还没有add的状态了,说明暂存区被回退了。此时再想回退的话就是情况一的内容了。

情况三:已经add了,也commit了

此时我commit到版本库了:

想要回退到上一个版本:

使用命令:git reset --hard HEAD^

此时在工作区的代码也会回退。使用git status也是干干净净。

1.7 删除版本库文件

一种是在工作区删除后,再去提交到版本库:

这样需要三步。

使用命令:git rm

这里可以看到,直接变成绿色了,说明在暂存区就删了,不需要add操作了,然后再commit就行了。

二. 分支管理

每次提交,Git都把它们串成一条时间线,这条时间线就可以理解为是一个分支。截止到目前,只有一条时间线,在Git里,这个分支叫主分支,即 master 分支。再来理解一下HEAD,HEAD严格来说不是指向提交,而是指向master,master才是指向提交的,所以,HEAD 指向的就是当前分支。

2.1 创建分支 git branch

使用命令:git branch

当前只有master主分支

当我们创建新的分支后,Git 新建了一个指针叫 dev, * 表示当前 HEAD 指向的分支是 master 分 支。另外,可以通过目录结构发现,新的 dev 分支:

在.git里就变化了:

这俩个分支指向的都是最新一次的提交,发现都是一样的:

2.2 切换分支 git checkout

使用命令:git checkout

注意加上--的才是版本回退的命令,这里是修改分支的。

这里的*就跑到dev上面了。

测试修改dev分支,那么主分支有什么变化?

简述一下:在dev分支下,修改file4文件,加一行“dev”。

现在切换会master分支,发现添加的“dev”字样没了:

切回dev分支的话,依然是在的:

2.3 合并分支 git merge

使用命令:git merge

这里就能看到dev了。

git merge 命令用于合并指定分支到当前分支。合并后,master就能看到dev分支提交的内容 了。此时的状态如图如下所示。

Fast-forward 代表“快进模式”,也就是直接把master指向dev的当前提交,所以合并速度非常快。 当然,也不是每次合并都能Fast-forward。

2.4 删除分支 git branch -d

合并完成后,dev分支对于我们来说就没用了,那么dev分支就可以被删除掉,注意如果当前正处于某分支下,就不能删除当前分支,如:

使用命令:git branch -d

注意就是不能处于被删除的分支下。

因为创建、合并和删除分支非常快,所以Git鼓励你使用分支完成某个任务,合并后再删掉分支,这和直接在master分支上工作效果是一样的,但过程更安全。

2.5 合并冲突

可是,在实际分支合并的时候,并不是想合并就能合并成功的,有时候可能会遇到代码冲突的问题。 为了演示这问题,创建⼀个新的分支dev1 ,并切换至目标分支,我们可以使用git checkout - b dev1 一步完成创建并切换的动作,

在dev1分支下去修改file4文件并commit。

切换回master分支:

此时的状态就相当于是:

此时去合并:

合并冲突了。

在vim中查看:

“ < ”和 “ = ”之间的是当前分支的代码,“ = ” 和“ > ”之间的是另一个分支的代码,在这些符号之间的是冲突代码。

必须我们自己去解决冲突,删除不要的:

记得一定要commit!

此时的状态相当于是:

dev1指向的还是自己的分支:

找到commit id可以看到对应的还是“修改了aaa”

这里切换到dev1分支也可以看到:

使用命令:git log --graph --abbrev-commit

看起来更清晰:

2.6 分支管理策略 git merge --no-ff -m

通常合并分支时,如果可能,Git 会采用 Fast forward 模式。还记得如果我们采用 Fast forward 模式之后,形成的合并结果是什么呢?

在这种 Fast forward 模式下,删除分支后,查看分支历史时,会丢掉分支信息,看不出来最新提 交到底是 merge 进来的还是正常提交的。但在合并冲突部分,我们也看到通过解决冲突问题,会再进行一次新的提交,得到的最终状态为:

那么这就不是 Fast forward 模式了,这样的好处是,从分支历史上就可以看出分支信息。例如我 们现在已经删除了在合并冲突部分创建的 dev1 分支,但依旧能看到 master 其实是由其他分支合并 得到:

也就是说如果是Fast forward 模式的话,这里就只能看到是一条线。如果是合并冲突的话可以看到是两条线合在一起。

先在dev2分支下修改file4:

切换回master后,使用合并命令时带上选项--no-ff ,请注意 --no-ff 参数,表示禁用 Fast forward 模式。禁用 Fast forward 模式后合并会创建一个新的 commit ,所以加上 -m 参数,把描述写进去。

此时就可以看的清晰了,一定是不同的分支提交的:

2.7 分支策略

首先,master分支应该是非常稳定的,也就是仅用来发布新版本,平时不能在上面干活;

那在哪干活呢?干活都在dev分支上,也就是说,dev分支是不稳定的,到某个时候,比如1.0版本发布 时,再把dev分支合并到master上,在master分支发布1.0版本;你和你的小伙伴们每个人都在dev分支上干活,每个人都有自己的分支,时不时地往dev分支上合并就可以了。 所以,团队合作的分支看起来就像这样

2.8 bug分支 git stash

假如我们现在正在 dev2 分支上进行开发,开发到一半,突然发现 master 分支上面有 bug,需要 解决。在Git中,每个 bug 都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。

可现在 dev2 的代码在工作区中开发了一半,还无法提交,怎么办?例如:

简述一下:在dev2分支下,修改了file4文件,我们不去commit,切换回master的话再工作区也会看到被修改的内容

使用命令:git stash

此时再切换为dev2执行这个命令:

保存在哪?

.git目录下,这里会多一个stash:

status查看就是干净的:

存起来之后,master分支就看不到了:

现在添加一个临时分支来修bug:

假设加上1111后,bug修复了。

然后就是commit,切换到主分支后再去合并。此时的fix_bug使命就完成了,再去管我们正在开发的dev2.

使用命令:【git stash list】【git stash pop】

然后开发完毕,就要commit,此时的状态是这样的:

可以看到,修改bug的时候,对主分支上面的代码修改了,dev2分支的代码和master的最新提交的代码不一样(dev2上面的代码还是基于master分支创建的那个有bug的代码)。合并的话会合并冲突?

解决这个问题的一个好的建议就是:最好在自己的分支上合并下 master ,再让 master 去合并 dev ,这样做的目的是有冲突可以在本地分支解决并进行测试,而不影响 master 。此时的状态 为

演示一下:

有冲突。之后就手动的去解决冲突,再去提交:

切换回master,再去合并,就不会有问题了:

2.9 强制删除分支 git branch -D

也就是说,在merge之前,新的节点已经创建创建出来了,使用-d选项删不掉,切换一下就行了:

换成-D就行了。

三. 远程操作

3.1 克隆远程仓库 git clone

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

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

HTTPS远程登录

HTTPS的就是直接clone:

注意不要在本地仓库的目录下去执行。

fetch是拉的意思,push是推的意思

SSH远程登录

在远程的gitee仓库点击设置:

此时如果直接去链接的话就会失败:

第一步:创建SSH  Key。在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有 id_rsa 和 id_rsa.pub 这两个文件,如果已经有了,可直接跳到下一步。如果没有,需要创建 SSH Key:

我这里没有

使用命令:ssh-keygen -t rsa -C "你的邮箱@qq.com"

此时就有公钥和私钥了。

把id_rsa.pub里面的内容完全的复制下来,到

此时就可以了。

如果有多个人协作开发,GitHub/Gitee 允许添加多个公钥,只要把每个人的电脑上的  Key 都添加到 GitHub/Gitee,就可以在每台电脑上往 GitHub/Gitee 上提交推送了。

当我们从远程仓库克隆后,实际上 Git 会自动把本地的 master 分支和远程的 master 分支对应起来, 并且,远程仓库的默认名称是 origin 。

3.2 向远程仓库推送 git push

首先要做的就是配置git,这里参考1.2.

这里就是在仓库的目录下添加了一个文件,并且commit了,这里再去用git status去查看的话里面会多出来两行内容,就是关于远程仓库的。

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

成功的话,在远程仓库就会出现:

推送成功!这里由于我们使用的是 SSH 协议,是不用每一次推送都输入密码的,方便了我们的推送操 作。如果你使用的是 HTTPS 协议,有个麻烦地方就是每次推送都必须输入口令。

3.3 拉取远程仓库 git pull

假如远程仓库更新了一行代码,本地仓库就需要拉取:

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

pull的作用其实是拉取和合并两个作用。

在本地也就可以看到了:

3.4 忽略特殊文件 .gitignore

在日常开发中,我们有些文件不想或者不应该提交到远端,比如保存了数据库密码的配置文件,那怎么让 Git 知道呢?在 Git 工作区的根目录下创建一个特殊的 .gitignore 文件,然后把要忽略的文件名填进去,Git 就会自动忽略这些文件了。不需要从头写 .gitignore 文件,gitee 在创建仓库时就可以为我们生成,不过需要我们主动勾选⼀ 下:

里面写上:

在工作区我创建一个文件a.so,使用git status就不会显示出来:

当然可以强制去加 git add -f:

在.gitignore文件里,前面带上!表示不排除c.so

有些时候文件太多可能自己也会糊涂,为什么某某某文件被忽略了?

使用命令:git check-ignore -v a.so

3.5 给命令配置别名 git config --global alias.

将 git status 简化为 git st ,对应的命令为:

--global 参数是全局参数,也就是这些命令在这台电脑的所有Git仓库下都有用。如果不加,那只 针对当前的仓库起作用。

四. 标签管理

4.1 理解标签

标签 tag ,可以简单的理解为是对某次commit 的一个标识,相当于起了一个别名。例如,在项目发布某个版本的时候,针对最后一次 commit 起一个 v1.0 这样的标签来标识里程碑的意义。这有什么用呢?相较于难以记住的 commit id , tag 很好的解决这个问题,因为 tag 一定要给一个让人容易记住,且有意义的名字。当我们需要回退到某个重要版本时,直接使⽤标签就能很快定位 到。

4.2 创建标签 git tag

给最新的一次提交打上标签v1.0,在.git文件中可以查看到,打印里面的内容,对应的就是最新的一次提交的内容:

当然也可以给其他的版本打标签:

也可以加上对应的描述,git show可以查看标签信息:

删除标签:

4.3 推送标签

在远程仓库中就可以看到了:

也可以一次性全部推送:

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

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

五. 多人协作

5.1 多人协作一

准备工作

先在远程创建一个dev分支:

再把远程的分支pull到本地:

拉取成功

再去我们的Windows创建:

找一个空目录,按“shift + 鼠标右键”,打开Powershell窗口:

git clone就行:

这样就是开发者2:

协作开发(dev分支)

开发者一:

注意不能直接对远程仓库的dev分支去开发。所以在本地就需要去创建dev分支。

此时虽然有了dev分支但是还没有跟远程的仓库关联:

使用命令:git push -u origin dev

当然也可以在本地仓库创建的时候直接可以关联:

使用命令:git checkout -b dev origin/dev

简诉一下:在dev分支下的file.txt文添加一行aaa,然后推送到远端。

那么在远端仓库的dev分支下,就可以看到(master分支看不到):

开发者二:

git checkout -b dev [dev] [origin/dev]这里不加远程的话就是不建立链接的意思

首先是去创建分支,然后这里用另一种方式建立关联:

创建分支完毕之后,添加一行bbb,再去push 的话就会失败:

此时就需要我们去使用git pull 拉取下来,再去手动解决问题:

改成我们想要的就可以:

然后再去add,commit,push就行了:

此时的远程仓库的dev分支就会:

但是现在是dev分支,master是没有的:

协作开发(master分支)

一种就是Pull Request

一种就是本地

就是本地的master分支去合并dev分支,再去推送到远程仓库。

注意顺序,本地master一定要是最新的。

先去pull下来:

保持好习惯,保证本地的master一定是最新的:

再去切换到dev,去merge  master。

切换到master去merge dev

最后一步,去push

不要忘记把dev分支删掉就行了。

• 首先,可以试图用 git push  origin  branch-name 推送自己的修改;

• 如果推送失败,则因为远程分支比你的本地更新,需要先用 git pull 试图合并;

• 如果合并有冲突,则解决冲突,并在本地提交;

• 没有冲突或者解决掉冲突后,再用git  push  origin  branch-name推送就能成功!

• 功能开发完毕,将分支 merge 进 master,最后删除分支。

5.2 多人协作二

准备工作

这里就不在远程建立分支了,直接在本地建立分支

开发者一:

建立一个分支feature-1,在新分支下创建文件function1.

此时直接去git push肯定是不行的,因为没有对应的分支,这里就需要git push origin feature-1

本地有:

远程也有:

开发者二:

跟上面的一样,直接push也不行:

开发者一帮开发者二开发

在开发者1中,只能看到自己的feature-1

使用 git pull

注意:

拉取分支内的内容才需要建立链接,而分支本身不属于分支内的内容,所以可以把git pull 的操作分为两类(所以上面的没有建立链接,依然是可以拉取仓库里的内容的):

再搁本地去创建feature-2分支,并且与远程仓库相关联:

此时我们就可以进入到开发者2 的文档:

在开发者二中:

使用pull操作可以拿下来开发者1开发的东西。注意这里的pull 是需要建立链接的,feature-2要与远程的feature-2对应。

此时的开发者二再去写代码,写完之后直接push就可以,这里不会冲突了。

合并到master

创建完pull request之后,就会提交给审核:

这个比较简单,简单看一下就行了。

然后就是合并另一个分支与master,我的建议依旧是先把master分支合并给feature,然后再合并给feature:

现在是开发者二,上面使用pull request 的方式的是开发者一。当然这里也可以去使用pull request,但是可能会冲突,还是使用本地的方式去:

先更新master:

依然是跟上面的5.1的一样,切换到feature-2去合并master,(在切换到master去合并feature-2,最后在push)或者(feature-2合并完成master之后,没有冲突了,再去使用pull request也可以)

看远程仓库,完成多人开发:

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

也就是说,远程的分支删除了,但是在本地依然可以看到

使用命令: git remote show origin

使用命令:git remote prune origin

六. Git分支设计规范

环境有了概念后,那么对于开发人员来说,一般会针对不同的环境来设计分支,例如:

以下是按照要求整理的Git分支管理表格,采用Markdown格式:

Git分支管理表

分支名称 适用环境 说明
master 生产环境 主分支,稳定版本
release 预发布/测试环境 预发布分支
develop 开发环境 日常开发主干分支
feature 本地 需求开发分支
hotfix 本地 紧急修复分支

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 Flow模型。


网站公告

今日签到

点亮在社区的每一天
去签到