重学Git

1 Git介绍

# Git的作用
1 对文件(代码)进行版本管理
2 完成 协同开发 项目,帮助程序员整合代码
	i)帮助开发者合并开发的代码
	ii)如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突

# Git简介
Git是分布式版本控制系统,控制的对象是开发的项目代码

# 举例
比如你在写毕业论文,想删除一个段落,又怕将来想恢复找不回来怎么办?
于是你先把当前文件另存为一个新的文件,再接着改,改到一定程度,再另存为成另一个新文件,这样一直改下去,最后你的文件变成了:
	-毕业论文1.doc
  -毕业论文2.doc
  -毕业论文3.doc
  -毕业论文-永不修改版.doc
  -毕业论文-打死不改版.doc
  -毕业论文-再改去死版.doc
  
过了一段时间,你想找回被删除的文字,但是已经记不清删除前保存在哪个文件里了,只好一个一个文件去找
看着一堆乱七八糟的文件,想保留最新的一个,然后把其他的删掉,又怕哪天会用上,还不敢删

2 Git 和SVN

image-20230222184031470 image-20230222184058518

**Git:分布式,无网络时也可以提交到本地版本库,待到有网络时再push到服务器. **

svn:非分布式.无网络不可以提交

3 Git,GitHub,GitLab,Gitee

Git:是一种版本控制系统,是一个命令,是一种工具。

GitHub:是一个基于Git实现的在线代码托管仓库,包含一个网站界面,向互联网开放,公有仓库免费,部分私有仓库收费,全球最大的开源代码托管平台

GitLab:是一个基于Git实现的在线代码仓库托管软件,可以通过GitLab自己搭建一个类似于GitHub一样的系统,用在企业内部网络搭建Git私服,用于企业团队内部协作开发

Gitee:(码云) 是 OSCHINA 推出的代码托管平台,支持 Git 和 SVN,提供免费的私有仓库托管,面向互联网开发,分收费和付费,中国最大的开源代码托管平台

4 Git工作流程

image-20230222184116353

5 Git使用

5.1 流程(核心总结)

"""
1)有红色信息(工作区有内容),就执行 add 
2)全绿信息(内容全部在暂存区),才执行 commit
3)只有被版本库控制的代码,才能被监听,所以可以回滚到任何一个版本
"""

5.2 安装

# 1.下载对应版本:https://git-scm.com/download
# 2.安装git:在选取安装路径的下一步选取 Use a TrueType font in all console windows 选项

5.3 基础命令

将已有的文件夹 - 初始化为git仓库

"""
>: cd 目标文件夹内部
>: git init
"""

在指定目录下 - 初始化git仓库

"""
>: cd 目标目录
>: git init 仓库名
"""

在仓库目录终端下 - 设置全局用户

"""
>: git config --global user.name '用户名'
>: git config --global user.email '用户邮箱'

注:在全局文件 C:\Users\用户文件夹\.gitconfig新建用户信息,在所有仓库下都可以使用
"""

在仓库目录终端下 - 设置局部用户

"""
>: git config user.name '用户名'
	-- 用户名
>: git config user.email '用户邮箱'
	-- 用户邮箱
	
注:在当前仓库下的config新建用户信息,只能在当前仓库下使用
注:一个仓库有局部用户,优先使用局部用户,没有配置再找全局用户
"""

查看仓库状态

"""
# 当仓库中有文件增加、删除、修改,都可以在仓库状态中查看
>: git status  
	-- 查看仓库状态
>: git status -s  
	-- 查看仓库状态的简约显示
"""

工作区操作

# 通过任何方式完成的文件删与改
# 空文件夹不会被git记录

撤销工作区操作:改、删(了解)

"""
>: git checkout .
	-- 撤销所有暂存区的提交
>: git checkout 文件名
	-- 撤销某一文件的暂存区提交
"""

工作区内容提交到暂存区

"""
>: git add .  
	-- 添加项目中所有文件
>: git add 文件名  
	-- 添加指定文件
"""

撤销暂存区提交:add的逆运算(很少使用)

"""
>: git reset HEAD .
	-- 撤销所有暂存区的提交
>: git reset 文件名
	-- 撤销某一文件的暂存区提交
>: git reset .
	-- 撤销所有暂存区的提交
"""

提交暂存区内容到版本库

>: git commit -m "版本描述信息"

撤销版本库提交:commit的逆运算

