Git的正确使用姿势与最佳实践 | 青训营笔记

151 阅读5分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第1篇笔记

项目初始化

mkdir study

cd study

git init

其他参数

--initial-branch 初始化的分支

--bare 创建一个裸仓库(纯Git目录,没有工作目录)

--template 可以通过模板来创建预先构建好的自定义git目录

使用tree .git 查看当前目录结构

tree .git在git bash中无法使用

参考www.cnblogs.com/snowdreams1…

常见Git配置

用户名配置

git config --global user.name "guochuang"

git config --global user.email 248704991@qq.com

Instead of

git config --global url.git@github.com:.insteadOf github.com/

Git命令别名设置

git config --global alias.cin "commint --amend --no-edit"

Git Remote

查看Remote

git remote -v

添加Remote

git remote add origin_ssh git@github.com:git/git.git

git remote add origin_http github.com/git/git.git

image-20220524223545305.png

同一个Origin设置不同的Push和Fetch URL

git remote add origin git@github.com:git/git

git remote set-url --add --push origin git@github.com:MY_REPOSITY/git

查看:git remote -v

Git Add

touch readme.md

git commit -m "add readme"

Objects

commit/tree/blob在git里统称为Object,除此之外还有个tag的object

Blob

存储文件的内容

Tree

存储文件的目录信息

Commit

存储提交信息,一个Commit可以对应唯一版本的代码

如何把这三个信息串联在一起的?

1、通过Commit寻找到Tree信息,每个Commit都会存储对应的Tree ID

git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904

2、通过Tree存储的信息,获取对应的目录树信息

git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904

3、从tree中获得blob的ID,通过Blob ID获取对应的文件内容

git cat-file -p 4b825dc642cb6eb9a060e54bf8d69288fbee4904

Refs

cat .git/refs/heads/master

cat .git/refs/heads/testimage-20220525134633916.pngrefs的内容就是对应的Commit ID

因此把ref当做指针,指向对应的Commit来表示当前Ref对应的版本

refs/heads前缀表示的是分支,除此之外还有其他种类的ref,比如refs/tags前缀表示的是标签

Branch

git checkout -b 可以创建一个新分支

分支一般用于开发,是可以不断添加Commit进行迭代

Tag

标签一般表示的是一个稳定版本,指向的Commit一般不会变更

通过git tag命令生成tag

Annotation Tag

附注标签

一种特殊的Tag,可以给Tag提供一些额外的信息

创建附注标签

通过git tag -a 命令来完成附注标签的创建

image-20220525135359320.png

查看tag object 的内容

image-20220525135422009.png

追溯历史版本

获取当前版本代码

通过Ref指向的Commit可以获取唯一的代码版本

获取历史版本代码

Commit里面会存有parent commit字段,通过commit的串联获取历史版本代码

1、修改文件,并提交,创建新的commit

image-20220525135939223.png

2、查看最新的commit,新增了parent信息

image-20220525135953856.png

1、新增 tree object 3a

2、新增 blob object 55

3、新增 commit object 64

image-20220525140329645.png

test ref 指向新的commit

image-20220525140148916.png

image-20220525140022663.png

修改历史版本

1.commit - amend

通过这个命令可以修改最近一次的commit信息,修改之后commit id 会变

2.rebase

通过git rebase -i HEAD ~3可以实现对最近三个commit的修改

1、合并commit

2、修改具体的commit message

3、删除某个commit

3. filter -branch

该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作

通过git commit — -amend 命令尝试修改commit message

Obejects

新增的Object

修改Commit后我们可以发现git object 又出现了变化

新增commit object 7f

但是之前的commit object 63并没有被删除

image-20220525165513391.png

悬空的Object

没有ref指向的object

image-20220525165525301.png

Git GC

GC

通过git gc 命令,可以删除一些不需要的object,以及会对object进行一些打包压缩来减少仓库的体积

Reflog

reflog是用于记录操作日志,防止误删除操作后数据丢失,通过reflog来找到丢失的数据,手动将日志设置为过期

指定时间

git gc prune=now 指定的是修剪多久之前的对象,默认是两周前

image-20220525165830486.png

完整的Git视图

image-20220525165855462.png

image-20220525165908423.png

Git Clone & Pull & Fetch

Clone

拉取完整的仓库到本地目录。可以指定分支,深度

Fetch

将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作

Pull

拉取远端某分支,并和本地代码进行合并,操作等同于git fetch + git merge,也可以通过git pull --rebase完成git fetch + git rebase操作

可能存在冲突,需要解决冲突

Git Push

常用命令

一般使用git push origin master 命令即可完成

冲突问题

1、如果本地的commit记录和远端的commit历史不一致,则会产生冲突,比如git commit --amend or git rebase 都又可能导致这个问题

2、如果该分支就自己一个人使用,或者团队内确认过可以修改历史则可以通过git push origin master -f来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送

常见问题

1、为什么配置Git,但是依然没有办法拉取代码?

免密认证没有配

Instead Of配置没有配,配的SSH的免密配置,但是使用的是HTTP协议访问

2、Fetch了远端分支,但是本地当前的分支历史没有变化

Fetch会把代码拉取到本地的远端分支,但是并不会合并到当前分支,所以当前分支历史没有改变