Git再学习

基本印象

基本印象是最为重要的,因为我层四次学习git,但是最后都忘了.所以在一段时间后我能够记住多少知识才是我们的首要关注点.

基本印象就是保证我们记忆住最基本的只是,从而更快地重学习.

参考1:https://javabetter.cn/git/git-qiyuan.html

参考2:https://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html

参考3:https://gitee.com/progit/index.html

参考3是git pro2

参考4:https://pdai.tech/md/devops/tool/tool-git.html

版本控制的几种方式

分布式版本控制和集中式版本控制

集中版本控制

相当于是主从复制,我们只有一个主服务器,要想要获取就只能从这一个服务器中获取,其他的都是slave不作数

优点就是没有冲突,缺点是必须联网保证和主服务器的网络通畅

分布式版本控制

在自己的电脑上搭建了版本仓库,这样就不需要联网了,也可以将自己的仓库推送到远程服务器上,这样实际上就可以让别人共享项目

优点就自己电脑本地就是一个仓库,当我们需要发送到远程服务器的时候才需要联网推送整个版本仓库

Git就是分布式版本控制系统

Git的基本模式

因为git就是分布式版本控制系统,所以git系统就有

  1. 远程仓库概念
  2. 本地仓库概念

最常用的就是本地仓库的使用了,而从本地仓库推送到远程仓库以及拉取远程仓库内容都比较简单

仓库的管理概念

向仓库中添加不同的版本,需要哪些步骤?

向仓库查询,获取不同的版本,需要怎么做?

解释

git提供了几种级别

  1. 当前工作版本桌面 Workspace
  2. 要存仓的版本袋子 Index/Stage
  3. 版本存放仓库 Repository
  4. 远程仓库 Remote

可以理解,我们操作修改workspace桌面上的东西,

改好以后装好放在袋子里,

等到所有东西都装在袋子里以后封袋存档

本地级别的基本使用

1 创建本地仓库

以目录为单位,在一个目录中创建仓库,这样Git就是将这个目录中的所有内容作为我们的软件的内容进行管理

实际的代码就是

1
git init

然后当前目录会出现一个.git目录,里面保留了整个仓库的信息

还有两个命令也可以得到一个本地仓库

1
2
3
4
5
# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]

# 下载一个项目和它的整个代码历史
$ git clone [url]

2 编辑配置文件

git的配置文件叫做.gitconfig

配置文件分为两类

  1. 全局(Git)配置文件,位于用户主目录.gitconfig文件
  2. 项目(当前仓库)配置文件,位于项目目录下.gitconfig文件

配置文件主要就是一些用户配置,文件配置之类的

1
2
3
4
5
6
7
8
9
# 显示当前的Git配置
$ git config --list

# 编辑Git配置文件
$ git config -e [--global] #也就是edit的缩写

# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"

3 与暂存区的交互

记住,所以仅对本地目录,桌面的操作,都不需要用到git命令

所以只要是git命令操作一定影响stage或者repository或者remote

我们写好一个文件可以将文件保存到stage中

1
2
3
4
5
6
# 添加文件到暂存区
git add [file1] [file2] ...
# 添加目录到暂存区
git add [dir]
# 添加当前所有到暂存区
git add . # 或者git add ./* ,git对于linux语法很支持

如果暂存区有一个相同文件名的存在,那么git会进行询问

如果你并不是向整个覆盖,那么你可以使用更小粒度的更新,这样git会在每一处修改处问你是否要覆盖?

1
2
3
# # 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
git add -p [同名文件]

也可以删除袋子中的文件

1
2
3
4
5
6
# 删除桌面上的文件,!同时!删除袋子中的
git rm [file1] [file2]...
# 也可以只删除袋子中的,这样桌面上的还保留,可以通过git add继续装袋
git rm --cache [file]...
# 当然可以直接把工作目录的文件删除了
rm file # linux指令

元信息修改

例如文件改名

1
2
# 改名!同时!提交到缓存区
git mv [old_filename] [new_filename]

如果我们直接在工作区给文件改名,那么git将不认得这个文件,会显示成untracked的新文件

4 与本地仓库的交互

提交

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 将整个袋子存档到仓库,必须有版本信息哦
git commit -m'版本信息'
# 将某些文件单独存档到仓库
git commit [file1][file2] -m'版本信息'
# 直接工作区提交到仓库
git commit -a # 也就是-all的意思
# 提交的时候显示版本差异
git commit -v #也就是带上-v就可以

# 也许你提交失误了,你可以覆盖上次的提交
git commit --amend -m'message'

# 也许你不想完全覆盖上次提交,只想修改一些文件
git commit --amend [file1][file2]...

本质理解

如果我们真的想理解这些命令的效果,我们必须知道git的工作原理

基本理解

本质1 Git以文件为版本单位

其他的版本控制系统,是发现与上一次提交文件的变化,然后记录文件变化,我们想要获取某次的文件版本就需要从初始文件,然后读取修改才能获得

