提升您的 Git 工作流程

2025-06-08

提升您的 Git 工作流程

您好,在这篇文章中,我们将介绍终端 Git 上的一些“高级”功能,用于处理文件更改、分支、提交手、ling 和缩短重复性工作。

这篇文章是上一篇关于如何在终端 Git 中执行常见任务的文章的续篇(也就是第二部分)。你可以在这里阅读。

此外,这篇文章是一篇独立的文章。

您可以查看前一个内容以了解上下文,或者如果您不想查看基础知识,可以从这里开始。

那么,不用多说,我们开始吧!

派对开始了

签署提交

如果您想知道为什么您在 GitHub 上所做的某些提交带有“已验证”标签,而其他提交却不喜欢这样……

已验证的提交

这是因为 GitHub 使用自己的密钥对提交进行了验证签名。

然后,每次您从 GitHub 仪表板进行提交时,您都会获得已验证的提交。

您还可以在将已验证的提交推送到远程之前在本地创建它们。

首先,您必须创建一个 GPG 密钥对,用于在本地签署提交。

如果您不知道如何做这样的事情,请查看GitHub Docs 上的这篇文章。

现在,您已经创建了 GPG 密钥对并将其告知 GitHub。

您可以使用“sign”标志(或简称“-S”)和git commit以下命令开始签署提交:

git commit -S -m "Signing my first commit"
Enter fullscreen mode Exit fullscreen mode

一旦您推送提交,您就可以看到它与其他提交一起出现在“提交”选项卡中,看起来非常漂亮。

可用选项git reset

现在您可能知道,Git 中的“reset”命令用于撤消更改或在我们之前搞砸时纠正问题。

但是我们可以向该命令传递 3 个选项,每个选项都会产生不同的结果。

在研究这些选项之前,让我们快速回顾一下文件在 Git 中的一些不同状态。

工作目录暂存索引提交历史记录

如果您在项目中创建新文件,Git 将检测它们并告诉您有“未跟踪的文件”。

也就是说,工作目录中的文件g尚未添加到_staging区域

未跟踪的文件

如果您运行该命令git reset而不传递任何选项,则效果与您已完成的操作相同。

git reset --mixed
Enter fullscreen mode Exit fullscreen mode

另外两个选项是“--soft”和“--hard”。你可能已经知道这两个选项的用途,但如果你需要复习一下……

  • 混合是默认选项,它会删除更改并将其放回工作目录
  • 软删除更改并将其放入暂存区
  • 硬删除更改但完全丢弃它们,因此它们将不再出现在工作目录暂存区中。

让我们看看它们的实际效果。

假设我们创建一个包含一些更改的新文件,然后提交它们。

当我们检查提交日志时,我们会看到类似的内容。

提交日志

在推动之前,我们意识到我们在改变时犯了一个错误。

因此,我们需要放弃提交并准备好再次编辑文件。

如果我们运行git reset --soft它将删除提交并将文件放回暂存区。

(不要忘记告诉 Git 您想要重置哪个提交,否则该命令将无效)。

如果我们想重置最后一次提交,可以使用表达式 'HEAD~1',意思是“从 HEAD 指针开始,取出第一次提交”。像这样……

暂存区中的文件

现在,您可以看到 Git 提示您可以使用它git reset HEAD <file>来取消暂存文件。

这将产生与使用“--mixed”标志而不是“--soft”标志运行“reset”命令相同的效果。

虽然只是为了看看结果,但我们还是再次提交更改,并使用“--mixed”标志运行命令。结果看起来会像这样……

工作目录中的文件

啊,看到了吗?更改被撤消了,文件现在位于工作目录中。你还可以看到 git 这次提供的额外输出。

现在,如果由于某种原因我们搞砸了某件事,并想摆脱提交和所做的更改。

然后我们运行git reset --hard,这样就好像从未引入过更改一样。

然后,如果我们运行该git status命令,我们将获得一个干净的历史记录,其中带有“无需提交的消息”。

警告:只有当您确实想要摆脱提交及其中的所有更改时才使用“--hard”标志,否则,如果您不小心重置,可能会给您带来麻烦

无需承诺

这样,我们就回到了对文件进行更改之前的初始状态。

