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

147 阅读6分钟

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

Git基本命令

项目初始化

  • mkdir demo

  • cd demo

  • git init

    参数:

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

配置

  • git config Git 配置,分成本地,用户,系统基本的配置

    不同级别的Git配置:

    • --global

      • git config --global user.name "yumo" 配置用户名
      • git config --global user.email "1304960237@qq.com" 配置用户邮箱
      • git config --global alias.cin "commit --amend --no-edit" 配置命令别名
    • --system 在 /etc/gitconfig

    • --local 在本地仓库的 .git/config

  • gir remote Git Remote 配置,分成 SSH 和 HTTP 两种协议实现,不同协议有不同的免密配置方式

    查看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
    • git remote set-url --add --push origin git@github.com:my_repo/git.git

    SSH Remote

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

    • 免密配置 : SSH可以通过公私钥的机制,将生成公钥存放在服务端,从而实现免密访问。

      • 目前的Key的类型有四种:dsa、rsa、ecdsa、ed25519
      • 默认使用的是rsa,由于一些安全问题,现在不推荐使用dsa和rsa,优先推荐使用ed25519
      • 新版本的windows代码可能会禁用dsa、rsa,从而导致本地无法拉取远程代码
      • 生成公私钥ssh-keygen -t ed25519 -C "1304960237@qq.com" 密钥默认存在~/.ssh/id_ed25519.pub

提交代码

  • git add 将代码从工作区提交到暂存区

    • git cat-file -p ce013625030ba8dba906f756967f9e9ca394464a 查看加密后的文件内容

  • git commit 将暂存区代码提交到 Git 存储

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

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

    • Tree : 存储文件的目录信息

    • Blob : 存储文件的内容

      串联三个信息

      1. 通过 Commit 寻找到 Tree 信息,每个 Commit 都会存储对应的 Tree ID
      2. 通过 Tree 存储的信息,获取到对应的目录树信息
      3. 从 tree 中获得 blob 的 ID,通过 Blob ID 获取对应的文件内容

    Refs

    • Refs 文件存储的内容:refs 的内容就是对应的 Commit ID,因此把 ref 当做指针,指向对应的 Commit 来表示当然 Ref 对应的版本

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

      Branch

      • git checkout -b <分支名> 创建一个新分支
      • 分支一般用于开发阶段,是可以不断添加 Commit 进行迭代的

      Tag

      • git tag <标签名> 生成一个tag
      • 标签一般表示的是一个稳定版本,指向的 Commit 一般不会变更
      • git tag -a <标签名> -m <附注信息> 添加一个附注标签
      • 附注标签:一种特殊的 Tag ,可以给 Tag 提供一些额外的信息

    追溯历史版本

    • git log

    修改历史版本

    • commit --amend

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

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

        1. 合并 commit
        2. 修改具体的 commit message
        3. 删除某个 commit
    • filter --branch

      • 该命令可以指定删除所有提交中的某个文件或者全局修改邮箱地址等操作
    • 悬空Object:修改Commit后发现新增了一个object,但是以前的没有被删除。这个以前的没有ref指向的object称为悬空object

      • git fsck --lost-found 检查悬空Commit

垃圾回收

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

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

  • 指定时间:git gc prune=now 指定的时修建多少之前的对象,默认是两周前

  • 完整流程:git reflog expire --expire=now --all

    git gc prune=now

远端同步

  • 拉取代码

    • git clone 拉取完整的仓库到本地目录,可以指定分支、深度
    • git pull 拉取远端某分支,并和本地代码进行合并,操作等同于 git fetch +git merge,也可以通过git pull --rebase 完成 git fetch + git rebase解决冲突
    • git fetch远端某些分支最新代码拉取到本地,不会执行merge操作,会修改refs/remote内的分支信息,若需要和本地代码合并则需要手动操作
  • 推送代码

    • git push 将本地代码同步至远端

    • 冲突问题:

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

常见问题

配置了Git配置,但依然无法拉取代码

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

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

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

研发流程

分支管理工作流-Github Flow

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

选择团队合作的方式:

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

代码合并

  • git merge <分支名> --ff-only FastForward 不会产生一个merge节点,合并和保持一个线性历史,如果 target 分支有了更新,则需要通过 rebase 操作更新 source branch 后才可以合入image-20220524150459863
  • git merge <分支名> --no-ff Three-Way Merge 三分合并,会产生一个新的merge节点image-20220524150620951

如何选择合适的工作流

没有最好,只有最合适,针对小团队合作,推荐使用 Github 工作流即可:

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

更多优质文章可以查看我的掘金主页,或者个人博客 www.yumoyumo.top