了解一下 Git 的一些现代命令和特性?

你应该了解和使用的现代 Git 命令和功能

现在已经不是 2005 年了, git提供的不仅仅是add, commit, pushpull. 让我们来探讨一下你应该知道的所有新的, 现代化的 git 命令吧.

我们所有的软件工程师每天都在使用git, 但大多数人只接触过add, commit, pushpull等最基本的命令, 就像还在2005年一样.

然而, Git 从那时起引入了许多功能, 使用这些功能可以让你的生活变得更轻松, 所以让我们来探索一些最近添加的现代 git 命令, 你应该了解它们.

switch

从 2019 年开始, 或者更准确地说, 从 Git 2.23 版本开始, 我们可以使用 git switch 来切换分支:

php 复制代码
git switch other-branch
git switch -  # Switch back to previous branch, similar to "cd -"
git switch remote-branch  # Directly switch to remote branch and start tracking it

这很酷, 但我们从一开始就用 git checkout 在 Git 中切换分支了, 为什么还需要一个单独的命令呢? git checkout是一个非常通用的命令--它可以(除其他外)检出或恢复特定文件, 甚至特定提交, 而新的 git switch 切换分支. 此外, switch还会执行一些checkout不执行的额外的合理性检查, 例如, 如果switch会导致本地改动丢失, 那么它就会中止操作.

restore

Git 2.23 版新增的另一个子命令/功能是 git restore, 我们可以用它把文件恢复到上次提交的版本:

css 复制代码
# Unstage changes made to a file, same as "git reset some-file.py"
git restore --staged some-file.py

# Unstage and discard changes made to a file, same as "git checkout some-file.py"
git restore --staged --worktree some-file.py

# Revert a file to some previous commit, same as "git reset commit -- some-file.py"
git restore --source HEAD~2 some-file.py

上面代码段中的注释解释了各种 git restore 的工作原理. 一般来说, git restore取代并简化了git resetgit checkout的一些用例, 因为它们已经是超载的功能了. 关于 revert, restorereset 的比较, 请参阅 本文档部分.

sparse-checkout

Next one is git sparse-checkout, a little more obscure feature that was added in Git 2.25, which was released on January 13, 2020.

下一个是 git sparse-checkout, 这是 2020 年 1 月 13 日发布的 Git 2.25 中新增的一个不起眼的功能.

比方说, 你有一个大型的单仓库(monorepo), 其中的微服务被分隔到各个目录中, 由于版本库太大, checkoutstatus之类的命令执行起来非常慢, 但也许你真的只需要处理单个子树/目录. 那么, git sparse-checkout 来拯救你了:

shell 复制代码
$ git clone --no-checkout https://github.com/derrickstolee/sparse-checkout-example
$ cd sparse-checkout-example
$ git sparse-checkout init --cone  # Configure git to only match files in root directory
$ git checkout main  # Checkout only files in root directory
$ ls
bootstrap.sh  LICENSE.md  README.md

$ git sparse-checkout set service/common

$ ls
bootstrap.sh  LICENSE.md  README.md  service

$ tree .
.
├── bootstrap.sh
├── LICENSE.md
├── README.md
└── service
    ├── common
    │   ├── app.js
    │   ├── Dockerfile
    ... ...

在上面的例子中, 我们首先克隆了仓库, 但并没有实际检查所有文件. 然后我们使用git sparse-checkout init --cone来配置git只匹配仓库根目录下的文件. 这样, 在运行checkout后, 我们就只有 3 个文件, 而不是整棵树了. 要下载/检出特定目录, 我们使用git sparse-checkout set ....

如前所述, 这在本地处理庞大的仓库时非常方便, 但在 CI/CD 中, 当你只想构建/部署 monorepo 的一部分, 而不需要检出所有文件时, 这对提高流水线性能同样有用.

有关sparse-checkout的详细介绍, 请参阅这里.

worktree

