面试中可能问到的Git问题
坤坤 Lv2
  • 团队协作能力一直是我们招聘开发人员的重要考核指标之一。而考核这个能力的原因很简单:一般公司都不会只有一个开发…而一旦涉及多人协作开发,良好的协作能力和习惯能显著提高整个团队的开发效率。Time is money!

  • 说到协作,面试中当然就会聊到开发人员日常最需要协作的事情,代码协作。因为 Github 在国内的流行,很多公司都已经把代码托管到 Github 或者内部的 git 服务上,所以大家也慢慢把 git 技能的考察引入到面试中。

  • 下面就分享一些笔者个人整理的 git 相关问题以及解析。

基础部分

平时都用什么Git工具?

命令行:只能说十个里面九个菜,还有一个是大神,虽然命令行提供了全部的功能,但是很多用 GUI 工具可以很便捷解决的问题,命令行做起来都比较麻烦。当然并不是让大家不要去命令行,通过命令行可以对 git 的功能和原理有一个更深入的了解。

由于命令行上手较慢,所以我们通常会用一些第三方 GUI 工具来提高我们 git 仓库管理的效率:

  • 作为Java开发,接触最多的当然是Intellij IDEA,内置了 Git 的功能。它是真的好用,只需简单配置,即可轻松使用。
  • SourceTree:笔者日常使用的一个图形化的 git 增强工具,而最好用的功能就在于它集成了 GitFlow,让开发者可以更简单、更规范的去做一些 git 操作;另外它还提供了更友好的 merge 界面,但是操作起来不是很顺手,因为它只支持整行删除;

SourceTree

  • SmartGit:

SmartGit

  • Atom:Atom 本身并不是专门用来做 git 管理的工具,而是一个支持多种开发语言的开源 IDE。提到它的原因是 merge-conflicts, 这个插件提供的 merge 界面,要比 SourceTree 的更好用,Atom 会在当前内容的基础上,把有冲突的部分直接对比标示出来,开发人员可以像编辑普通文本一样在标示的区域内直接进行修改,并最终选择自己满意的那个部分作为 merge 之后的内容。

  • VSCode:如同Atom一样,VSCode生来就内置了基本的Git工具,日常的操作基本可以通过页面简单的操作来完成。

VSCode

而且配合其插件Git Lens,在写作开发中更是得心应手。它能让你清楚的知道文件的每一行是由谁改动的,是不是很强大。

VSCode

git add 和 git stage 有什么区别

在回答这个问题之前需要先了解 git 仓库的三个组成部分:工作区(Working Directory)、暂存区(Stage)和历史记录区(History):

  • 工作区:在 git 管理下的正常目录都算是工作区,我们平时的编辑工作都是在工作区完成;
  • 暂存区:临时区域。里面存放将要提交文件的快照;
  • 历史记录区:git commit 后的记录区。

然后是这三个区的转换关系以及转换所使用的命令:

然后我们就可以来说一下 git add 和 git stage 了。其实,他们两是同义的,所以,惊不惊喜,意不意外?这个问题竟然是个陷阱…引入 git stage 的原因其实比较有趣:是因为要跟 svn add 区分,两者的功能是完全不一样的,svn add 是将某个文件加入版本控制,而 git add 则是把某个文件加入暂存区,因为在 git 出来之前大家用 svn 比较多,所以为了避免误导,git 引入了git stage,然后把 git diff –staged 做为 git diff –cached 的相同命令。基于这个原因,我们建议使用 git stage 以及 git diff –staged。

考察关键点:

对 git 工作区(Working Directory)、暂存区(Stage)和历史记录区(History)以及转换关系的了解;
对 git add 和 git stage 的了解。

回答关键点:

工作区(Working Directory)、暂存区(Stage)和历史记录区(History)以及转换关系不能少;
git stage 是 git add 的同义指令;
我用 git stage。

git reset、git revert 和 git checkout 有什么区别

这个问题同样也需要先了解 git 仓库的三个组成部分:工作区(Working Directory)、暂存区(Stage)和历史记录区(History)。

首先是它们的共同点:用来撤销代码仓库中的某些更改。

然后是不同点:

首先,从 commit 层面来说:

  • git reset 可以将一个分支的末端指向之前的一个 commit。然后再下次 git 执行垃圾回收的时候,会把这个 commit 之后的 commit 都扔掉。git reset 还支持三种标记,用来标记 reset

    • –mixed:会影响到暂存区和历史记录区。也是默认选项;
    • –soft:只影响历史记录区;
    • –hard:影响工作区、暂存区和历史记录区。

