Git 版本控制课程笔记|青训营笔记

118 阅读5分钟

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

Git 版本控制

1.1 版本控制类型

本地版本控制 RCS

集中式版本控制 SVN

  • 提供一个远端服务器来维护代码版本,用户所有提交都提交到该服务器中
  • 增量保存每次提交的 Diff,如果提交的增量中和远端现存的文件存在冲突,则需要本地提前解决冲突
  • 本地不保存代码版本,所有提交都只能连上服务器后才能提交,如果服务端故障容易导致历史版本丢失

分布式版本控制 Git

  • 每个库都存有完整的提交历史,可以直接在本地进行代码提交
  • 每次提交记录的都是完整的文件快照,而不是记录增量
  • 通过 Push 等操作来完成和远端代码的同步

    • Push 其实只是同步,提交是在本地完成
  • 对大文件的支持不是特别好(可用 git-lfs 工具弥补)

1.2 Git 发展历史

作者:Linus Torvalds

  • GitHub

    全球最大的代码托管平台

  • GitLab

    全球最大的开源代码托管平台,项目的所有代码都开源,可以在自己的服务器上搭建 GitLab

  • Gerrit

    谷歌开发的平台,Android 项目就托管在 Gerrit 上

Git 基本命令

  • 配置

    • git config
    • git remote
  • 提交代码

    • git add
    • git commit
  • 远端同步

    • 拉取代码

      • clone
      • pull
      • fetch
    • 推送代码

      • push

常见问题

  1. 为什么我配置了 Git 配置,但依然没有办法拉取代码

    没有密钥,没有权限

  1. 为什么我 fetch 了远端分支,但是我看本地当前的分支历史还是没有变化

git init 命令

其他参数:

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

目录结构

HEAD 文件内容: ref: refs/heads/master 表示当前指向的分支是 master

git config

不同级别的 git 配置

  • global
  • system
  • local

低级别的配置会覆盖高级别的配置

常见 git 配置

  • 用户名配置

    • user.name
    • user.email
  • instead of 配置
  • git 命令别名配置

git remote

HTTP remote

免密配置

  • 内存 git config --global credential.helper 'cache --timeout=3600'
  • 硬盘 git config --global credential.helper "store --file /path/to/credential-file"

    • 不指定目录的情况默认是 ~/.git-credentials
  • 具体格式 {scheme}://${user}:${password}@github.com

一般不推荐用 HTTP 方式访问 git,因为不安全,一般还是会使用 SSH

SSH remote

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

ssh-keygen -t ed25519 -C "``saicaca@github.com``"

生成好后查看 pub 文件内容 cat id_ed25519.pub,将其添加到 GitHub 中

Git 命令

touch

命令含义:用于修改文件或者目录的时间属性,包括存取时间和更改时间。若文件不存在,系统会建立一个新的空白文件。

touch readme.md

add

令 Git 包含某文件

add readme.md

完成上面的操作后 objects 文件夹里会多出来东西(上面的 e6 和 9de…… 连起来就是文件ID)

此时文件是加密的,但通过 cat-file 命令可以看到内容

commit 命令

git commit -m "add readme"

commit 后会多出一些文件,包括目录树、commit 记录等

Objects

commit / tree / blob 统称为 Object,除此之外还有个 tag

  • Blob

    存储文件的内容

  • Tree

    存储文件的目录信息

  • Commit

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

refs

refs 的内容就是对应的 Commit ID,可以把 ref 当做指针,指向对应的 Commit 来表示当前 ref 对应的版本

在 refs 下面会多出 test 文件,文件的内容就是 commit 的 ID

两种 ref

  • refs/heads 表示的是分支(branch)

    • Branch 是出于开发过程中的,可以不断添加 commit
    • git checkout -b test
  • refs/tags 表示的是标签

    • tags 表示稳定的版本,不会再进行变更
    • git tag v0.0.1

Annotation Tag

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

git tag -a v0.0.2 -m "add feature xxx"

这种 tag 文件里的内容不是指向 commit 而是指向一个 object

这个 b487xxx 才是真正指向的 commit object

commit —amend

git commit --amend

在弹出的编辑器中修改保存

注意老的 commit object 并不会被删除,产生悬空的 Object,没有任何 ref 指向,可用 git fsck --lost-found 查找悬空的 Object

Git Clone & Pull & Fetch

如果对代码情况很清楚可以用 Pull,如果不是很清楚会不会有冲突就用 Fetch,在本地做一次 rebase 解决冲突

分支管理工作流

  • Git Flow

    • 分支类型丰富,规范严格
    • 五种类型

      • Master
      • Develop
      • Feature
      • Release
      • Hotfix
    • 如果按规范执行代码会很清晰,但流程过于复杂,上线过程会比较慢
  • GitHub Flow

    • 只有主干分支和开发分支,规则简单
  • GitLab Flow

    • 在主干分支和开发分支之上构建环境分支,版本分支,满足不同发布 or 环境的需要

这里的工作流只是推荐,并不强制

代码合并

  • Fast-Forward

    • git merge test --ff-only
  • Three-Way Merge

    • git merge test --no-ff

在没有指定合并方式时软件会自动选择

如何选择合适的工作流

  • 小型团队合作推荐使用 GitHub 工作流
  • 大型团队合作根据自己的需要选择不同的工作流

\