0

0

13个实用Git技巧

WBOY

WBOY

发布时间:2024-07-21 10:31:01

|

654人浏览过

|

来源于Linux就该这么学

转载

13个实用git技巧

为了纪念 Git 的 13 岁生日,这里有 13 条技巧和诀窍来让你的 Git 经验更加有用和强大。从你可能忽略的一些基本知识开始,并扩展到一些真正的高级用户技巧!

1、 你的 ~/.gitconfig 文件

当你第一次尝试使用 git 命令向仓库提交一个更改时,你可能会收到这样的欢迎信息:

*** Please tell me who you are.
Run
  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"
to set your account's default identity.

你可能没有意识到正是这些命令在修改 ~/.gitconfig 的内容,这是 Git 存储全局配置选项的地方。你可以通过 ~/.gitconfig 文件来做大量的事,包括定义别名、永久性打开(或关闭)特定命令选项,以及修改 Git 工作方式(例如,git diff 使用哪个 diff 算法,或者默认使用什么类型的合并策略)。你甚至可以根据仓库的路径有条件地包含其他配置文件!所有细节请参阅 man git-config。

2、 你仓库中的 .git/config 文件

在之前的技巧中,你可能想知道 git config 命令中 --global 标志是干什么的。它告诉 Git 更新~/.gitconfig 中的“全局”配置。当然,有全局配置也意味着会有本地配置,显然,如果你省略 --global标志,git config 将改为更新仓库特有的配置,该配置存储在 .git/config 中。

在 .git/config 文件中设置的选项将覆盖 ~/.gitconfig 文件中的所有设置。因此,例如,如果你需要为特定仓库使用不同的电子邮件地址,则可以运行 git config user.email "also_you@example.com"。然后,该仓库中的任何提交都将使用你单独配置的电子邮件地址。如果你在开源项目中工作,而且希望它们显示自己的电子邮件地址,同时仍然使用自己工作邮箱作为主 Git 配置,这非常有用。

几乎任何你可以在 ~/.gitconfig 中设置的东西,你也可以在 .git/config 中进行设置,以使其作用于特定的仓库。在下面的技巧中,当我提到将某些内容添加到 ~/.gitconfig 时,只需记住你也可以在特定仓库的.git/config 中添加来设置那个选项。

3、 别名

别名是你可以在 ~/.gitconfig 中做的另一件事。它的工作原理就像命令行中的 shell —— 它们设定一个新的命令名称,可以调用一个或多个其他命令,通常使用一组特定的选项或标志。它们对于那些你经常使用的又长又复杂的命令来说非常有效。

你可以使用 git config 命令来定义别名 —— 例如,运行 git config --global --add alias.st status 将使运行 git st 与运行 git status 做同样的事情 —— 但是我在定义别名时发现,直接编辑 ~/.gitconfig文件通常更容易。

如果你选择使用这种方法,你会发现 ~/.gitconfig 文件是一个 INI 文件。INI 是一种带有特定段落的键值对文件格式。当添加一个别名时,你将改变 [alias] 段落。例如,定义上面相同的 git st 别名时,添加如下到文件:

[alias]
st = status

(如果已经有 [alias] 段落,只需将第二行添加到现有部分。)

4、 shell 命令中的别名

别名不仅仅限于运行其他 Git 子命令 —— 你还可以定义运行其他 shell 命令的别名。这是一个用来处理一个反复发生的、罕见和复杂的任务的很好方式:一旦你确定了如何完成它,就可以在别名下保存该命令。例如,我有一些复刻fork的开源项目的仓库,并进行了一些本地修改。我想跟上项目正在进行的开发工作,并保存我本地的变化。为了实现这个目标,我需要定期将来自上游仓库的更改合并到我复刻的项目中 —— 我通过使用我称之为upstream-merge 的别名来完成。它是这样定义的:

upstream-merge = !"git fetch origin -v && git fetch upstream -v && git merge upstream/master && git push"

别名定义开头的 ! 告诉 Git 通过 shell 运行这个命令。这个例子涉及到运行一些 git 命令,但是以这种方式定义的别名可以运行任何 shell 命令。

(注意,如果你想复制我的 upstream-merge 别名,你需要确保你有一个名为 upstream 的 Git 远程仓库,指向你已经分配的上游仓库,你可以通过运行 git remote add upstream <URL to repo> 来添加一个。)

5、 可视化提交图

如果你在一个有很多分支活动的项目上开发,有时可能很难掌握所有正在发生的工作以及它们之间的相关性。各种图形用户界面工具可让你获取不同分支的图片并在所谓的“提交图表”中提交。例如,以下是我使用 GitLab提交图表查看器可视化的我的一个仓库的一部分:

