Git的使用 | 青训营笔记

85 阅读7分钟

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

为什么要学习Git:

  • 协同工作:业界绝大多数公司都是基于Git进行代码管理,因此Git是一个程序员必备技能。
  • 开源社区:目前绝大多数的开源项目都是基于Git维护的,参与这些项目的开发都需要使用Git。

学习目标:

  • 学习基本的Git命令,并了解原理,在遇到Git相关问题时,能自行排查并解决。
  • 了解研发流程中的基本概念和规范,学会正确的使用Git。

一、Git是什么

1.1 版本控制

  • 版本控制是什么?

一种记录一个或若干文件内容变化,以便将来查阅特定版本修订情况的系统。

  • 为什么需要版本控制?

为了更好的关注变更,了解到每个版本的改动是什么,方便的对改动的代码进行检查,预防事故发生;也能够随时切换到不同的版本,回滚误删改的问题代码。

image.png

1.2 Git的发展历史

作者: Linus Torvalds(是linux项目的作者,同时也是Git的作者)

开发原因: 怀疑Linux团队对BitKeeper(另一种分布式版本控制系统,专有软件)进行了逆向工程,BitKeeper不允许Linux团队继续无偿使用。因此决定自己开发一个分布式版本控制系统。

  • Github:全球最大的代码托管平台,大部分的开源项目都放在这个平台上。
  • Gitlab:全球最大的开源代码托管平台,项目的所有代码都是开源的,便于在自己的服务器上完成Gitlab的搭建。
  • Gerrit:由谷歌开发的一个代码托管平台,Android这个开源项目就托管在Gerrit之上。

二、Git的基本使用方式

image.png

2.1 Git目录介绍

  • 项目初始化:mkdir study、cd study、git init。

git init其他参数:

  • --init-branch 初始化的分支
  • --bare 创建一个裸仓库(纯Git目录,没有工作目录)
  • --template 可以通过模板来创建预先构建好的自定义git目录。

image.png

2.2 Git Config

不同级别的Git配置

  • --global
  • --system
  • --local

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

  • 用户名配置
  • Instead of 配置
    • git config --global url.git@github.com:.insteadOf github.com/
    • 可以做一些url的替换,可以把http协议换成ssh协议,或者ssh协议换成http协议。
  • Git命令别名配置(简化命令)
    • git config --global alias.cin "commit --amend --no-edit"

2.3 Remote

Git Remote

查看Remote

  • git remove -v

添加Remote

HTTP Remote

URL: github.com/git/git.git

一般不推荐使用HTTP Remote,因为不是特别安全。

SSH Remote

URL: git@github.com:git/git.git

免密配置:SSH可以通过公私钥的机制,将生成公钥存放在服务端,从而实现免密访问。目前的Key的类型有四种,分别是dsa、rsa、ecdsa、ed25519,默认使用的是rsa,由于一些安全问题,不推荐使用dsa和rsa,优先推荐使用ed25519。

ssh-keygen -t ed25519 -C "you_email@example.com",密钥默认存储在~/.ssh/id_ed25519.pub

2.4 Git Add和Git Commit

  • Git Add:将文件加入到暂存区。
  • Git Commit:将文件提交到目录里面。

2.5 Git Clone & Pull & Fetch

  • Clone:拉取完整的仓库到本地目录,可以指定分支,深度。
  • Fetch:将远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,如果需要和本地代码合并需要手动操作。
  • Pull:拉取远端某分支,并和本地代码进行合并,操作等同于git fetch + git merge,也可以通过git pull --rebase操作。可能存在冲突,需要解决。

2.6 Git push

push是将本地代码同步至远端的方式。

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

冲突问题:

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

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

三、Git研发流程

3.1 不同的工作流

image.png

3.2 集中式工作流

什么是集中式工作流:只依托于master分支进行研发活动。

工作方式:

  1. 获取远端master代码。
  2. 直接在master分支完成修改。
  3. 提交前拉取最新的master代码和本地代码进行合并(使用rebase),如果有冲突需要解决冲突。
  4. 提交本地代码到master。

Gerrit:是由谷歌开发的一款代码托管平台,主要特点是能够很好的进行代码评审。在aosp(android open source project)中使用很广,Gerrit的开发流程就是一种集中式工作流。

优点:

  1. 提供强制的代码评审机制,保证代码质量。
  2. 提供更丰富的权限功能,可以针对分支做细粒度的权限管控。
  3. 保证master的历史完整性。
  4. Aosp多仓的场景支持更好。

缺点:

  1. 开发人员角度的情况,更容易出现冲突。
  2. 对于多分支的支持较差,想要区分多个版本的线上代码时,更容易出现问题。
  3. 一般只有管理人员才能创建仓库,比较难以在项目之间形成代码复用,比如类似的fork操作不支持。

3.3 分支管理工作流

image.png

3.3.1 分支管理工作流 - GitFlow

  • 包含五种类型的分支
    • Mater:主干分支
    • Develop:开发分支
    • Feature:特性分支
    • Release:发布分支
    • Hotfix:热修复分支
  • 优点:
    • 如果能按照定义的标准严格执行,代码会很清晰,并且很难出现混乱。
  • 缺点:
    • 流程过于复杂,上线的节奏会比较慢。由于太复杂,研发容易不按照标准执行,从而导致代码出现混乱。

3.3.2 分支管理工作流 - GitHub Flow

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

选择团队合作的方式:

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

image.png

image.png

创建一个Pull Request

  1. 创建一个main主分支。
  2. 创建一个feature分支。
  3. 创建一个feature到main的pull request。

image.png

可以在pull request页面执行CI、CA、CR等操作,都检查通过后,执行合入。

image.png

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

image.png

3.3.3 分支管理工作流 - Gitlab Flow

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

原则:upstream first上游优先。 只有在上游分支采纳的代码才可以进入到下游分支,一般上游分支就是master。

3.4 代码合并

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

Three-Way Merge:三方合并,会产生一个新的merge节点。

3.5 如何选择合适的工作流

选择原则:没有最好的,只有最合适的。

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

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

大型团队合作,根据自己的需要指定不同的工作流,不需要局限在某种流程中。

四、总结

Git是工作中必备的技能,同时也是开源项目维护的工具。通过本次课程,明白了Git仓库管理的各种知识,对git的各种命令的使用也更加的熟练了。特别是工作流的知识是我之前没有接触到的。