Git学习笔记

Git学习笔记

概述

概念Git是一个分布式版本控制工具可以结合github、gitee、gitlab等代码托管平台对项目进行管理开发,在项目中,我可以对项目的每一次修改提交定义为一个版本,例如应用也分1.1版本,1.2版本等等。Git对于计算机工作中是一个管理我们代码的一个重要的工具

实际工作场景和功能

  1. 备份:对于实际开发中,备份是一个很重要的功能,可以避免数据丢失导致无法找回问题
  2. 代码还原:在开发中,我们总会因为修改以及更新代码不恰当导致一些需要的代码丢失或者代码面目全非,这个时候我们就需要代码回滚到上一个版本来重新获得
  3. 协同开发:在企业的开发中,一个项目肯定不可能只有一个人来维护和开发,所以对于各个人的分工实现的代码,如何进行合并,git可以结合托管平台来实现这一功能,大大降低了管理成本
  4. 可以追溯问题代码的编写人和编写日期:当企业项目开发中,出现问题代码时,就可以利用git的上传日志来进行追责

版本控制器

  1. 集中式版本控制工具:示例有SVN和CVS将版本库集中存放在中央服务器中,每次修改提交则会向中央服务器进行递交提交,但是这会出现一个问题,当中央服务器出现问题(宕机等等)导致数据丢失则会造成很严重的问题,因此现在基本没有企业会用集中式版本控制工具
  2. 分布式版本控制工具Git每个开发人员都有在本地有个版本库,当在本地测试就可以将修改的文件放入暂存区,当我们需要向递交更新时会向远程仓库(共享版本库)提交,这样即使远程仓库丢失,而每个开发人员本地都有备份则就不会造成集中式版本控制工具的问题

Git

Git工作流程

Git工作流程图

  1. clone(克隆):从远程仓库中克隆代码到本地
  2. checkout(检出):从本地仓库中检出一个仓库分支进行修订
  3. add(添加):在提交前先将代码提交到暂存区
  4. commit(提交):提交到本地仓库中,本地仓库中保存修改的各个历史版本
  5. fetch(抓取):从远程仓库抓取到本地仓库,不进行任何合并动作
  6. pull(拉取):从远程仓库中拉去到本地仓库,自动进行很冰,然后放到工作区
  7. push(推送):修改完成后,将代码推送到远程仓库中

暂存区:.git目录下的index就是暂存区

工作区:除了.git目录的其他文件就是工作区

文件状态

  1. 已修改:修改了但没有保存到暂存区的文件
  2. 已暂存:修改后保存到暂存区中的文件
  3. 已提交:把暂存区提交到本地仓库后的状态

Git安装与初始化

Win/Mac

  1. 进入到Git官网
  2. 选择下载对应版本

image-20240807221658363

Linux

  1. 可以选择与Win/Mac下载方式一样
  2. 也可以通过包管理器下载
1
2
3
4
5
6
7
8
9
10
11
12
-- centos/redhat
yum -y install git

-- ubuntu/debian
sudo apt-get install git

-- archlinux
yay -S git
sudo pacman -S git

-- fedora
yum install git

ssh密钥配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-- 进入到.ssh目录中
cd .ssh

-- 输入以下命令生成密钥
ssh-keygen -t rsa -b 4096
-- 如果第一次就可以一路回车
-- 如果不是第一次,可以更改密钥文件名,要不然会默认将之前的密钥文件覆盖

-- 打开生成的密钥文件.pub后缀的
vi test.pub #将内容复制到github中进行配置ssh密钥

-- 如果修改文件名的话,则需要添加配置文件config
touch config
vi config

-- 添加以下内容
#github
Host github.com
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/test #这个是你连接github的ssh密钥文件的路径

