现代 Git 命令和功能

@高效码农  March 11, 2024

我们所有人(软件工程师)每天都会使用,git但大多数人只接触过最基本的命令,例如addcommit或,就像 2005 年一样。push`pull`

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

switch

自 2019 年以来的新功能,或者更准确地说,引入了 Git 版本 2.23,git switch我们可以用它来切换分支:

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 中切换分支git checkout,为什么需要单独的命令?git checkout是一个非常通用的命令 - 它可以(除其他外)检查或恢复特定文件甚至特定提交,而 newgit switch 切换分支。此外,switch还执行额外的健全性检查checkout,例如,如果 switch 会导致本地更改丢失,则 switch 将中止操作。

restore

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

# 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 reset`git checkout[](https://git-scm.com/docs/git#_reset_restore_and_revert)revertrestorereset`

Sparse Checkout

下一个是git sparse-checkout2020 年 1 月 13 日发布的 Git 2.25 中添加的一个更晦涩的功能。

假设您有一个大型 monorepo,微服务分为单独的目录,由于存储库大小,诸如checkout或 之类的命令status非常慢,但也许您真的只需要使用单个子树/目录。好吧,git sparse-checkout救援:

$ 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 中,当您只想构建/部署部分单一存储库并且无需检查时,它对于提高管道性能同样有用。一切。

有关详细文章,sparse-checkout请参阅这篇文章

worktree

这种情况并不罕见,您可能必须同时处理单个应用程序(存储库)中的多个功能,或者当您正在处理某些功能请求时可能会出现严重错误。

在这些情况下,您要么必须克隆存储库的多个版本/分支,要么需要隐藏/丢弃当时正在处理的任何内容。针对这些情况的答案是git worktree,2018年9月24日发布:

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,但我们被告知要紧急修复错误。我们不是隐藏更改并重置分支,而是在分支./hotfix的子目录中创建一个新的工作树master。然后我们可以移动到该目录,进行更改,推送它们并返回到原始工作树。

有关更详细的文章,请参阅这篇文章

bisect

最后但并非最不重要的一点是git bisect,它并不是那么新(Git 1.7.14,于 2012 年 5 月 13 日发布),但大多数人只使用git2005 年左右的功能,所以我认为无论如何它都值得展示。

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

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将检查“坏”“好”提交之间的提交。此时我们需要测试该版本是否有错误,然后我们用它git bisect good来判断git它是否有效git bisect bad。我们不断重复这一过程,直到没有提交为止,并且git会告诉我们哪个提交是引入问题的提交。

我建议查看文档页面,其中显示了更多选项,git bisect包括可视化、重播或跳过提交。

结论

如果您搜索与 相关的问题git,您很可能最终会出现StackOverflow问题,其答案有数千个赞成票。虽然这个答案很可能仍然有效,但它很可能已经过时了,因为它是 10 年前写的。因此,可能有更好、更简单、更容易的方法来做到这一点。因此,当遇到某些git问题时,我建议检查git 文档以获取更新的命令,所有这些命令都有很多很棒的示例,或者探索man页面以查找添加到旧命令中的许多标志和选项。年。



评论已关闭