Git进阶技巧

1 基于GPT的自动代码审核

项目地址 3.1k⭐

Star History Chart

目前支持多种部署方式,官方推荐为使用 Github Action

  1. 添加OPENAI_API_KEY到你的 github action 密钥(Setting - Secrets and variables - Actions - New repository secret,输入GPT相关的API密钥)
  2. 创建.github/workflows/cr.yml添加以下内容(Actions - New workflow - set up a workflow yourself - yml文件重命名,撰写具体的配置信息):
# cr.yml
name: Code Review

permissions:
  contents: read
  pull-requests: write

on:
  pull_request:
    types: [opened, reopened]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: anc95/ChatGPT-CodeReview@main
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
          # optional
          LANGUAGE: Chinese
          # OPENAI_API_ENDPOINT: https://api.chatanywhere.com.cn/v1 # 支持第三方API 
          # PROMPT:

2 Git中的垃圾回收机制

Git中的垃圾回收机制包括数据打包、清理垃圾数据和清理过期数据三部分

  • 数据打包主要是针对松散的对象文件、pack文件和引用文件进行操作
  • 垃圾数据是指没有引用和引用日志指向的数据(不可达对象),通常是之前被reset掉的数据
  • 过期数据包括reflog、worktree元数据和rerere元数据
  • git的gc机制可以自动触发;底层子命令可以用来执行具体的垃圾回收动作。

常用底层命令:

  • pack-refs:用来打包引用文件
  • repack:用来打包数据对象
  • reflog expire:用来删除超期的日志信息
  • prune:用来删除不可达的松散数据对象文件
  • worktree prune:用来删除残留的worktree元数据
  • rerere gc:用来删除rerere记录的冲突解决元数据

需要注意的是,prune只能删除不可达的松散数据对象文件。如果对象已经被打包到pack文件中,则不能被删除。pack中的不可达对象需要使用repack来删除。参考:Git技术内幕-垃圾回收那些事

3 处理占用较大的项目

  • 在一个大型项目中只克隆一个目录,以提升下载速度:sparse clone和sparse checkout通过设置sparse参数和filter参数,可以只下载需要的部分内容
  • 将这些目录独立成一个新项目 git subtree split -P 【目录】 -b 【新分支名】
  • 浅克隆(shallow clone):git checkout --depth=1 只取最新版本,也可以提交代码、创建分支和标签

其他相关处理技巧: 【GitFAQ-如何拆分大仓库】
【GitFAQ-如何管理大文件】
【GitFAQ-如何删除提交记录中的大文件】

4 根据 Repo 找到 github 用户邮箱

适用于用户主页没有邮箱,但因为代码等问题需要联系该用户时

具体方法:

  • 随便找一条该用户的 Commit 记录,并找到对应 url(比如 https://github.com/didi/xiaoju-survey/commit/3dc15aeb688f04dfdf69f0f46b0f66902303f92d
  • 该 url 后缀 .patch 后即可打开纯本文形式的 Commit 记录,其中就会包含用户邮箱

参考: 一日一技:如何找到Github用户的邮箱?

5 squash:合并多个 commit

  1. 首先确保有两个分支与远程分支是同步的(更直观):master 和 dev
  2. 目的:将 dev 分支下的多个 commit 合并后提交到 master 主分支
  3. 首先在开发分支 dev 下执行 git rebase -i master 进入交互式编辑 git 历史
# 执行上面的语句后,会进入以下编辑界面
pick xxx: commit1 add : add xxx 
Pick xxx: commit 2 fix: update xxxx
Pick xxx: commit 3 fix: delete xxx
Pick xxx: commit 4 modify : update xxxx 
# 进入编辑模式,将除第一行的 pick 外,其余的 pick 都改成 squash 
pick xxx: commit 1 add : add xxx 
squash xxx: commit 2 fix: update xxxx
squash xxx: commit 3 fix: delete xxx
squash xxx: commit 4 modify : update xxxx 
# 最后退出编辑模式,保存即可
  1. squash 操作会将对应的 commit 与上一个 commit 合并
  2. 使用 git push orgin dev: dev -f 将更新强制同步到远程分支
  3. 最后通过 pull requests 提交 dev 远程分支至 master 远程分支

参考:git squash 用法

6 cherry-pick 合并特定的 commit

允许你从一个分支中选择特定的提交(commit)应用到当前的分支

git checkout main # 切换到目标分支, 假设是 main 分支
git cherry-pick 1a2b3c4 # 提交 `1a2b3c4` 的更改,应用到 main 分支
git cherry-pick commit1 commit2 commit3 # 提交多个commit
git cherry-pick commitA^..commitB # 提交两个commit之间的所有更改
git cherry-pick --continue # 解决冲突后,继续提交commit

7 处理文件权限变更问题

现象:文件权限从 old mode 100644 变更为 new mode 100755

  • 100644:普通文件,拥有读写权限,不可执行
  • 100755:普通文件,拥有读写权限,可执行

变更原因:

  • 用户主动修改文件权限,从读写改为可执行
  • 文件在不同操作系统间切换,导致文件权限变化
  • 由于系统配置或版本库迁移等原因导致的权限误变

解决思路:

  • 确认文件权限变更的合理性,合理则保留修改,否则进行还原
  • 配置 Git 忽略文件权限变更:git config core.fileMode false

参考:git中有关old mode 100644、new mode 10075的问题解决小结

往年同期文章