初始化配置

  • 设置用户信息

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    -- git config命令参数
    省略(local):本地配置,只对本地仓库有效
    --global:全局配置,对所有仓库生效
    --system:系统配置,对所有用户生效

    -- 配置用户名
    git config --global user.name "your name"
    -- 配置邮箱
    git config --global user.email "your email"
    -- 存储配置(保存用户名和邮箱)
    git config --global credential.helper store
  • 查看配置信息

    1
    2
    git config --global user.name
    git config --global user.email

Git仓库使用

新建仓库

创建本地仓库创建并初始化一个空的本地仓库在你要创建仓库的目录下输入以下命令(Windows用户需要使用git bash输入)

1
2
3
4
-- 将当前目录初始化为git仓库,目录下出现.git文件即代表创建成功
git init
-- 在当前目录下创建一个git仓库(而不是当前目录初始化为git仓库),<repo>为仓库名
git init <repo>

克隆远程仓库将远程仓库的版本库克隆到本地

1
2
git clone <url>
-- <url>是要克隆的仓库url(可以是https,也可以是ssh)

查看仓库状态可以查看当前分支与上游分支的差异,以及是否有文件未提交等信息

1
git status

添加和提交文件

添加文件将修改的文件添加到仓库暂存区中

1
2
3
4
5
-- <file...>是可变长参数,也就是你可以将多个文件、目录下的修改的文件(参数为一个目录)、满足通配符(例如*.txt)的文件添加到暂存区中
git add <file...>

-- 以下命令可以将全部当前目录(.就是当前目录)已修改文件添加到暂存区
git add .

提交文件将暂存区中文件提交到本地仓库中

1
2
3
4
5
6
7
-- desc是提交的信息,这个是需要指定的
git commit -m "desc"

#小技巧,当commit后面添加-a -m参数时,就可以一个命完成添加暂存和提交的操作
git commit -a -m "desc"
#-a -m可省略成-am参数
git commit -am "desc"

回退版本

sort模式回滚回退到某一个版本,并且保留当前版本的工作区和暂存区的所有修改内容

1
2
-- <id>为要回退的版本id
git reset --sort <id>

hard模式回滚回退到某一个版本,并且丢弃当前版本的工作区和暂存区所有修改内容

1
2
-- <id>为要回退的版本id
git reset --hard <id>

mixed模式回滚git reset命令的默认参数,回退到某一个版本,并且只保留当前版本的工作区的修改内容,丢弃当前版本的暂存区的修改内容

1
2
-- mixed为默认参数(可以省略),<id>为要回退的版本id
git reset --mixed <id>

查看日志

查看提交记录可以查看提交的日志,不包括已经被删除的commit记录和reset的操作

1
2
3
4
5
6
7
8
9
10
11
-- 查看提交记录
git log <option>

-- 参数:
--all:为默认参数,也就是查看提交记录的所有信息
--oneline:简介模式,只查看提交id和提交信息
--graph:以图的形式显示
--abbrev-commit:使得显示的提交id更加简短

-- 简介模式,只查看提交id和提交信息
git log --oneline

查看所有操作记录查看所有历史操作日志,包括分支、标签和HEAD等引用过去操作中的指向记录,包括已经删除的commit记录和reset操作

1
git reflog

查看差异

查看差异查看工作区、暂存区、本地仓库之间的差异,也可以比较版本、分支之间的差异,会显示更改的文件以及更改的详细信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 命令后面不加参数,默认是比较工作区与暂存区之间的差异
git diff

-- 在命令后加入HEAD参数则可以比较工作区和本地仓库之间的差异
git diff HEAD

-- 在命令后加入--cached参数则可以比较暂存区和本地仓库之间的差异
git diff --cached

-- 比较两个版本差异,只需在命令加入要比较的两个版本提交id
git diff <id1> <id2>

-- HEAD可以表示当前分支的最新提交,然后我们可以使用某个版本与HEAD比较
git diff <id1> HEAD

-- 比较当前版本和上一个版本(使用HEAD~或HEAD^来表示)的差异,HEAD~2表示HEAD之前的两个版本
git diff HEAD~ HEAD

