Git指南

Git指南

零、目的

  1. 掌握各类场景下如何更好使用Git。
  2. 减少因为代码提交问题带来的生产环境问题。 /images/git-zoo.jpg

一、了解[[Git]]

  1. 什么是Git?     1. 一款分布式版本管理系统     2. 优点:分布式、性能、版本的文件完整性         1. 分布式,可以让你在本地提交代码(对于SVN而言没有网络就无法提交代码,在家也能愉快地写代码);         2. 性能,对于我们的一般项目而言,你感受不到合并时性能的差别(与SVN比较);         3. 版本的文件完整性:git背后设计理念是快照思想。
  2. Git概念     1. 仓库(repository)         1. 用于代码版本管理         2. 一个git仓库管理了三棵“树”,分别是             1. Working Directory(工作目录)             2. Index(暂存区)             3. HEAD(本地仓库)         3. 大多数时候你通过编辑器只能对工作目录操作,操作其他两个“树”(区域)必须使用git命令才可以。     2. 分支(branch)         1. 用于并行独立开发,更方便管理不同开发任务的进度
  3. Git常用命令     1. git add     2. git commit     3. git push     4. git pull     5. git branch     6. git switch     7. git restore

二、最常见的一种使用场景

陈主管说他已经开发好了整个架构,需要我去把几个功能实现一下,并提交到dev分支让他方便Review。

  • 基本流程     1. 先从远程服务器把代码拉到本地:git clone http://197.68.6.70/demo-project     2. 此时你拥有的是主干master分支的代码,我们需要切换到dev分支进行开发:         1. git fetch --all         2. git switch --track origin/dev     3. 在工作目录写代码     4. 提交变更的文件到暂存区git add <somefile>     5. 提交文件到本地仓库git commit -m "xxx"     6. 把我的代码推送到远程仓库(同步):git push

三、最佳实践——Git里的后悔药

  1. 我提交到暂存区的代码搞错了:git restore -S <files or dir> (在使用IDEA时,这个场景不太会出现,因为IDEA往往是把add 和 commit的操作会合并成一个处理)
  2. 我提交到本地仓库的代码搞错了:     1. 最近的一个commit:git reset -mixed HEAD~1     2. 历史中的一个commit:         1. 使用 git reset --mixed <commit_id>,然后重新提交正确的代码( ❗从最新commit到指定commit的代码都需要重新提交)         2. 使用 git revert <commit_id> ,这个操作近似于自己重新提交代码
  3. 我提交到远程仓库的代码搞错了:     1. 只有一个建议:请写出正确的代码,重新提交!所以,请在每次push之前谨慎!

四、最佳实践——与他人同步

  1. 我想把别人在dev分支上开发的代码同步下来看看:git pull --rebase 或者 git pull (前者会让你的commit log更加清爽一些,没有一些额外的merge commit log)
  2. 如果你开发的分支和多人一同开发,建议每天进行一次 git pull --rebasegit push

五、最佳实践——我的改动比较大

  1. 建议自己拉一个分支进行开发 git switch -c <new_branch_name>
  2. 开发结束后,先把主开发分支合并到你的分支:git merge dev
  3. 没问题后再把你的分支合并到主开发分支:git switch devgit merge <new_branch_name>

六、其他

  1. ⭐准备上线前     1. 和上一个版本代码对比(git diff release master),确认release分支是正确的需要上线的代码     2. 使用Jenkins对release分支进行自动打包与部署,在工作空间获取上线代码包(禁止本地打包)
  2. 上线完成后     1. 在gitlab上提交release合并至master分支的merge request,由技术经理确认合并;     2. 对最新的master分支进行tag,方便反查源码;

七、几个原则

强制

  1. 禁止git push -f
  2. 禁止git push master

建议

  1. 建议分支命名:master、release、dev、dev_xx     1. master分支为线上正在运行的代码;不允许手动提交;只能通过页面的merge request进行代码合并;每次上完线后把分支(release)代码合并到master     2. release为测试环境对应的代码,jenkins均从该分支进行自动构建与部署     3. dev,以及其他分支为开发分支,较为自由。
  2. 减少对git checkout的使用,已经拆分为 git switchgit restore
  3. 不要把二进制文件放到git仓库中进行版本管理

八、实现方式之数据结构

在Git当中,


// 一个文件就是字节数组

type blob = array<byte>

  

// 一个目录包含文件或者其他目录

type tree = map<string, tree | blob>

  

// 一个commit包含它的父节点,原始信息,顶级目录(快)

type commit = struct {

    parents: array<commit>

    author: string

    message: string

    snapshot: tree

}

  

// 文件、目录、commit最终都以object类型进行存储

type object = blob | tree | commit

这样看起来,每一次修改文件并提交git仓库后,都会新建一个blob对象,并作为新的快照内部的文件使用,因此,git仓库存储空间可能会越来越大,特别是对于那些二进制文件(非文本文件,难以压缩)。这时候可以通过git gc进行git仓库压缩,这里面的算法大家可以自己去探索一下。根据我的经验,能大概缩小到原本的1/3~1/2。

九、参考

Cheatsheet

  1. 一个可视化的Git Cheatsheet
  2. Gitlab官方Cheatsheet
  3. https://github.com/k88hudson/git-flight-rules
  4. Git - 高级合并 (git-scm.com)

原理学习

  1. 为什么你应该使用 Git 进行版本控制 - 面向信仰编程 (draveness.me)
  2. Pro Git 中文版(第二版)
  3. Version Control (Git) · the missing semester of your cs education (mit.edu)

Some code


git clone

git branch --track dev origin/dev

git checkout dev

git add & git commit

git push

Merge Request (MR)

  

git restore -S <files or dir>

git reset -mixed HEAD~1

git reset --mixed <commit_id>

git revert <commit_id>

  

git pull --rebase

git pull

  

git checkout -b <branch_name>

...

git merge dev

  

git stash

git stash pop

最后修改于 2022-01-03