13个实用Git技巧

GitLab commit graph viewer

如果你是一个专注于命令行的用户或者发现分支切换工具让人分心,那么可以从命令行获得类似的提交视图。这就是 git log 命令的 --graph 参数出现的地方:

13个实用Git技巧

Repository visualized with --graph command

以下命令可视化相同仓库可达到相同效果:

git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)< %an>%Creset' --abbrev-commit --date=relative

--graph 选项将图添加到日志的左侧,--abbrev-commit 缩短提交的 SHA 值,--date=relative 以相对方式表示日期,以及 --pretty 来处理所有其他自定义格式。我有个 git lg 别名用于这个功能,它是我最常用的 10 个命令之一。

6、 更优雅的强制推送

有时,你越是想避开越避不开,你会发现你需要运行 git push --force 来覆盖仓库远程副本上的历史记录。你可能得到了一些反馈,需要你进行交互式变基rebase,或者你可能已经搞砸了,并希望隐藏“罪证”。

AITDK
AITDK

免费AI SEO工具,SEO的AI生成器

下载

当其他人在仓库的远程副本的同一分支上进行更改时,会发生强制推送的危险。当你强制推送已重写的历史记录时,这些提交将会丢失。这就是 git push --force-with-lease 出现的原因 -- 如果远程分支已经更新,它不会允许你强制推送,这确保你不会丢掉别人的工作。

7、 git add -N

你是否使用过 git commit -a 在一次行动中提交所有未完成的修改,但在你推送完提交后才发现 git commit -a 忽略了新添加的文件?你可以使用 git add -N (想想 “notify”) 来解决这个问题,告诉 Git 在第一次实际提交它们之前,你希望在提交中包含新增文件。

8、 git add -p

使用 Git 时的最佳做法是确保每次提交都只包含一个逻辑修改 —— 无论这是修复错误还是添加新功能。然而,有时当你在工作时,你的仓库中的修改最终应该使用多个提交。你怎样才能设法把事情分开,使每个提交只包含适当的修改呢?git add --patch 来拯救你了!

这个标志会让 git add 命令查看你工作副本中的所有变化,并为每个变化询问你是否想要将它提交、跳过,或者推迟决定(你可以在运行该命令后选择 ? 来查看其他更强大的选项)。git add -p 是生成结构良好的提交的绝佳工具。

9、 git checkout -p

与 git add -p 类似,git checkout 命令也接受 --patch 或 -p 选项,这会使其在本地工作副本中显示每个“大块”的改动,并允许丢弃它 —— 简单来说就是将本地工作副本恢复到更改之前的状态。

这真的很棒。例如,当你追踪一个 bug 时引入了一堆调试日志语句,修正了这个 bug 之后,你可以先使用 git checkout -p 移除所有新的调试日志,然后 git add -p 来添加 bug 修复。没有比组合一个优雅的、结构良好的提交更令人满意!

10、 变基时执行命令

有些项目有一个规则,即存储库中的每个提交都必须处于可工作状态 —— 也就是说,在每次提交时,应该可以编译该代码,或者应该运行测试套件而不会失败。 当你在分支上工作时,这并不困难,但是如果你最终因为某种原因需要变基rebase时,那么需要逐步完成每个变基的提交以确保你没有意外地引入一个中断,而这个过程是乏味的。

幸运的是,git rebase 已经覆盖了 -x 或 --exec 选项。git rebase -x <cmd> 将在每个提交在变基中被应用后运行该命令。因此,举个例子,如果你有一个项目,其中使用 npm run tests 运行你的测试套件,git rebase -x npm run tests 将在变基期间每次提交之后运行测试套件。这使你可以查看测试套件是否在任何变基的提交中失败,以便你可以确认测试套件在每次提交时仍能通过。

11、 基于时间的修订引用

很多 Git 子命令都接受一个修订参数来决定命令作用于仓库的哪个部分,可以是某次特定的提交的 SHA1 值,一个分支的名称,甚至是一个符号性的名称如 HEAD(代表当前检出分支最后一次的提交),除了这些简单的形式以外,你还可以附加一个指定的日期或时间作为参数,表示“这个时间的引用”。

这个功能在某些时候会变得十分有用。当你处理最新出现的 bug,自言自语道:“这个功能昨天还是好好的,到底又改了些什么”,不用盯着满屏的 git log 的输出试图弄清楚什么时候更改了提交,你只需运行 git diff HEAD@{yesterday},看看从昨天以来的所有修改。这也适用于更长的时间段(例如 git diff HEAD@{'2 months ago'}),以及一个确切的日期(例如 git diff HEAD@{'2010-01-01 12:00:00'})。