"""
回滚暂存区已经提交到版本库的操作:
    查看历史版本:
        >: git log
        >: git reflog
    查看时间点之前|之后的日志:
        >: git log --after 2018-6-1
        >: git log --before 2018-6-1
        >: git reflog --after 2018-6-1
        >: git reflog --before 2018-6-1
    查看指定开发者日志
        >: git log --author author_name
        >: git reflog --author author_name
    回滚到指定版本:
        回滚到上一个版本:
            >: git reset --hard HEAD^
            >: git reset --hard HEAD~
        回滚到上三个版本:
            >: git reset --hard HEAD^^^
            >: git reset --hard HEAD~3
        回滚到指定版本号的版本:
            >: git reset --hard 版本号 (重点)
            >: eg: git reset --hard 35cb292
"""

扩展阅读

# git log 和git reflog的区别
git log 命令可以显示所有提交过的版本信息
如果感觉太繁琐,可以加上参数  --pretty=oneline,只会显示版本号和提交时的备注信息
git reflog 可以查看所有分支的所有操作记录(包括已经被删除的 commit 记录和 reset 的操作)


# git reset --hard,--mix,--soft的区别
hard (硬)-> 全部删除,会彻底返回到回退前的版本状态,了无痕迹
mixed (中)-> 保留工作目录,文件回退到未commit的状态
soft (软)-> 保留工作目录、暂存区 ,文件会回退到未 add(未到暂存)的状态
总结:
soft是撤销commit的提交,但工作区未提交的更改还是保留;
mixed是撤销暂存区的提交,工作区的更改同样也保留;
而hard是把工作区、暂存区、commit到仓库的三个版本都回滚了

6 Git忽略文件

Git工作目录中,有些文件必须要有,但又不能提交它们,就可以设置忽略文件

在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名放进去,Git就会自动忽略这些文件

# .gitignore 文件

# 1)在仓库根目录下创建该文件
# 2)文件与文件夹均可以被过滤
# 3)文件过滤语法

""" 过滤文件内容
文件或文件夹名:代表所有目录下的同名文件或文件夹都被过滤
/文件或文件夹名:代表仓库根目录下的文件或文件夹被过滤

例如:
a.txt:项目中所有a.txt文件和文件夹都会被过滤
/a.txt:项目中只有根目录下a.txt文件和文件夹会被过滤
/b/a.txt:项目中只有根目录下的b文件夹下的a.txt文件和文件夹会被过滤
*x*:名字中有一个x的都会被过滤(*代表0~n个任意字符)
空文件夹不会被提交,空包会被提交,包可以被提交(包中有一个init空文件)


注意:
# 以'#'开始的行,被视为注释.                                                                                                                          
# 忽略掉所有文件名是 lqz.txt的文件.
	lqz.txt
# 忽略所有生成的 html文件,
*.html
# lqz.html是例外,不在忽略范围内
!lqz.html
# 忽略所有.o和 .a文件.
*.[oa]

"""

7 Git分支

7.1 基本使用

"""
1.创建分支
git branch 分支名

2.查看分支
git branch

3.切换分支
git checkout 分支名

4.创建并切换到分支
git checkout -b 分支名

5.删除分支
git branch -d 分支名

6.查看远程分支(列出所有分支,包含远程)
git branch -a

7.合并分支
git merge 分支名
把dev分支合并到master分支:切换到master分支,执行合并dev分支的命令

8.删除远程分支
git push origin --delete lqz

9.新建远程分支
本地lqz分支建立完成
git push origin lqz 
"""


"""
1)多个开发者都是在一个分支上进行开发,不出意外,该分支一定叫dev(协同开发)
2)如果出现一个特殊任务(敏感任务),与正常业务关系不紧密,甚至可能大的影响正常的dev分支开发,可以依赖dev开一个子分支,进行开发,开发完毕后合并到dev分支,再删除该分支即可
3)所有的开发任务都可以在dev分支上进行(除非公司硬性要求不能直接在dev分支开发,只能在dev子分支开发,测试通过后才能合并给dev)
"""

7.2 dev分支合并到master分支

image-20230222184143360

7.3 基于分支的线上bug修复(开发新功能,出现bug)

image-20230222184158064
# 无冲突情况
git branch dev # 创建dev分支
git checkout dev # 切换到dev分支
vi d3.txt       # 新增d3.txt
git add .
git commit -m 'd3.txt' # 提交到版本库
git checkout master    # 切换到master分支
git branch bug         # 创建bug分支
git checkout bug       # 切换到bug分支
vi b4.txt              # 在bug分支,新增b4.txt  
git add .
git commit -m 'b4.txt'
git checkout master    # 切换回master分支
git merge bug          # 合并bug分支
git log
git merge dev          # 合并dev分支,无冲突,写注释
git log
git branch -d dev
git branch -d bug

