原文作者:Lydia Hallie

前言

尽管 Git 是一款非常强大的工具。

我发现在使用 Git 时,在头脑里可视化地想象它会非常有用:当我执行一个特定命令时,这些分支会如何交互,又会怎样影响历史记录?

为什么当我在 master 上执行硬重启,force push 到原分支以及 rimraf 我们的 .git 文件夹时,我的同事哭了?

我觉得创建一些最常用且最有用的 Git 命令的可视化示例会是一个完美的用例!

下面我将介绍的很多命令都有可选参数——你可以使用这些参数来改变对应命令的行为。

而我的示例只会涵盖命令的默认行为,而不会添加(或添加太多)可选配置!

合并中 Merging

拥有多个分支是很方便的,以使新变更彼此分离,并确保您不会意外将未经批准或破损的变更推到生产中。

但一旦这些修改得到了批准许可,我们就可以将其部署到我们的生产分支中了!

将更改从一个分支转移到另一个分支的一种方法是执行 git mergeGit 可以执行两种类型的合并:fast-forward 和 no-fast-forward

现在这可能没有多大意义,所以让我们看一下差异!

Fast-forward(--ff

在当前分支相比于我们要合并的分支没有额外的提交(commit)时,可以执行 fast-forward 合并。

Git 很懒,首先会尝试执行最简单的选项:fast-forward!这类合并不会创建新的提交,而是会将我们正在合并的分支上的提交直接合并到当前分支。

完美!现在,我们 dev 可以在分支上获得对 master 分支所做的所有更改。

那么 no-fast-forward 又是什么意思呢?

No-fast-foward (--no-ff

如果你的当前分支相比于你想要合并的分支没有任何提交,那当然很好,但很遗憾现实情况很少如此!

如果我们在当前分支上提交我们想要合并的分支不具备的改变,那么 git 将会执行 no-fast-forward 合并。

使用 no-fast-forward 合并时,Git 会在当前活动分支上创建新的 merging commit

这个提交的父提交(parent commit)即指向这个活动分支,也指向我们想要合并的分支!

 

没什么大不了的,完美的合并!

现在,我们在 dev 分支上所做的所有改变都合并到了 master 分支上。

合并冲突 Merge Conflicts

尽管 Git 能够很好地决定如何合并分支以及如何向文件添加修改,但它并不总是能完全自己做决定。

当我们想要合并的两个分支的同一文件中的同一行代码上有不同的修改,或者一个分支删除了一个文件而另一个分支修改了这个文件时,Git 就不知道如何取舍了。

在这样的情况下,Git 会询问你想要保留哪种选择?假设在这两个分支中,我们都编辑了 README.md 的第一行。

如果我们想把 dev 合并到 master,就会出现一个合并冲突:你想要标题是 Hello! 还是 Hey!?

当尝试合并这些分支时,Git 会向你展示冲突出现的位置。

我们可以手动移除我们不想保留的修改,保存这些修改,再次添加这个已修改的文件,然后提交这些修改。

完成!尽管合并冲突往往很让人厌烦,但这是合理的:Git 不应该瞎猜我们想要保留哪些修改。

变基(Rebasing)

我们刚看到可通过执行 git merge 将一个分支的修改应用到另一个分支。

另一种可将一个分支的修改融入到另一个分支的方式是执行 git rebase

git rebase 会将当前分支的提交复制到指定的分支之上。

完美,现在我们在 dev 分支上获取了 master 分支上的所有修改。

变基与合并 有一个重大的区别:Git 不会尝试确定要保留或不保留哪些文件。我们执行 rebase 的分支总是含有我们想要保留的最新近的修改!这样我们不会遇到任何合并冲突,而且可以保留一个漂亮的、线性的 Git 历史记录。

上面这个例子展示了在 master 分支上的变基。但是,在更大型的项目中,你通常不需要这样的操作。git rebase 在为复制的提交创建新的 hash 时会修改项目的历史记录。

如果你在开发一个 feature 分支并且 master 分支已经更新过,那么变基就很好用。你可以在你的分支上获取所有更新,这能防止未来出现合并冲突。

交互式变基(Interactive Rebase)

在为提交执行变基之前,我们可以修改它们!我们可以使用交互式变基来完成这一任务。交互式变基在你当前开发的分支上以及想要修改某些提交时会很有用。

在我们正在 rebase 的提交上,我们可以执行以下 6 个动作:

  • reword:修改提交信息;
  • edit:修改此提交;
  • squash:将提交融合到前一个提交中;
  • fixup:将提交融合到前一个提交中,不保留该提交的日志消息;
  • exec:在每个提交上运行我们想要 rebase 的命令;
  • drop:移除该提交。

很棒!这样我们就能完全控制我们的提交了。如果你想要移除一个提交,只需 drop 即可。

如果你想把多个提交融合到一起以便得到清晰的提交历史,那也没有问题!

交互式变基能为你在 rebase 时提供大量控制,甚至可以控制当前的活动分支。

重置(Resetting)

当我们不想要之前提交的修改时,就会用到这个命令。也许这是一个 WIP 提交或者可能是引入了 bug 的提交,这时候就要执行 git reset

git reset 能让我们不再使用当前台面上的文件,让我们可以控制 HEAD 应该指向的位置。

软重置

软重置会将 HEAD 移至指定的提交(或与HEAD 相比的提交的索引),而不会移除该提交之后加入的修改!

假设我们不想保留添加了一个 style.css 文件的提交 9e78i,而且我们也不想保留添加了一个 index.js 文件的提交 035cc。但是,我们确实又想要保留新添加的 style.css 和 index.js 文件!这是软重置的一个完美用例。

输入 git status 后,你会看到我们仍然可以访问在之前的提交上做过的所有修改。这很好,这意味着我们可以修复这些文件的内容,之后再重新提交它们!

还原(Reverting)

另一种撤销修改的方法是执行 git revert。通过对特定的提交执行还原操作,我们会创建一个包含已还原修改的新提交。

假设 ec5be 添加了一个 index.js 文件。但之后我们发现其实我们再也不需要由这个提交引入的修改了。那就还原 ec5be 提交吧!

完美!提交 9e78i 还原了由提交 ec5be 引入的修改。在撤销特定的提交时,git revert 非常有用,同时也不会修改分支的历史。

拣选(Cherry-picking)

当一个特定分支包含我们的活动分支需要的某个提交时,我们对那个提交执行 cherry-pick!对一个提交执行 cherry-pick 时,我们会在活动分支上创建一个新的提交,其中包含由拣选出来的提交所引入的修改。

假设 dev 分支上的提交 76d12 为 index.js 文件添加了一项修改,而我们希望将其整合到 master 分支中。我们并不想要整个 dev 分支,而只需要这个提交!

现在 master 分支包含 76d12 引入的修改了。

取回(Fetching)

如果你有一个远程 Git 分支,比如在 GitHub 上的分支,当远程分支上包含当前分支没有的提交时,可以使用取回。比如当合并了另一个分支或你的同事推送了一个快速修复时。

通过在这个远程分支上执行 git fetch,我们就可在本地获取这些修改。这不会以任何方式影响你的本地分支:fetch 只是单纯地下载新的数据而已。

现在我们可以看到自上次推送以来的所有修改了。这些新数据也已经在本地了,我们可以决定用这些新数据做什么了。

拉取(Pulling)

尽管 git fetch 可用于获取某个分支的远程信息,但我们也可以执行 git pullgit pull 实际上是两个命令合成了一个:git fetch 和 git merge。当我们从来源拉取修改时,我们首先是像 git fetch 那样取回所有数据,然后最新的修改会自动合并到本地分支中。

很好,我们现在与远程分支完美同步了,并且也有了所有最新的修改!

Reflog

每个人都会犯错,但犯错其实没啥!有时候你可能感觉你把 git repo 完全搞坏了,让你想完全删了了事。

git reflog 是一个非常有用的命令,可以展示已经执行过的所有动作的日志。包括合并、重置、还原,基本上包含你对你的分支所做的任何修改。

如果你犯了错,你可以根据 reflog 提供的信息通过重置 HEAD 来轻松地重做!

假设我们实际上并不需要合并原有分支。当我们执行 git reflog 命令时,我们可以看到这个 repo 的状态在合并前位于 HEAD@{1}。那我们就执行一次 git reset,将 HEAD 重新指向在 HEAD@{1} 的位置。

我们可以看到最新的动作已被推送给 reflog


Git有很多有用强大的命令,我希望我能掌握所有!

我知道我现在还没有介绍其他有用的命令:让我知道您最喜欢/最有用的命令是什么,我可能会在另一篇文章中介绍它们!

和往常一样,随时与我联系!

动画图解 Git 的 10 大命令的更多相关文章

  1. 动画图解Git命令

    ​Git是一个开源的分布式版本控制系统,可以有效.高速的处理从很小到非常大的项目版本管理,是目前使用范围最广的版本管理工具 尽管Git是一个非常强大的工具,但我认为大多数人都会同意我的说法,即它也可以 ...

  2. 【】(Git)用动图展示10大Git命令

    1.说明 git merge.git rebase.git reset.git revert.git fetch.git pull.git reflog-- 你知道这些 git 命令执行的究竟是什么任 ...

  3. [git]图解git常用命令

    本文图解git中最常用的命令.如果你稍微理解git的工作原理,这篇文章能够让你理解的更透彻. 基本用法 约定 命令详解 Diff Commit Checkout Detached HEAD(匿名分支提 ...

  4. 图解Git命令【转】

    本文转载自:https://github.com/geeeeeeeeek/git-recipes/wiki/4.1-%E5%9B%BE%E8%A7%A3Git%E5%91%BD%E4%BB%A4 此页 ...

  5. 10大炫酷的HTML5文字动画特效欣赏

    文字是网页中最基本的元素,在CSS2.0时代,我们只能在网页上展示静态的文字,只能改变他的大小和颜色,显得枯燥无味.随着HTML5的发展,现在网页中的文字样式变得越来越丰富了,甚至出现了文字动画,HT ...

  6. 图解git中的最常用命令

    图解git中的最常用命令 Git命令参考手册(文本版) git init                                                  # 初始化本地git仓库(创 ...

  7. Git仓库删除大文件

    Git仓库删除大文件 背景 当用Git久了,难免会手误或临时添加一些大文件到仓库中,即使以后添加进了.gitignore,甚至做了git rm,但是Git为了保证版本可回退,history pack里 ...

  8. 2018年值得关注的10大JavaScript动画库

    2018年值得关注的10大JavaScript动画库 旭日云中竹 前端早读课 1周前 前言 平时大家开发动画是采用什么方式呢?虽然18年过半,可这十个动画库是真的没听过几个,有点尴尬.今日早读文章由@ ...

  9. 10大H5前端框架(转)

    10大H5前端框架 作为一名做为在前端死缠烂打6年并且懒到不行的攻城士,这几年我还是阅过很多同门从知名到很知名的各种前端框架,本来想拿15-20个框架来分享一下,但在跟几个前辈讨教写文章的技巧时果断被 ...

  10. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

随机推荐

  1. GPS北斗卫星时钟同步系统提升电信支撑网性能

    GPS北斗卫星时钟同步系统提升电信支撑网性能 京准科技提供参考--更多资料VX(ahjzsz) 各项新的数据业务,如电子商务.多媒体通信.IP电话等都是电信业务发展的新增长点,而传统业务也存在多家企业 ...

  2. Win10打开Autodesk软件时提示“管理员已阻止你运行此应用”

    Win10用户的最大困扰就是系统的安全性太高,导致很多软件在运行时总是会报错,这不,又有同学遇到了下面的问题: 当你的电脑跳出这么鲜红的界面你是不是很想砸了它....手下留脑~它还能再奋斗两年. 出现 ...

  3. (0524) rbf 格式 (intel)

    http://blog.chinaaet.com/yuwoo/p/5100049901 https://blog.csdn.net/qq_38531460/article/details/107066 ...

  4. Django操作mongo数据库二(MongoClient方式)

    一.基本环境 1.开发环境: Python环境:Python 3.8.16 Django环境:4.1 2.需要安装的包 pip install pymongo pip install mongoeng ...

  5. php textarea根据回车转换成数组

    $val是textarea文本框的内容 假如是:张三/32岁/男 李四/28岁/男 $arr=explode("\n",$val); $arr2 = array(); foreac ...

  6. Centos SSH 免密操作

    1. 在本机生成公钥+私钥      ssh-keygen -t rsa 2. 发送密钥到目标服务器      ssh-copy-id root@192.168.137.111 3.尝试登录目标服务器 ...

  7. py13函数迭代器与生成器

    """什么是迭代器 迭代:更新换代(重复)的过程,每次的迭代都必须基于上一次的结果 迭代器:迭代取值的工具 为什么要用 迭代器给你提供了一种不依赖于索引取值的方式 如何用 ...

  8. Jenkins拉取GitHub上代码

    1.github 生成 Personal Access Token 2.github 设置 GitHub webhooks (具体需要持续集成的项目),新建或者设置现有项目的 webhooks 选项, ...

  9. The first python article

    Smile is the most beautiful language! and Python so on !

  10. 《Python深度学习》《卷积神经网络的可视化》精读

    对于大多数深度学习模型,模型学到的表示都难以用人类可以理解的方式提取和呈现.但对于卷积神经网络来说,我们可以很容易第提取模型学习到的表示形式,并以此加深对卷积神经网络模型运作原理的理解. 这篇文章的内 ...