-- 我们也可以比较时指定要比较的文件,<file>表示指定文件名
git diff <id1> <id2> <file>

-- 比较分支之间的差异
git diff <branch_name1> <branch_name2>

查看暂存区文件

查看暂存区文件查看当前暂存区中存在的文件

1
git ls-files

删除文件

删除文件从暂存区和工作区中将指定文件删除,需要及时手动提交更新版本库

1
2
3
4
5
6
7
8
-- 把文件从工作区和暂存区中同时删除
git rm <file>

-- 把文件从暂存区删除,保留在工作区的文件
git rm --cached <file>

-- 递归删除某个目录下的所有子目录和文件
git rm -r *

忽略文件

引言:在提交版本库时,我们总有一些系统自动生成和用户运行产生的日志文件等等,我们不需要将其添加到版本库,这个时候我们就需要编写.gitignore这个文件,将一些以上所说的文件,让其忽略掉这些文件不被添加

忽略文件编写.gitignore文件,每个规则一行

1
2
3
4
5
6
7
-- 编写.gitignore文件
vim .gitignore

-- 添加以下信息来忽略具体文件、文件夹和匹配规则的文件或文件夹
1.txt #忽略1.txt文件
*.o #忽略所有后缀为.o的文件
hello/ #忽略hello文件夹

同步远程仓库

引言:因为本地仓库和远程仓库是互不影响的两个仓库,因此本地仓库进行修改不会影响到远程仓库,同理远程仓库修改也不会影响本地仓库,因此需要一种同步机制来将本地和远程仓库进行同步

添加远程仓库将指定远程仓库与本地仓库关联起来,并为其设置别名,用来同步远程仓库使用

1
2
3
4
5
6
7
8
9
10
11
-- <name>为远程仓库起的别名,<remote>为远程仓库ssh地址
git remote add <name> <remote>

-- 添加远程仓库
-- remote为远程仓库别名
-- branch1为本地仓库分支名
-- branch2为远程仓库分支名
git push -u <remote> <branch1>:<branch2>

-- 查看当前本地仓库对应的远程仓库的别名和地址
git remote -v

推送更新内容将本地仓库修改内容推送到远程仓库

1
2
3
4
5
#注意:如果两个分支名一样可以省略:<branch2>的内容
-- remote为远程仓库别名(可以自定义设置本地仓库对应的远程仓库)
-- branch1为本地仓库分支名
-- branch2为远程仓库分支名
git push <remote> <branch1>:<branch2>

拉取更新内容将远程仓库修改内容拉取到本地仓库中

1
2
3
4
5
6
7
8
9
#注意:会自动合并到本地仓库,如果本地仓库修改内容与远程仓库修改内容有冲突则无法完成合并
-- remote为远程仓库别名(可以自定义设置本地仓库对应的远程仓库)
-- branch1为远程仓库分支名
-- branch2为本地仓库分支名
-- 如果两个分支名一样可以省略:<branch2>的内容
git pull <remote> <branch1>:<branch2>

# 不会自动合并到本地仓库
git fetch <remote>

Git分支

概念

  • 分支分支适合团队协作和开发管理,多个开发人员在自己的分支上进行开发,最后再合并到主线中。这样可以让主线代码仓库处于一个随时可用的比较稳定的状态,而不会影响其他功能的开发和测试,可以提高团队写作的效率,减少冲突和错误的影响
  • 默认分支也就是没有创建分支,默认名字叫做main或者master

创建分支

查看当前所在分支查看当前处于的分支,分支名前有*则表示这是当前所在分支

1
git branch

创建分支为当前仓库创建新分支,并没有切换到新分支上

1
2
-- <name>为你要创建的分支名
git branch <name>

切换分支

切换分支切换当前所在的分支,如果只是想且切换分支,推荐使用switch进行切换