# 有冲突情况
git branch dev # 创建dev分支
git checkout dev # 切换到dev分支
vi d4.txt       # 新增d4.txt
git add .
git commit -m 'd4.txt' # 提交到版本库
git checkout master    # 切换到master分支
git branch bug         # 创建bug分支
git checkout bug       # 切换到bug分支
vi b4.txt              # 在bug分支,新增b4.txt  
git add .
git commit -m 'd4.txt'
git checkout master    # 切换回master分支
git merge bug          # 合并bug分支
git log
git merge dev          # 合并dev分支,出冲突
'''
CONFLICT (add/add): Merge conflict in d4.txt
Auto-merging d4.txt
Automatic merge failed; fix conflicts and then commit the result.
'''
# 打开d4.txt发现如下错误
<<<<<<< HEAD    # 原来代码
bug-add-d4
=======         # 新代码
sada
>>>>>>> dev
#  手动修复,解决冲突,再提交

git add .
git commit -m '解决冲突'
git log

8 Git远程仓库

我们要协同开发,代码要提交到远程仓库,可以使用gitee,github,gitlab,本文以gitee为例

8.1 创建远程仓库

# 首先注册gitee账号,登陆后,创建仓库

image-20230222184220656

image-20230222184253259

**注意:git push -u origin master 中-u的意思是,只要执行一遍这个命令,以后执行git push 就等同于git push origin maste,所有-u表示设置一个默认 **

8.2 remote源操作

"""
1)查看仓库已配置的远程源
>: git remote
>: git remote -v

2)查看remote命令帮助文档
>: git remote -h

3)删除远程源
>: git remote remove 源名
eg: git remote remove origin

4)添加远程源
>: git remote add 源名 源地址
>: git remote add orgin https://gitee.com/liuqingzheng/app01.git

5)提交代码到远程源
>: git push 源码 分支名

6)克隆远程源
>: git clone 远程源地址
"""

"""
1)通过克隆方式连接远程源,默认远程源名就叫origin;所以主动添加远程源来连接远程仓库,源码也用origin
2)本地一个仓库只需要和远程一个源进行同步,所以只需要连接一个远程源,如果还想把本地代码同步给第三个平台,那么可以通过主动添加远程源来连接第三个平台的远程仓库,此时的源码就不能再叫origin了,比如online都可以
3)pull和push都可以提供选择不同的源码,和不同的远程仓库交互
"""

8.3 采用ssh协议连接远程源

# 生成公钥私钥,帮助文档
官网:https://gitee.com/help/articles/4181#article-header0

# 在命令行下执行命令
ssh-keygen -t rsa -C "306334678@qq.com" # 邮箱可以任意填写

# 生成的公钥私钥,会放在用户家路径下的.ssh文件夹下
本机命令,查看公钥:cat ~/.ssh/id_rsa.pub
# 复制公钥,粘贴到gitee上配置
	-项目仓库 => 管理 => 部署公钥管理 => 添加公钥 => 添加个人公钥
  
# 把原来的 origin删除,新增ssh源
git remote remove orgin
git remote add orgin git@gitee.com:liuqingzheng/app01.git
  
# 配置成功后,再拉取和提交代码,不需要输入用户名密码认证了

image-20230222184313791

8.4 如何成为其他码云项目的开发者

如果公司项目已经存在,同事新入职,基于原项目开发
"""
1)生成自己电脑的公钥,配置到自己的码云个人公钥中
2)把自己的码云用户名提供给别人,别人添加你成为项目开发者
3)自己确认添加,成为开发者,克隆开发项目,进行开发
"""

8.5 协同开发

"""
1)作为开发者,第一次同步项目
>: git clone 项目地址

2)保证自己本地有dev分支,且与远程仓库版本同步(没有就自己新建)

3)本地开发的代码,必须add、commit到本地版本库后,才和远程仓库进行交互

4)交互顺序:必须 先拉(pull)后提(push)

5)必须切换到要交互的分支,在与远程同名的分支进行交互,如本地dev与远程dev交互
>: git checkout dev
>: git add .
>: git commit -m '本次提交的信息提示'
>: git pull origin dev
>: git push origin dev
"""