我们可以做其他更改,或审查其他文件,或做完全不同的事。

从硬重置中恢复

现在假设您想在现实世界场景中尝试不同的“重置”选项。

然后你不小心删除了你的存储库中的某些工作(甚至是从工作gulp中删除的)

就这样结束了吗?难道一切都要从头再来吗?

震惊的gif

.......

别担心,我的朋友,Git 已经帮我们搞定了。只要它跟踪了更改,就有办法恢复它们。

我们来看看这个强大的git reflog命令。

硬重置后,请记住状态显示“无需提交,工作树干净”。

如果我们想让其中一个提交“起死回生”,我们可以运行该git reflog命令,它将显示以下内容。

Git 引用日志

现在我们可以做这样的事情......

Git 签出 ID

我们现在位于更改被消除之前所存在的提交处git reset --hard

您还可以在消息中看到我们现在处于“分离 HEAD”状态,我们可以查看并使用当时存在的文件。

还要记住,“HEAD”只不过是一个指向提交的指针。

现在指向我们签出的提交 ID,而不是指向它通常所在的位置。

所以现在,由于我们想要恢复丢失的更改index.md

我们可以创建一个新的分支来按照消息中的 iGit 指示保留这些更改。

git checkout -b restore-index类似“我们会成功”之类的话。

现在,如果我检查状态和提交日志,我将看到以下内容。

Git 新分支

看看这个,是不是很酷?我们能够通过之前的提交来恢复之前的更改。

git merge如果我们愿意的话,我们现在可以将它们集成到主分支中。

只需一个命令即可添加文件、改写消息、合并更改等

现在让我们看看如何将我们的提交处理技能提升一个档次。

git rebase我们可以使用“交互式”标志来做一些特别有趣的事情,让它变得更酷、更容易使用。

当您第一次使用“--interactive”标志(或简称“-i”)运行rebase命令时,您将看到类似这样的内容。

Git rebase 交互式

该消息会告诉您需要了解哪些信息才能使其正常工作。

我们必须告诉 Git 我们想要重新定位到哪个分支(可以是我们最初所在的分支)

如果我们运行该命令,默认编辑器将打开并显示以下内容

基于变更分支进行变基

正如您所看到的,我们将把“restore-index”分支上的提交重新定位到“changes”分支上。

默认情况下,提交 ID 和消息前面会显示单词“pick”。

这意味着我们将使用这个提交作为 rebase 的一部分。

在下面,您可以看到除了“pick”之外还有哪些其他可用的命令。

您还可以看到有关 rebase 如何工作的更多重要信息。

如果我们保存更改并退出编辑器,则重新定基将完成。

现在我们回到终端,并收到来自 Git 的成功消息。

成功重新定基与单独运行命令相比,我们可以用交互模式 f 做更多有用的事情git rebase

  • 我们可以使用“reword”命令更改任何提交的提交消息,而不仅仅是最后一个提交。
  • 我们可以使用“编辑”命令添加提交中可能遗漏的文件或更改。
  • 我们可以使用“squash”命令将多个提交合并成一个更具描述性的提交。
  • 我们可以像以前一样做,但不必关心使用“fixup”命令的提交消息。
  • 我们可以使用“drop”命令删除那些可能不是好主意并且不希望任何同行评审员看到它们的提交。

所有这些操作都只需要一个 Git 命令即可完成。

使用“autosquash”自动执行 rebase 过程

更酷的是,一旦你开始更频繁地使用 rebase,你就可以自动执行此过程,并避免在 Git 编辑器上做额外的工作。

让我们看一个例子。

而不是在几次提交上取得渐进的进展,然后才完成。

  • 拉起 git 编辑器。
  • 选择要压缩的提交。
  • 选择在提交时留下的消息。
  • 确保一切正常。

我们可以提前告诉 Git 完成所有这些操作。

index.md假设我们对现有文件做了一些额外的更改,现在我们要提交这些新的更改。

我们会添加更改,然后像往常一样创建提交,并附上我们正在处理的内容的消息。

新的主要提交

现在对于下一次提交,我们可以使用“--fixup”标志和我们将重新定基的提交的 id,而不是编写随机消息并在最后丢弃它们,就像这样...

使用 fixup 标志