一个人可能需要同时在单个应用(仓库)中处理多个功能, 或者当你正在处理某个功能请求时出现了一个重要的 bug, 这种情况并不少见.

在这种情况下, 要么你必须克隆多个版本/分支的版本库, 要么你需要隐藏/丢弃你当时正在处理的内容. 2018 年 9 月 24 日发布的 git worktree 就是解决这些情况的办法:

bash 复制代码
git branch
# * dev
# master

git worktree list
# /.../some-repo  ews5ger [dev]

git worktree add -b hotfix ./hotfix master

# Preparing worktree (new branch 'hotfix')
# HEAD is now at 5ea9faa Signed commit.

git worktree list
# /.../test-repo         ews5ger [dev]
# /.../test-repo/hotfix  5ea9faa [hotfix]

cd hotfix/  # Clean worktree, where you can make your changes and push them

该命令允许我们同时签出同一版本库的多个分支. 在上面的例子中, 我们有 2 个分支devmaster. 假设我们正在dev分支中开发功能, 但有人告诉我们要进行紧急 bug 修复. 与其将更改存储起来并重置分支, 不如在 master 分支的 ./hotfix 子目录下创建一个新的Worktree. 然后, 我们就可以移动到该目录, 进行修改, 推送并返回原始Worktree.

更详细的介绍请参阅本文.

bisect

最后但并非最不重要的是git bisect, 它并不新鲜(Git 1.7.14, 2012 年 5 月 13 日发布), 但大多数人只使用 2005 年左右的git功能, 所以我觉得还是值得展示一下.

正如文档页所描述的那样: git-bisect - 使用二进制搜索查找引入错误的提交:

ini 复制代码
git bisect start
git bisect bad HEAD  # Provide the broken commit
git bisect good 479420e  # Provide a commit, that you know works
# Bisecting: 2 revisions left to test after this (roughly 1 step)
# [3258487215718444a6148439fa8476e8e7bd49c8] Refactoring.

# Test the current commit...
git bisect bad  # If the commit doesn't work
git bisect good # If the commit works

# Git bisects left or right half of range based on the last command
# Continue testing until you find the culprit

git bisect reset  # Reset to original commit

首先, 我们使用 git bisect start明确启动分段会话, 然后提供不生效的提交(很可能是HEAD)和最后一次已知的工作提交或标记. 有了这些信息, git 就会检查出介于 "bad""good" 提交之间的一个提交. 这时, 我们需要测试该版本是否有 bug, 然后使用git bisect good来告诉git该版本有效, 或使用git bisect bad来告诉 git该版本无效. 我们不断重复这个过程, 直到没有提交了, git 就会告诉我们哪个提交引入了问题.

我推荐你去看看文档那里还有更多关于git bisect 的选项, 包括可视化, 重放或跳过提交.

总结一下

如果你搜索一些与 git 相关的问题, 你很可能会在 StackOverflow 上找到有几千个向上投票的答案的问题. 虽然这个答案很可能仍然有效, 但很可能已经过时, 因为它是 10 年前写的. 因此, 可能还有更好, 更简单, 更容易的方法. 所以, 当遇到一些git问题时, 我建议查看git文档, 了解更多最新的命令, 这些命令都有很多很好的示例, 或者浏览man页面, 了解多年来添加到老命令中的很多标志和选项.

相关推荐
姑苏风2 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
数据猎手小k5 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
但老师5 小时前
Git遇到“fatal: bad object refs/heads/master - 副本”问题的解决办法
git
秃头女孩y6 小时前
git创建分支
git
你的小106 小时前
JavaWeb项目-----博客系统
android
风和先行6 小时前
adb 命令查看设备存储占用情况
android·adb
AaVictory.7 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
似霰8 小时前
安卓智能指针sp、wp、RefBase浅析
android·c++·binder
大风起兮云飞扬丶8 小时前
Android——网络请求
android
干一行,爱一行8 小时前
android camera data -> surface 显示
android