8.6 线上分支合并(提交pr)

无冲突情况

# 本地创建分支
git branch dev

# 把本地分支提交到远程
git push  origin dev

# 在本地dev分支修改代码
git checkout dev
vi d5.txt
git add .
git commit -m '新增d5'

# 推送到远程
git push  origin dev

image-20230222184333398

image-20230222184348010

image-20230222184402168

有冲突情况


git pull origin master  # 主分支拉取最新
vi d5.txt
git add .
git commit -m '修改d5.txt'
git push  origin master  # 主分支修改一行,提交到远程

git checkout dev  # 切换到dev分支
 vim d5.txt
git add .
git commit -m 'dev修改d5.txt'
git push  origin dev    # 修改同一行,提交到远程,注意同一行内容不能一致


## 线上提交pr,线上不能自动合并,需要手动合并
git checkout master
git pull https://gitee.com/liuqingzheng/app01.git dev
# 手动修改冲突
git add .
git commit -m '合并pr'
git push origin master

# 再去线上,看到分支已经合并好了

8.7 远程仓库回滚

"""
用dev分支举例
1)本地切换到远程要回滚的分支对应的本地分支
git checkout dev

2)回滚本地分支
git reset --hard 版本号

3)本地版本强行提交给服务器
git push origin dev -f
"""

9 冲突解决

9.1 多人开发同一分支导致冲突

"""
1)在远程仓库和本地仓库版本不一致时,拉取远程仓库版本到本地时,两个版本进入融合,可能会出现版本冲突

2)定位冲突文件冲突代码,线下沟通冲突代码,整合代码解决冲突

3)将解决冲突后的代码重新提交到本地版本库

4)再拉去远程仓库,直到没有冲突,提交本地版本库到远程
"""

"""
<<<<<<< HEAD  # 冲突的开始
# 自己的代码
=======  # 分割线
# 别人的代码
>>>>>>> b63c408abd05b87fc492d40523240561999dba50  # 冲突的结束(版本)
"""

"""
1)删除冲突相关标识:冲突的开始、分割线、冲突的结束(版本)
2)线下沟通,根据实际需求完成代码整合
3)测试整合后的代码

"""

"""
出现冲突的前提:
1)不同开发者同时操作了同一文件
2)并且在相同行写了代码
强调:有业务交际时,版本合并不一定会出现冲突相关的标识,但是可能会带着代码运行崩溃,所有理论上每一次版本合并,都要测试合并后的所有功能(及其之少的情况)
"""

9.2 分支合并导致冲突

分支合并出现冲突效果跟上面一样,只需要解决冲突,重新提交即可

"""
<<<<<<< HEAD  # 冲突的开始
# 自己的代码
=======  # 分割线
# 别人的代码
>>>>>>> dev  # 冲突的分支
"""

10 同一个人在公司开发和在家开发

image-20230222184419277

10.1 正常情况

# 公司电脑,有代码
git branch lqz
git checkout lqz # 创建一个自己的分支,写代码
vi new.txt
git add .
git commit -m '公司开发了'
git push origin lqz

# 家里电脑,没有代码,需要先克隆
cd Desktop/proj
git clone https://gitee.com/liuqingzheng/app01.git
cd app01
git pull origin lqz #拉取lqz分支内容
git checkout lqz    # 切换到lqz分支
# 基于此继续开发,公司开发的代码也拉下来了,写完记得提交到远程

# 到了公司只需要再pull一下即可把家中开发的开发同步过来

10.2 公司忘记提交代码情况

# 忽然有一天,在公司开发了代码,没有提交到远程仓库
# 回家就没法拉取最新公司开发的代码,只能基于远程仓库最新代码继续开发其他功能(跟公司开发的功能不一样)
# 在家中开发完成提交到远程

# 第二条天到公司,拉取远程最新代码(可能有冲突)

11 Git标签管理

# 1 打tag
git tag -a "v1.0" -m "new tag v1.0"
# 2 推送tag到远程
git push origin v1.0
# 3 可以看到远程有tag了
# 4 基于其他位置打log
git reflog # 查看日志id
# 5 打tag
git tag -a "v1.1" id号 -m 'test'
# 6 推送tag到远程
git push origin v1.1

12 为开源项目贡献代码

# 第一步:fork开源代码,fork后,在你的个人仓库里就可以看到这个开源代码了(相当于copy了一份)

# 第二步:在自己仓库进行修改
修改代码,提交暂存,提交到版本库,提交到自己gitee