1
2
3
4
//git switch切换分支
#注意:git switch是专门用于切换分支的,不能够恢复文件
-- <name>为要切换到的分支名
git switch <name>

恢复分支

恢复分支:checkout也可以用于切换分支,但是当文件与分支名同名会发生冲突,可以使用checkout进行回退恢复到之前的某一个状态,也可以用于恢复分支

1
2
3
4
5
6
7
8
9
//git checkout切换分支
#注意:git checkout也可以用于恢复文件或者目录到之前的某一个状态,所以当文件名与分支名同名时,默认进行切换分支而不是恢复文件
-- <name>为要切换到的分支名
git checkout <name>


//git checkout恢复分支
-- <branch>为要恢复的分支,<commid>要恢复分支状态的提交节点id
git checkout -b <branch> <commid>

合并分支

合并分支将其他分支合并到当前分支,分支被合并是不会将这个分支删除

1
2
3
4
5
6
7
8
#注意:这是将其他分支合并到当前所在的分支上
-- <name>为其他分支名
git merge <name>

//例子:
#当前处于master分支
git merge test
#以上用于将test分支合并到master分支上

删除分支

删除分支将指定分分支进行删除

1
2
3
4
5
6
-- <name>为要删除的分支名
#注意:-d参数是需要被删除的分支已经被合并到其他分支,如果没有被合并的分支,是不能用-d参数将其删除
git branch -d <name>

#注意:-D参数会强制删除指定分支,不管分支是否被合并
git branch -D <name>

解决合并冲突

合并冲突当两个合并的分支中存在重合的修改内容时,git不知道保存哪个分支的修改内容,就会产生冲突,这个时候我们就需要手动解决冲突,例如修改了同一文件的同一行代码时

解决冲突

  1. 当出现合并冲突时,进行合并操作时,会出现以下报错,表示自动合并失败:

    image-20240905112127173

  2. 可以使用git status查看冲突文件列表

    image-20240905112236344

  3. 也可以使用git diff查看冲突的具体内容,HEAD表示当前分支的,”不好”则是HEAD的test.txt中冲突内容,”你好”则是test分支下的test.txt的冲突内容

    image-20240905112313980

  4. 然后手动操作将冲突内容需要的留下,不要的内容则删掉,将修改后的文件添加暂存区并且提交后会自动合并(因为当出现冲突,冲突的所有内容会出现在你的当前分支的冲突文件中,你可以选择留下需要的内容,然后再将其修改内容进行添加和提交,这样就会自动合并且留下你想要的内容),如果不想自动合并可以在合并冲突后就输入git merge --abort即可取消

    image-20240905113922922

    image-20240905113956489

    image-20240905113018655

分支变基

分支变基

  • 也是一种合并分支的一种方式,但是它只是将提交记录进行移植,使得两个分支变成一条主线,也就是将分支的提交记录变化基础分支,可以将当前分支和目标分支的共同祖先提交节点到当前分支的最新提交记录的所有内容移植到目标分支的最新提交记录后面,形成了目标分支的最新提交记录,合并了两个分支

  • 例子:将当前分支main移植到目标分支dev(git rebase dev),将会将main分支与dev分支的公共祖先提交节点(main:3)到当前分支的最新提交节点(main:5)的所有提交内容移动到dev分支的最新提交节点(dev:2)后面

    image-20240907173431534

    image-20240907173443464

1
2
-- <target>为目标分支名
git rebase <target>

合并和变基区别

方式 合并(merge) 变基(rebase)
优点 不会破坏原分支的提交记录,方便回溯和查看 不会新增额外的提交记录,形成线性历史,比较直观和干净
缺点 会产生额外的提交节点,分支图比较复杂 会改变提交历史,改变当前分支的branch out的节点,避免在共享分支使用

Git学习笔记
https://moonfordream.github.io/posts/Git学习笔记/
作者
Moon
发布于
2024年9月7日
许可协议