注意:因为 git reset 是直接删除 commit 记录,从而会影响到其他开发人员的分支,所以不要在公共分支(比如 develop)做这个操作。

  • git checkout 可以将 HEAD 移到一个新的分支,并更新工作目录。因为可能会覆盖本地的修改,所以执行这个指令之前,你需要 stash 或者 commit 暂存区和工作区的更改。

  • git revert 和 git reset 的目的是一样的,但是做法不同,它会以创建新的 commit 的方式来撤销 commit,这样能保留之前的 commit 历史,比较安全。另外,同样因为可能会覆盖本地的修改,所以执行这个指令之前,你需要 stash 或者 commit 暂存区和工作区的更改。
    然后,从文件层面来说:

  • git reset 只是把文件从历史记录区拿到暂存区,不影响工作区的内容,而且不支持 –mixed、–soft 和 –hard。

  • git checkout 则是把文件从历史记录拿到工作区,不影响暂存区的内容。

  • git revert 不支持文件层面的操作。

    回答关键点:

  • 对于 commit 层面和文件层面,这三个指令本身功能差别很大。

  • git revert 不支持文件层面的操作。

  • 不要在公共分支做 git reset 操作。

GitFlow 基本流程和你的理解

GitFlow 是由 Vincent Driessen 提出的一个 git操作流程标准。包含如下几个关键分支:

名 称 说 明
master 主分支
develop 主开发分支,包含确定即将发布的代码
feature 新功能分支,一般一个新功能对应一个分支,对于功能的拆分需要比较合理,以避免一些后面不必要的代码冲突
release 发布分支,发布时候用的分支,一般测试时候发现的 bug 在这个分支进行修复
hotfix hotfix 分支,紧急修 bug 的时候用

GitFlow 的优势有如下几点:

  • 并行开发:GitFlow 可以很方便的实现并行开发:每个新功能都会建立一个新的 feature 分支,从而和已经完成的功能隔离开来,而且只有在新功能完成开发的情况下,其对应的 feature 分支才会合并到主开发分支上(也就是我们经常说的 develop 分支)。另外,如果你正在开发某个功能,同时又有一个新的功能需要开发,你只需要提交当前 feature 的代码,然后创建另外一个 feature 分支并完成新功能开发。然后再切回之前的 feature 分支即可继续完成之前功能的开发。
  • 协作开发:GitFlow 还支持多人协同开发,因为每个 feature 分支上改动的代码都只是为了让某个新的 feature 可以独立运行。同时我们也很容易知道每个人都在干啥。
  • 发布阶段:当一个新 feature 开发完成的时候,它会被合并到 develop 分支,这个分支主要用来暂时保存那些还没有发布的内容,所以如果需要再开发新的 feature,我们只需要从 develop 分支创建新分支,即可包含所有已经完成的 feature 。
  • 支持紧急修复:GitFlow 还包含了 hotfix 分支。这种类型的分支是从某个已经发布的 tag 上创建出来并做一个紧急的修复,而且这个紧急修复只影响这个已经发布的 tag,而不会影响到你正在开发的新 feature。

然后就是 GitFlow 最经典的几张流程图,一定要理解:

GitFlow
feature 分支都是从 develop 分支创建,完成后再合并到 develop 分支上,等待发布。

GgitFlow
当需要发布时,我们从 develop 分支创建一个 release 分支

GitFlow
然后这个 release 分支会发布到测试环境进行测试,如果发现问题就在这个分支直接进行修复。在所有问题修复之前,我们会不停的重复发布->测试->修复->重新发布->重新测试这个流程。

发布结束后,这个 release 分支会合并到 develop 和 master 分支,从而保证不会有代码丢失。

GitFlow
master 分支只跟踪已经发布的代码,合并到 master 上的 commit 只能来自 release 分支和 hotfix 分支。

hotfix 分支的作用是紧急修复一些 Bug。

它们都是从 master 分支上的某个 tag 建立,修复结束后再合并到 develop 和 master 分支上。

GitFlow

考察关键点

  • GitFlow 包含的分支类型和功能;

  • GitFlow 的优势;

  • 对 GitFlow feature、release、hotfix 流程的理解。

    回答关键点

  • GitFlow 的基本内容以及优势;

  • 对于 feature 流程,都是从 develop 分支发起,然后通过 PR/MR 的方式合并回 develop 分支;

  • 对于 release 流程,则是要注意几点:

    • 如果 release 分支上有 bug 需要修复,直接在 release 分支上完成;
    • release 分支上的 bug 修复要持续通过 PR/MR 的方式合并回 develop 分支;
    • 最后确认发版的时候才把 release 分支直接合并到 master 分支。
  • 对于 hotfix 流程,则是要注意几点:

    • 从 master 分支发起;
    • 修复完要同时合并到 develop 和 master。
  • Post title:面试中可能问到的Git问题
  • Post author:坤坤
  • Create time:2017-10-23 16:49:50
  • Post link:https://is908.github.io/2017/10/23/git-learn/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.