# 第三步:给开源作者提交pr

# 第四步:开源软件作者就会收到pr,他选择是否合并,合并后,你就成了开源软件开发者

image-20230222184433349

13 变基操作(rebase)

让提交记录变得更加简洁

13.1 第一,多个记录整合成一个记录

image-20230222184454725

git branch lqz  # 创建分支lqz
git checkout lqz # 切换到分支lqz
vi lqz.txt       
git add .
git commit -m '增加lqz.txt' # 新增lqz.txt 并提交

vi lqz1.txt
git add .
git commit -m '增加lqz1.txt' # 新增lqz1.txt 并提交

vi lqz2.txt
git add .
git commit -m '增加lqz2.txt' # 新增lqz2.txt 并提交

git log   # 查看版本日志

# 指定合并从当前版本开始往前的哪个版本(不包含)
git rebase -i 8fa035cd6805e8b35ccb9ceee9a9710c9b819b3c
# 把第二行开始,改为s
# 加入注释,合并后的注释
git log # 只能看到合并后的注释了,多次更改变成了一次


# 注意:已经提交到远程仓库的版本,不要再使用rebase,只合并本地版本提交的几率

13.2第二,解决分支合并分叉问题

image-20230222184514470

#### 正常merge合并
git branch dev
git checkout dev
vi dev.txt
git add .
git commit -m 'dev增加dev.txt'

git checkout master
vi master.txt
git add .
git commit -m 'master增加master.txt'

# 使用merge合并
git merge dev # 写入注释合并

# 图形化查看版本情况
git log --graph


##### 使用rebase合并
git branch -d dev # 删除dev分支

git branch dev
git checkout dev # 新建,切换到dev分支
vi dev1.txt
git add . 
git commit -m 'dev 增加dev1.txt' # 新建dev1.txt 并提交到版本库


git checkout master
vi master1.txt
git add .
git commit -m 'master增加master1.txt' # 切换到master,新建master1.txt,并提交到版本库

git checkout dev
git rebase master  # 切换到dev分支,完成变基

git checkout master
git merge dev     # 切换到master,完成合并

git log --graph   # 查看,变成了一条线

image-20230222184544169

image-20230222184600017

rebase合并出冲突情况解决

git branch -d dev # 删除dev分支

git branch dev
git checkout dev # 新建,切换到dev分支
vi lqz.txt       # 在内部增加一行话
git add . 
git commit -m 'dev 增加lqz.txt' # 新建lqz.txt 并提交到版本库


git checkout master
vi lqz.txt
git add .      # 在内部也增加一行话
git commit -m 'master增加lqz.txt' # 切换到master,新建lqz.txt,并提交到版本库

git checkout dev
git rebase master  # 切换到dev分支,完成变基,出现冲突

# 解决冲突
vi lqz.txt  # 把冲突解决掉

# 查看状态
git status # git rebase正在进行状态
# 继续往下走
git add .
git rebase --continue



git checkout master

git merge dev     # 切换到master,完成合并

git log --graph   # 查看,变成了一条线



git rebase --continue

13.3 第三

git branch -d dev
git branch dev
git checkout dev # 删掉dev,重新创建,并切换到dev分支

git push origin dev # 把本地dev同步到远程

vi gs.txt
git add .
git commit -m '公司写了代码,提交到本地'  # 忘了提交到远程仓库


# 回家后,继续开发,从远程拉下来
mkdir pr
cd pr
git clone https://gitee.com/liuqingzheng/app01.git  # 把代码克隆下来
cd app01
git checkout dev   # 切换到dev分支,此时是没有gs.txt的

vi j.txt           # 在家继续开发
git add .
git commit -m '家里写了代码'  
git push origin dev      # 家里写的代码提交到远程仓库



# 第二天来到公司,拉取代码继续开发,如果直接拉取,会分叉
# 不使用git pull 拉取代码,会分叉
# 先 git fetch 拉取
git fetch origin dev  # 先拿下来,自定合并代码,使用merge合并会分叉
# 使用rebase合并
git rebase origin/dev

'''
由原来的 git pull origin dev
变成
git fetch origin dev
git rebase origin/dev

'''

image-20230222184621549

14 git pull 和git fetch

1. 相同点
首先在作用上他们的功能是大致相同的,都是起到了更新代码的作用。
2. 不同点
git pull 类似于 git fetch+git merge
posted @ 2021-09-24 03:06  刘清政  阅读(915)  评论(0编辑  收藏  举报