你也可以将这些基于日期的修订参数与使用修订参数的任何 Git 子命令一起使用。在 gitrevisions 手册页中有关于具体使用哪种格式的详细信息。

12、 全知的 reflog

你是不是试过在变基时干掉过某次提交,然后发现你需要保留那个提交中一些东西?你可能觉得这些信息已经永远找不回来了,只能重新创建。但是如果你在本地工作副本中提交了,提交就会被添加到引用日志(reflog)中 ,你仍然可以访问到。

运行 git reflog 将在本地工作副本中显示当前分支的所有活动的列表,并为你提供每个提交的 SHA1 值。一旦发现你变基时放弃的那个提交,你可以运行 git checkout <SHA1> 跳转到该提交,复制任何你需要的信息,然后再运行 git checkout HEAD 返回到分支最近的提交去。

13、 自己清理

哎呦! 事实证明,我的基本数学技能不如我的 Git 技能。 Git 最初是在 2005 年发布的,这意味着它今年会变成 13 岁,而不是 12 岁(LCTT 译注:本文原来是以 12 岁生日为题的)。为了弥补这个错误,这里有可以让我们变成十三岁的第 13 条技巧。

如果你使用基于分支的工作流,随着在一个长期项目上的工作,除非你在每个分支合并时清理干净,否则你最终会得到一大堆分支。这使得你难于找到想要的分支,分支的森林会让你无从找起。甚至更糟糕的是,如果你有大量活跃的分支,确定一个分支是否被合并(可以被安全删除)或仍然没有被合并而应该留下会非常繁琐。幸运的是,Git 可以帮到你:只需要运行 git branch --merged 就可以得到已经被合并到你的当前分支的分支列表,或者 git branch --no-merged 找出被合并到其它分支的分支。默认情况下这会列出你本地工作副本的分支,但是如果你在命令行包括 --remote 或 -r 参数,它也会列出仅存于远程仓库的已合并分支。

重要提示:如果你计划使用 git branch --merged 的输出来清理那些已合并的分支,你要小心它的输出也包括了当前分支(毕竟,这个当前的分支就被合并到当前分支!)。确保你在任何销毁动作之前排除了该分支(如果你忘记了,参见第 12 条技巧来学习 reflog 怎样帮你把分支找回来,希望有用……)。

以上是全部内容

希望这些技巧中至少有一个能够教给你一些关于 Git 的新东西,Git 是一个有 13 年历史的项目,并且在持续创新和增加新功能中。你最喜欢的 Git 技巧是什么?


热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

444

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

605

2023.08.10

自建git服务器
自建git服务器

git服务器是目前流行的分布式版本控制系统之一,可以让多人协同开发同一个项目。本专题为大家提供自建git服务器相关的各种文章、以及下载和课程。

979

2023.07.05

git和svn的区别
git和svn的区别

git和svn的区别:1、定义不同;2、模型类型不同;3、存储单元不同;4、是否拥有全局版本号;5、内容完整性不同;6、版本库不同;7、克隆目录速度不同;8、分支不同。php中文网为大家带来了git和svn的相关知识、以及相关文章等内容。

582

2023.07.06

git撤销提交的commit
git撤销提交的commit

Git是一个强大的版本控制系统,它提供了很多功能帮助开发人员有效地管理和控制代码的变更,本专题为大家提供git 撤销提交的commit相关的各种文章内容,供大家免费下载体验。

275

2023.07.24

git提交错误怎么撤回
git提交错误怎么撤回

git提交错误撤回的方法:git reset head^:撤回最后一次提交,恢复到提交前状态。git revert head:创建新提交,内容与之前提交相反。git reset :使用提交的 sha-1 哈希撤回指定提交。交互式舞台区:标记要撤回的特定更改,然后提交,排除已撤回更改。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

568

2024.04.09

git怎么对比两个版本的文件内容
git怎么对比两个版本的文件内容

要对比两个版本的 git 文件,请使用 git diff 命令:git diff 比较工作树和暂存区之间的差异。git diff 比较两个提交或标签之间的差异。git diff 输出显示差异块,其中 + 表示添加的行,- 表示删除的行, 表示修改的行。可使用 gitkraken、meld、beyond compare 等可视化工具更直观地查看差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

533

2024.04.09

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

498

2023.08.14

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.6万人学习

Git 教程
Git 教程

共21课时 | 4.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号