Git是计算此次提交文件整体的hash值,如果不同就保存为一个新的文件版本,这个文件保存了完整的文件内容,如果和之前的文件版本相同,git就会创建一个指向该文件的链接占位

所以,Git的粒度更大,保存最小单位为是一个文件,而其他的控制系统最小是文件中的一次修改

所以我们要以文件作为版本控制的基本视野

img

如上图,我们的项目里面有A,B,C三个文件

如果新的提交和之前的提交没有差异,就会指向之前的文件版本.

如果有差异就会直接保存文件作为一个新的版本

本质2 git发现差异的原理

git实际上会将文件的全部内容进行内容校验和运算,最后得到SHA-1 算法计算数据的校验和

git通过这个值,来比较文件是否相同.

Git 的工作完全依赖于这类指纹字串,所以你会经常看到这样的哈希值。实际上,所有保存在 Git 数据库中的东西都是用此哈希值来作索引的,而不是靠文件名。

git diff 检查工作区和暂存区中文件的不同

本质3 文件的四种状态

在git中,文件只有三种状态

  1. 已提交 committed
  2. 已修改 modified
  3. 已暂存 staged
  4. 未追踪 untracked

我们需要理解追踪的意思

文件追踪

我们知道git中的版本控制是以文件为单位的

所以git中最常见的操作就是修改文件中的内容,这样git就会保存新版本的文件的快照

所以我们更新的文件,也就是git知道的文件,有上一个版本的文件就被叫做 tracked文件

如果我们添加一个新的文件,git完全不知道,所以就显示叫做 untracked文件

基本的工作流程如下:

  1. 在工作目录修改了某些文件
  2. 将文件保存到缓存区
  3. 提交更新,将保存在暂存区的文件快照保存在Git目录中

使用基础

使用git之前我们需要知道一些基础东西

一个是配置,一个是帮助

三个地方:

  1. /etc/gitconfig 全局配置 优先级最低
  2. ~/.gitconfig 当前用户配置 优先级中等
  3. .git/config 当前项目配置 优先级最高

包括下面的配置

配置用户信息

我们在提交的时候,git需要记录这次提交的用户信息,所以我们需要配置

通过git config --global user.name 你的用户名进行配置

以及用户的emailgit config --global user.email 你的邮箱

获取帮助

另一个基础是获取git的帮助

没人能永远记住所有的git指令,当我们有疑问的时候,调用git帮助是最快的解决方法

  1. git help <verb>
  2. git <verb> –help
  3. man git -<verb>

这三种方式都可以查看一个命令的帮助

新手开始

首先我们创建一个git 项目,git会将这个目录作为工作区,可以追踪工作区中的所有文件(默认排除.git文件夹因为这个文件夹就是git的仓库)

1
2
3
4
5
6
# 我们可以自己初始化一个项目
git init
# 或者我们可以下载一个git项目
git clone [url]
-- 这里的url可以是git协议,形如git://...,也可以是http://或者https://,又或者user@server://这个是SSH的传输协议
-- 不同的传输协议有不同的好处

查看文件状态

我们知道文件有四种状态,我们可以查看工作区中文件的状态

可能有几种情况

  1. untracked 有一些未追踪的新文件
  2. deleted 删除了一些文件
  3. modified 修改了一些文件的内容

跟踪新的文件

通过git add [file]来将文件加入暂存区

高级使用

当我们真的想使用git的时候我们就需要了解这部分的知识,因为了解了才能够方便的进行版本的管理

分支管理

同一个版本做出不同的修改,那么就会衍生出不同的版本分支,这些分支都来自同一个版本,但是却都是不同的版本

这里的分支可以来源于其他分支,也可以独成一派

合并分支,相当于就是将下一个版本指向另外的分支版本,例如将开发分支合并到master分支,这样相当于是发布为正式版

img

img

查看分支

1
2
3
4
5
6
7
8
# 查看本地分支
git branch

# 查看远程分支
git branch -r #也就是remote的缩写

# 查看所有分支(本地以及远程)
git branch -a

新建分支

1
2
3
4
5
6
7
8
9
10
11
# 新建一个分支,来自当前分支的最新提交版本,但是不切换分支
git branch [branch-name]

# 新建一个分支来自当前版本,然后切换到该分支
git checkout -b [new-branch] # 实际上切换分支的命令就是git checkout [branch-name]

# 新建分支,然后指向某个版本
git branch [new-branch][commit]

# 新建分支,并作为远程分支的代表
git branch --track [new_branch][remote_branch]

切换,合并分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 切换分支并且,更新工作区
git checkout [branch] #所以注意,保存你的工作区,否则就要丢失了

# 切换到上一个分支
git checkout - #记得linux中cd -就是回到上一次的目录

# 建立追踪关系,在已有分支和远程分支之间
git branch --set-upstream [branch] [remote_branch]

# 合并指定分支到当前分支
git merge [branch]

# 选择一个commit 合并进入当前分支,
git cherry-pick [commit]

删除分支

1
2
3
4
5
6
7
# 删除分支
git branch -d [branch-name]