现在,如果我们检查提交日志,我们将看到以下内容。

使用新提交进行日志记录

开头的“修复!”说明了提交的目的以及这些更改属于哪个提交。

下次我们会做出一些改变并提交它们。

我们可以通过执行以下操作来避免传递第一个提交的 id(可能是因为我们没有复制它并且我们忘记了它是什么)。

git commit --fixup :/important
Enter fullscreen mode Exit fullscreen mode

这可能看起来很奇怪,但这只是告诉 Git“在提交消息中查找带有字符串‘important’的最新提交”的一种方法

我们可以对我们将要进行的所有“WIP”提交重复这一点,它们甚至不需要按顺序进行。

假设我在处理“index.md”文件时需要开发另一个功能。最后,我可以得到如下的提交日志……

更新提交日志

您可以看到“修复”是非连续的,并且需要提交另一项更改。

我们现在唯一需要做的就是使用带有提交 ID 或我们要重新定基的分支名称的“--autosquash”标志进行重新定基。

git rebase -i ---autosquash 02da2df
Enter fullscreen mode Exit fullscreen mode

这将启动编辑器,您可以看到提交已经按照我们想要的命令正确排序。

使用自动压缩进行 rebase

现在我们可以保存并退出编辑器,rebase 操作将成功完成。如果您发现任何错误或缺失,请删除注释上方的行并退出编辑器。

现在,当我们检查提交日志时,我们会看到类似这样的内容

重新建立提交日志

因此,“修复”被压缩到我们为此目的指定的原始提交中。

此外,另一个提交已被正确移动,我们不需要在编辑器上做任何额外的事情来实现这一切!

这是一场胜利

强制推送至远程时需谨慎

现在需要注意的是,重新定基的操作会重写历史记录并更改受影响提交的 ID。

有了它,您将拥有与远程不同的历史记录,因为即使更改相同,提交也会不同。

由于我们通过重新定基重写了历史记录,您可能认为只需强制推送到远程即可。

这样它就会拥有和我们本地相同的历史记录。但不要这样做……

git push --force origin changes 
Enter fullscreen mode Exit fullscreen mode

我们将使用“--force-with-lease”标志而不是“--force”标志进行推动。

git push --force-with-lease origin changes 
Enter fullscreen mode Exit fullscreen mode

这是一个需要格外小心的选择,然后再采取行动。

如果其他人向该分支添加了其他提交,则操作将失败(本质上确保您不会覆盖团队成员的工作)

使用别名可以节省重复工作的时间。

一旦您习惯了每天重复几次的某个 git 工作流程,您就可以使用 Git 中的别名对其进行优化。

它们位于.gitconfig[alias]部分的文件内,并且如果我们愿意的话,它们基本上允许我们创建“新”命令。

你可能已经在上面的例子中注意到,我最常用的命令都有非常简约的别名😅

您可以使用其选项来执行命令,也可以创建更具描述性的命令,例如

deploy = "!git push --force deis \"$(git rev-parse --abbrev-ref HEAD):master\""
Enter fullscreen mode Exit fullscreen mode

或者你可以用几个键来运行一个长命令,比如

lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%C    reset' --abbrev-commit --branches
Enter fullscreen mode Exit fullscreen mode

这就是别名的魅力所在,你可以随心所欲地自定义 Git。“唯一的限制就是你的想象力”。

有关别名的更多信息,请参阅Git 书中的文档。

总结

现在,有了这些知识,您已经准备好出去解决一些工作流程难题,更重要的是,您可以有信心使用 Git 来完成其他人认为是终端魔法的事情。

记住要善用你的力量,不仅可以改善你的工作流程,还可以帮助那些不像你一样精通 Git 神秘艺术的人🧙‍♂️

这篇文章就到这里!感谢你的阅读,希望这篇文章能给你一些启发,并帮助你更好地、更高效地使用 Git。


daily.dev在每个新标签页发布最棒的编程新闻。我们将为您筛选数百个优质资源,助您掌控未来。
每日海报

鏂囩珷鏉ユ簮锛�https://dev.to/dailydotdev/level-up-your-git-workflow-3jio
PREV
语义 HTML 及其重要性
NEXT
⚛️ JavaScript 面试题、React、CSS 等 — 每周精选 #113