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

153 阅读6分钟

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

image-20220524201121727

Git

分布式版本控制系统

Git的基本使用方式

Git基本命令

image-20220524203653154

Git目录介绍

项目初始化

mkdir 项目名
cd 项目名
git init
(默认分支是master分支)

其他参数

--initial-branch    初始化的分支,指定分支
--bare  创建一个裸仓库(纯Git目录,没有工作目录),不允许添加文件
--template  可以通过模板来创建预先构造好的自定义git目录

image-20220525143406806

tree命令安装

Windows下安装的git bash不支持tree命令,因此需要自己安装tree命令。

  1. 下载地址:jaist.dl.sourceforge.net/project/gnu…
  2. 下载后,复制压缩包内bin目录中的tree.exe
  3. 粘贴到git安装目录 Git\usr\bin 中

Git Config

每个级别的配置可能重复,但是低级别的配置会覆盖高级别的配置

常见Git配置

image-20220525143548762

Git Remote

查看Remote

git remote -v

添加Remote

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

同一个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

HTTP Remote

image-20220525144358072

不推荐,不安全,推荐用SSH

SSH Remote

image-20220525144449582

Git Add

touch readme.md (直接在文件夹创建也行)
vim readme.md
git status
​
git add .
git status

Objects

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

  • Blob

    • 存储文件的内容
  • Tree

    • 存储文件的目录信息
  • Commit

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

image-20220525220218972

Refs

Refs文件存储的内容

refs的内容就是对应的Commit ID

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

不同种类的ref

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

Branch

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

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

Tag

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

通过 git tag 命令生成 tag.

Annotation Tag

附注标签

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

如何创建

git tag -a

查看该tag object的内容

git cat-file -p 

追溯历史版本

image-20220525222421436

修改历史版本

  1. commit- amend
  • 通过这个命令可以修改最近的一次 commit 信息,修改之后 commit id 会变
  1. rebase
  • 通过 git rebase -i HEAD~3 可以实现对最近三个 commit 的修改:

    1. 合并 commit
    2. 修改具体的 commit message
    3. 删除某个 commit
  1. filter - branch
  • 该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作

Object

image-20220525223503608

Git GC

GC

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

Reflog

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

指定时间

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

Git Clone & Pull & Fetch

Clone

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

Fetch

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

Pull

  • 拉取远端某分支,并和本地代码进行合并,操作等同于 git fetch + git merge,也可以通过 git pull --rebase 完成 git fetch + git rebase 操作。
  • 可能存在冲突,需要解决冲突。

Git Push

Push是将本地代码同步之远端的方式。

常用命令

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

冲突问题

  1. 如果本地的 commit 记录和远端的 commit 历史不一致,则会产生冲突,比如 git commit --amend or git rebase 都有可能导致这个问题。
  2. 如果该分支就自己一个人使用,或者团队内确认过可以修改历史则可以通过 git push origin master-f 来完成强制推送,一般不推荐主干分支进行该操作,正常都应该解决冲突后再进行推送。

推送规则限制

  • 可以通过保护分支,来配置一些保护规则,防止误操作,或者一些不合规的操作出现,导致代码丢失。

Git研发流程

不同的工作流

image-20220525141605970

集中式工作流

只依托于master分支进行研发活动

分支管理工作流

image-20220525141722206

Gitflow

包含五种类型的分支

  • Master:主干分支
  • Develop:开发分支
  • Feature:特性分支
  • Release:发布分支
  • Hotfix:热修复分支

代码清晰不混乱,但流程过于复杂,上线节奏慢。

Github Flow

只有一个主干分支,基于Pull Request 往主干分支中提交代码。

选择团队合作的方式

  1. owner 创建好仓库后,其他用户通过 Fork 的方式来创建自己的仓库,并在 fork 的仓库上进行开发
  2. owner 创建好仓库后,统一给团队内成员分配权限,直接在同一个仓库内进行开发

可以通过进行一些保护分支设置,来限制合入的策略,以及限制直接的push操作。

Gitlab Flow

Gitlab 推荐的工作流是在 GitFlow 和 Github Flow 上做出优化, 既保持了单一主分支的简便,又可以适应不同的开发环境。

原则:upstream first 上游优先

只有在上游分支采纳的代码才可以进入到下游分支, 一般上游分支就是 master.

代码合并

Fast-Forward

不会产生一个 merge 节点,合并后保持一个线性历史,如果 target 分支有了更新,则需要通过 rebase 操作更新 source branch 后才可以合入。

image-20220526140557192

git merge test --ff-only

Three-Way Merge

三方合并,会产生一个新的merge节点

image-20220526140645193

git merge test --no-ff

如何选择合适的工作流

针对小型团队合作,推荐使用Github工作流即可

  1. 尽量保证少量多次,最好不要一次性提交上千行代码
  1. 提交 Pull Request 后最少需要保证有 CR 后再合入
  1. 主干分支尽量保持整洁,使用 fast-forward 合入方式,合入前进行 rebase

实操记录

项目初始化

mkdir demo
cd demo
ls
git init
​
tree .git
cat .git/HEAD

image-20220525142959836

image-20220525143127235

image-20220525143200324

git remote -h

image-20220525144119906

SSH Remote

image-20220525145310082

image-20220525151152991

git以前下的,可能当时没配置用户名和邮箱,没配置前打不开

image-20220525151449283

image-20220525205149054

image-20220525213048431

Vim基本操作

  1. 进入vim正常模式后,按i进入插入模式,输入内容
  2. 输入完成后,按Esc退出插入模式
  3. 输入完成后,按shift+:进入进入命令模式
  4. 输入w保存
  5. 再次按shift+:进入命令模式,输入q退出vim编辑器

image-20220525215056410

image-20220525215840118

git add后文件在暂存区,然后commit到git目录里

image-20220525215652513

image-20220525215746415

Refs

创建新分支

image-20220525220500311

image-20220525220548402

创建tag

image-20220525221104302

创建附注标签

image-20220525221417934

image-20220525221434134

查看该tag object的内容

image-20220525222050201

提交新的ommit

image-20220525222718172

修改历史版本

image-20220525223418543

查找悬空的commit

image-20220525223557621

Git gc

image-20220525224435252


Create a new repository

image-20220525225457497

克隆

image-20220525230207556

Push

image-20220525231352273

image-20220525231545683

创建feature分支

image-20220525231921456

image-20220525231936607

Pull request

image-20220525232228628

image-20220525232246178

拉到本地

git checkout main
git pull origin main