【每日一技】那些鲜为人知的 git 实用新功能

6,602 阅读5分钟

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

系列介绍

每日一技系列 是一个 How to 的系列,内容摘自我维护的知识星球:Android 解忧杂货铺,专注于高质量碎片化知识的分享。

目前星球中已经有600多位小伙伴,感兴趣的小伙伴可以在底部加我微信进入。

前言

git 几乎是每个程序员都会使用的版本控制工具,但是你是否有这样的困扰:

  • 想为不同项目配置不同的 git 信息,每个新项目都要用 git config --local 配置一次,很烦
  • 使用 feature-branching 工作流时经常在 多个 feature 或 修复 bug 的分支来回切换,每次都要 syc 一次项目,还要用 stash 暂存修改
  • git checkout 命令承载了 切换分支和文件恢复的部分功能,职责不单一
  • ...

本文介绍几个我日常用到的 git 新功能,并在文末附上 mac 上更新 git 的方法。

多分支操作利器:worktree(2.5)

目前主流的 git 工作流是 feature-branching,即:任何新的功能(feature)或 bug 修复全都新建一个 branch 来写。

当我们在某个 feature 分支上开发时(分支名 feature),有一个高优的 bug 需要解决,这时候我们一般会进行如下操作:

  1. 使用 git stash 隐藏未完成的修改
  2. 基于 dev 分支创建并切换到修改 bug 的分支(分支名 bugfix)
  3. 进行开发,测试完成后合入 dev 分支
  4. 切回 feature 分支,使用 git stash pop 恢复之前未完成的修改,继续开发

很多小伙伴会平时会再 clone 出一个项目来简化上述场景,不过这会带来另一个问题:你需要保持两个仓库与远程的同步。

git 2.5 版本引入了 git worktree 命令,该命令允许将分支检出到某个文件夹下。对于上文提到的场景,我们只需:

  1. 使用 git worktree add -b bugfix ../bugfix dev 基于 dev 创建 bugfix 分支到 ../bugfix 目录
  2. cd ../bugfix 进入到该目录进行开发

bugfix 目录对应 bugfix 分支,与 feature 分支互不干扰,并且 bugfix 目录下的 .git 是一个文件,指向主仓库。

git worktree add <path> <branch>:关联一个branch到指定的路径

git worktree add -b <new_branch> <path> <branch>:基于指定branch新建一个branch到指定路径

差异配置:IncludeIf (2.13)

作为 github 的重度使用者,我经常会发布一些个人项目。个人项目与公司项目的 git 配置是有很多差异的,例如:

  • 用户名邮箱
  • 拉代码的方式(rebase 还是 merge)
  • ...

git 2.13 版本前 可以使用 git config --globalgit config --local 分别设置全局配置和本地配置

2.13 版本开始,我们有了新的选择,IncludeIf 为不同目录下的仓库提供不同的默认设置

简单讲,我们可以为指定目录下的所有仓库单独设置 git 配置,例如我们在 ~/projects 下建立三个目录:workpersonalthirdparty 分别存储公司,个人和第三方的项目:

之后我们可以为这三个目录以及全局设置不同的 git 配置,其中全局的配置文件在 ~/.gitconfig,目录的独立的配置文件需要我们手动创建,例如我们分别创建 .gitconfit-work.gitconfig-personal.gitconfig-thridparty:

之后我们在 ~/.gitconfig 加入如下配置:

省略...

+ [includeIf "gitdir:~/projects/work/"]
+  path = ~/.gitconfig-work
+ [includeIf "gitdir:~/projects/personal/"]
+  path = ~/.gitconfig-personal
+ [includeIf "gitdir:~/projects/thirdparty/"]
+  path = ~/.gitconfig-thirdparty

这样 ~/projects/work/ 目录下的所有 git 仓库都使用 ~/.gitconfig-work 中的配置。(注意:使用 git config --local 的配置优先级更高)

例如我们在 ~/.gitconfig-work 填入工作的用户信息:

[user]
  signingkey = xxxxxxxx
  name = xxxx
  email = xxx@yy.com

为 checkout 减负:switch 和 restore(2.23)

我们都知道,git checkout 可以切换分支,除此之外,git checkout 还可以切换到某个 commit,或者恢复文件:

git checkout branchname # 切换分支

git checkout -b branchname # 创建并切换到新的分支

git checkout commitid # 切换到某个commit id

git checkout -- filename # 丢弃工作区某文件的修改

git 2.23 版本开始引入了 git switchgit restore 命令

# 切换分支
- git checkout branchname
+ git switch branchname

# 创建并切换到新的分支
- git checkout -b branchname
+ git switch -c branchname # -c 代表 -- create

git checkout commitid # 无替代

# 丢弃工作区某文件的修改
- git checkout -- filename
+ git restore -- filename # 等价 git restore -W --filename 其中 -W 代表 --worktree

# 将某文件从暂存区移除
+ git restore -S -- filename # -S 代表 --staged

# 将某文件从暂存区移除并丢弃工作区的修改
+ git restore -S -W -- filename

git switch 命令专注于分支的切换,git restore 命令可以将文件从暂存区移至工作区或从工作区丢弃

注意,git switch 不能切换至 commit id

mac 使用 brew 更新默认 git

一般来说,mac 自带的 git 版本较低,我们可以使用 brew 安装或更新 git:

# 安装 git
brew install git

# 升级 git
brew upgrade git

brew 安装软件时首先会更新自身,屏幕显示:Updating Homebrew...,通常较慢,我们可以使用 ctrl + c 跳过这一过程。

不过此时系统默认的 git 并不是 brew 安装的版本,我们只需执行以下命令将默认 git 连接到 brew 安装的版本上:

brew link --overwrite git

我们可以使用 git versiongit --version 查看目前的 git 版本。完整操作如下图:

关于我

人总是喜欢做能够获得正反馈(成就感)的事情,如果感觉本文内容对你有帮助的话,麻烦点亮一下👍,这对我很重要哦~

我是 Flywith24人只有通过和别人的讨论,才能知道我们自己的经验是否是真实的,加我微信交流,让我们共同进步。