#删除远程分支
git push origin --delete [branch-name]
git branch -dr [remote-branch]

标签管理

标签是什么?实际上就是给我们版本添加一个快捷方式,添加了描述以及快速选择。

**标签实际上就是commit的别名,**在命令上都可以代替commit出现

显示标签

1
git tag #会显示当前项目中的所有标签

添加标签

1
2
3
4
5
6
# 给当前版本添加一个标签
git tag [tag_name]

# 给指定版本加上标签
git tag [tag_name] [commit]

删除标签

1
2
3
4
5
6
# 删除指定标签
git tag -d [tag_name]

# 删除远程标签
git push origin :refs/tags/[tag_name]
# 实际上用到的是底层命令

查看标签信息

实际上就是查看标签所在的版本的信息

1
2
# 查看信息
git show [tag_name] # 也就相当于是标签是commit的别名

提交到远程仓库

1
2
3
4
5
# 实际上就是push命令中,使用标签代替commit的位置
git push [remote] [tag]

# 提交所有的tag
git push [remote] --tags

远程操作(remote操作)

我们操作远程仓库

显示远程仓库

1
2
3
4
5
6
# 显示所有的远程仓库
git remote -v #意思就是-v visiable可视的意思

# 显示某个具体的远程仓库的信息
git remote show [remote]

添加远程仓库

1
2
# 给项目添加一个远程仓库
git remote add [shortname] [url]

从远程仓库获取内容

1
2
3
4
5
6
# 下载所有的变动
git fetch [remote]

# 下载最新版本并合并到本地分支
git pull [remote][branch]

上传到远程

1
2
3
4
5
6
7
8
# 上传本地指定分支
git push [remote] [branch]

# 上传当前当前分支,强制覆盖
git push [remote] --force

# 推送所有分支到远程,
git push [remote] --all

本地操作

获取到工作区 checkout

1
2
3
4
5
6
7
8
# 从stage读取到工作区
git checkout [file] # 实际上的意思就是切换到版本

# 从commit中读取到工作区,以及暂存区
git checkout [commit/tag] [file]

# 从stage中读取所有到工作区
git checkout .

所以可以知道,默认都是从暂存区回退到工作区的,想要从仓库回退,必须指明仓库的版本

获取到暂存区 reset

1
2
3
4
5
6
7
# 从当前commit中获取到暂存区,但是工作区没影响
git reset [file] # 从当前commit中获取到暂存区
git reset [commit]

# 包括工作区一起重置(容易丢失工作区修改)
git reset --hard
git reset --hard [commit/tag]

改变commit

1
2
3
4
5
6
7
8
9
10
# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]

# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]

# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop

发布版本

1
2
# 将项目打包成一个可发布的压缩包
git archive

查看信息

非常常用的命令类型

git status 系列

用来显示当前工作区,暂存区,仓库中的状态,差异之类的

1
2
# 显示当前工作区,暂存区,仓库版本的状态
git status

git log 系列

显示当先版本的日志,包括commit编号,提交时间,作者,分支,标签之类的信息

1
2
3
4
5
6
7
8
# 显示当前版本日志
git log

# 显示commit日志和详情(内容有哪些修改)
git log --stat

# 搜索提交例如,根据关键词
git log -S [search_keys]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 显示有变更的文件
$ git status

# 显示当前分支的版本历史
$ git log

# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat

# 搜索提交历史,根据关键词
$ git log -S [keyword]

# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s

# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature

# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]

# 显示指定文件相关的每一次diff
$ git log -p [file]

# 显示过去5次提交
$ git log -5 --pretty --oneline

# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn

# 显示指定文件是什么人在什么时间修改过
$ git blame [file]

# 显示暂存区和工作区的差异
$ git diff

# 显示暂存区和上一个commit的差异
$ git diff --cached [file]

# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD

# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]

# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"

# 显示某次提交的元数据和内容变化
$ git show [commit]

# 显示某次提交发生变化的文件
$ git show --name-only [commit]

# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]

# 显示当前分支的最近几次提交
$ git reflog

其他概念

例如远程仓库

一些配置

  1. git将中文显示为八进制字符编码问题

将git配置文件 core.quotepath项设置为falsequotepath表示引用路径,加上--global表示全局配置

git bash终端输入命令:

1
git config --global core.quotepath false
  1. git自动转换换行符的问题
1
2
3
4
5
6
// 提交时转换为LF,检出时转换为CRLF 
git config --global core.autocrlf true
// 提交时转换为LF,检出时不转换
git config --global core.autocrlf input
// 提交检出均不转换
git config --global core.autocrlf false
1
2
3
4
5
6
// 拒绝提交包含混合换行符的文件 
git config --global core.safecrlf true
// 允许提交包含混合换行符的文件
git config --global core.safecrlf false
// 提交包含混合换行符的文件时给出警告
git config --global core.safecrlf warn

Git再学习
https://wainyz.online/wainyz/2024/03/30/Git再学习/
作者
wainyz
发布于
2024年3月30日
许可协议