当前位置: 首页 > 科技观察

工作流程一目了然,看看10个Git命令

时间:2023-03-16 01:34:16 科技观察

gitmerge,gitrebase,gitreset,gitrevert,gitfetch,gitpull,gitreflog……你知道这些git命令执行的是什么吗?任务?如果你还有点不明白,那就不要错过这篇文章。在本文中,熟悉JavaScript、TypeScript、GraphQL、Serverless、AWS、Docker和Golang的21岁软件顾问LydiaHallie以动画的形式直观地介绍了这些常用的git命令的工作过程,所以你永远不会忘记他们。虽然Git是一个非常强大的工具,但如果我说Git是使用起来的噩梦,大多数人都会同意我的看法。我发现在使用Git时在脑海中想象它非常有用:当我执行特定命令时,这些分支如何交互以及它们如何影响历史记录?当我在master上执行硬重启、强制推送到origin分支并rimraf我们的.git文件夹时,为什么我的同事哭了?我认为创建一些最常用和有用的Git命令的可视化示例将是一个完美的用例!我将在下面描述的许多命令都有可选参数——您可以使用这些参数来更改相应命令的行为。而我的示例将仅涵盖命令的默认行为,而不会添加(或添加太多)可选配置!这篇文章是由莉迪亚·哈莉(L??ydiaHallie)撰写的。合并对于拥有多个分支来说很方便,可以将不同的新更改彼此隔离,并确保您不会意外地将未经批准或损坏的代码更改推送到生产代码。但是一旦这些修改被批准,我们需要将它们部署到我们的生产分支!将更改从一个分支合并到另一个分支的一种方法是执行gitmerge。Git可以执行两种类型的合并:快进和非快进。您现在可能无法分辨出差异,但让我们稍后看一下差异。fast-forward(--ff)可以在当前分支相对于我们要合并的分支没有额外的提交(commits)时进行快进合并。Git是懒惰的,会首先尝试实现最简单的选项:快进!这种类型的合并不会创建新的提交,而是将我们正在合并的分支上的提交直接合并到当前分支中。完美的!现在,我们在dev分支上所做的所有更改都合并到master分支中。那么没有快进是什么意思呢?No-fast-forward(--no-ff)如果您当前的分支与您要合并的分支相比没有任何提交,那很好,但遗憾的是这种情况很少见!如果我们在当前分支上提交我们要合并的分支没有的更改,那么git将执行非快进合并。当使用no-fast-forward合并时,Git在当前活动的分支上创建一个新的合并提交。这个commit的parentcommit指向这个活跃的分支,同时也指向我们要合并的分支!没什么大不了的,完美融合!现在,我们在dev分支上所做的所有更改都合并到master分支中。合并冲突虽然Git非常擅长决定如何合并分支以及如何向文件添加更改,但它并不总是完全自己做出这些决定。当我们要合并的两个分支对同一个文件的同一行代码有不同的修改,或者一个分支删除了一个文件,另一个分支修改了文件时,Git不知道该如何选择。在这种情况下,Git会询问您要保留哪个选项?假设我们在两个分支中编辑README.md的第一行。如果我们尝试将dev合并到master中,将会出现合并冲突:doyouwantthetitletobeHello!或嘿!?当试图合并这些分支时,Git会告诉你冲突发生的地方。我们可以手动删除不想保留的更改,保存更改,再次添加修改后的文件,并提交更改。结束!虽然合并冲突通常很烦人,但这是有道理的:Git不应该猜测我们想要保留哪些更改。变基我们刚刚看到您可以通过执行gitmerge将更改从一个分支应用到另一个分支。将更改从一个分支合并到另一个分支的另一种方法是执行gitrebase。gitrebase会将当前分支的提交复制到指定的分支。完美,现在我们将master分支上所做的所有更改获取到dev分支上。变基在一个重要方面不同于合并:Git不会尝试确定要保留或不保留哪些文件。我们变基的分支总是包含我们想要保留的最新更改!这样我们就不会遇到任何合并冲突,并且我们会保持良好的线性Git历史记录。上面的示例显示了在master分支上的变基。然而,在较大的项目中,您通常不需要这样的操作。gitrebase修改项目的历史,因为它为复制的提交创建新的哈希值。如果您正在处理功能分支并且主分支已更新,则变基非常有用。您可以获得分支上的所有更新,从而防止将来发生合并冲突。交互式变基(InteractiveRebase)在对提交进行变基之前,我们可以修改它们!我们可以使用交互式变基来实现这一点。交互式变基在您当前的开发分支上以及当您想要修改某些提交时很有用。在我们rebase的提交上,我们可以执行以下6个操作:reword:修改提交信息;编辑:修改此提交;squash:将提交合并到之前的提交中;fixup:将提交合并到之前的提交中,不保留本次提交的日志信息;exec:运行我们想要在每次提交时变基的命令;删除:删除此提交。伟大的!这样我们就可以完全控制我们的提交。如果要删除提交,只需将其删除即可。如果您想将多个提交合并在一起以获得干净的提交历史,那也很好!交互式变基使你在变基时有很多控制权,甚至是当前活动的分支。重置(Resetting)当我们不想要之前提交的更改时使用这个命令。也许它是一个WIP提交或者它可能是一个引入了错误的提交,这就是应该完成gitreset的时候。gitreset允许我们不再使用当前deck上的文件,允许我们控制HEAD应该指向的位置。软重置软重置会将HEAD移动到指定的提交(或与HEAD相比的提交索引),而不会删除在该提交之后添加的更改!假设我们不想保留提交9e78i,它添加了一个style.css文件,我们也不想保留提交035cc,它添加了一个index.js文件。但是,我们确实希望保留新添加的style.css和index.js文件!这是软重置的完美用例。输入gitstatus后,您会看到我们仍然可以访问我们对之前提交所做的所有更改。太好了,这意味着我们可以修复这些文件的内容并稍后重新提交!硬重置有时我们不想保留由特定提交引入的更改。与软重置不同,我们永远不需要再次访问它们。Git应该简单地将整体状态直接重置为特定提交之前的状态:这甚至包括您在工作目录和暂存文件中的更改。Git丢弃了9e78i和035cc引入的更改,并将状态重置为ec5be。还原撤消更改的另一种方法是执行gitrevert。通过对特定提交执行还原,我们创建了一个包含还原更改的新提交。假设ec5be添加了一个index.js文件。但是后来我们发现我们真的不再需要这次提交引入的更改。然后还原ec5be提交!完美的!提交9e78i恢复由提交ec5be引入的更改。gitrevert在撤消特定提交而不修改分支历史时很有用。Cherry-picking当特定分支包含我们的活动分支需要的提交时,我们会选择该提交!当我们挑选一个提交时,我们在活动分支上创建一个新提交,其中包含由挑选的提交引入的更改。假设dev分支上的提交76d12添加了对我们想要合并到master分支中的index.js文件的更改。我们不想要整个开发分支,只想要这个提交!master分支现在包含76d12引入的更改。获取如果你有一个远程Git分支,比如GitHub上的一个分支,当远程分支包含当前分支没有的提交时,你可以使用获取。就像合并另一个分支或您的同事提出快速修复时一样。通过在这个远程分支上执行gitfetch,我们可以在本地获取这些更改。这不会以任何方式影响您的本地分支:获取只是下载新数据。现在我们可以看到自上次推送以来的所有修改。新数据也已经在本地,我们可以决定如何处理新数据。拉动虽然gitfetch可以用来为一个分支拉取远程,我们也可以做一个gitpull。gitpull实际上是两个命令合二为一:gitfetch和gitmerge。当我们从sourcepullchanges的时候,我们先像gitfetch一样fetch所有的数据,然后自动将最新的changes合并到本地分支。太好了,我们现在与远程分支完美同步并拥有所有最新更改!Reflog的每个人都会犯错,但犯错没关系!有时你可能觉得你已经完全搞砸了你的git仓库,让你想要完全删除它。gitreflog是一个非常有用的命令,它显示已执行的所有操作的日志。这包括合并、重置、还原以及基本上您对分支所做的任何更改。如果你犯了错误,你可以很容易地根据reflog提供的信息,通过重置HEAD来重做!假设我们实际上不需要合并原来的分支。当我们执行gitreflog命令时,我们可以看到这个repo在合并之前的状态是在HEAD@{1}。然后我们执行gitreset将HEAD重新指向HEAD@{1}的位置。我们可以看到最新的动作已经被推送到reflog。