iOS架构设计iOS面试题汇总工具使用

面试技巧攻克-Git问题

2019-11-20  本文已影响0人  iOS大蝠

一、基础部分

1、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)做这个操作。

回答关键点:

二、GitFlow 基本流程和你的理解

1、什么是GitFlow?

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

名称 说明

GitFlow 的优势有如下几点:

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



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



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

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

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



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

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

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


考察关键点
回答关键点

2、解释下 PR 和 MR 的区别

PR 和 MR 的全称分别是 pull request 和 merge request。解释它们两者的区别之前,我们需要先了解一下 Code Review,因为 PR 和 MR 的引入正是为了进行 Code Review。

Code Review 是指在开发过程中,对代码的系统性检查。通常的目的是查找系统缺陷,保证代码质量和提高开发者自身水平。 Code Review 是轻量级代码评审,相对于正式代码评审,轻量级代码评审所需要的各种成本要明显低的多,如果流程正确,它可以起到更加积极的效果。

进行 Code Review 的原因:

提高代码质量

然后我们需要了解下 fork 和 branch,因为这是 PR 和 MR 各自所属的协作流程。

fork 是 git 上的一个协作流程。通俗来说就是把别人的仓库备份到自己仓库,修修改改,然后再把修改的东西提交给对方审核,对方同意后,就可以实现帮别人改代码的小目标了。fork 包含了两个流程:

和 fork 不同,branch 并不涉及其他的仓库,操作都在当前仓库完成。



所以 PR 和 MR 的最大区别就在于此。

考察关键点:

回答关键点:
回答这个问题的时候不要单单只说它们的区别。而是要从 PR 和 MR 产生的原因,分析它们所属的流程,然后再得出两者的区别。

三、进阶部分

1、### 讲一讲你知道的 githooks

githooks 是指 git 在执行某些特定操作时会触发的一系列程序,有点类似数据库中的触发器,由用户编写。默认情况下,这些程序都被放置在 $GIT_DIR/hooks 目录下,当然,我们也可以通过 git 的环境配置变量 core.hooksPath 来改变这个目录。

githooks 的类型有很多中,这些 hook 会在各个特定操作时帮你自动完成一些你想要做的操作,比如:在提交代码到 develop 分支的时候自动打包。

下面是目前支持的 githooks 列表:

2、### git rebase vs git merge vs git cherry pick

首先,我们需要了解一下这三个指令的意义:协同开发时往往每个人都会新建自己的分支去做开发,然后再合并到公共分支。因为我们不提倡在公共分支解决冲突,所以这时候就涉及到把别人合并到公共分支的 commit 合并到自己分支了。而这三个指令,就可以帮你完成分支合并的操作。

然后,我们要了解这三个指令是怎么做的:

注意:一旦分支中的 commit 对象已经发布到公共仓库,就千万不要对该分支进行 rebase 操作,因为 rebase 是生成了新的 commit,这样其他人就需要重新再 rebase 一次…

3、如果工程中有些文件不需要上传远端,该怎么处理?

这个问题考察的是对 .gitignore 的理解。

.gitignore 是配置在仓库根目录下的一个文件,作用是用来把一些文件忽略,让 git 不要跟踪这些文件。

注意:如果你想把一个已经被跟踪的文件 ignore 掉,这是时候新增的规则并不会对这个文件产生作用,你需要先用下面的指令把这个文件设置为不跟踪:

 git rm --cached FILENAME

下面是 .gitignore 文件的基本语法:

然后是一些官方建议的 gitignore 例子:https://github.com/github/gitignore,请自取。

回答关键点

4、.git 目录下面都维护了一些什么信息

大家对这个目录应该不太陌生,但是应该很少有人会去探究这个目录下的内容,但是如果一旦清楚的了解过 .git 目录下的内容,你对 git 各个操作的细节会更加了解。

首先我们来看一下某个仓库 .git 目录下的内容:

.
├── COMMIT_EDITMSG
├── FETCH_HEAD
├── HEAD
├── config
├── description
├── hooks
│ └── README.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ ├── heads
│ │ ├── develop
│ │ └── master
│ └── remotes
│ └── origin
│ ├── develop
│ └── master
├── objects
│ ├── 01
│ │ ├── 50a03f535237397e5c16fbd4e96f79886889e0
│ │ └── 71e32dd777e045b27923657a58328becd66b56
│ ├── info
│ └── pack
├── refs
│ ├── heads
│ │ ├── develop
│ │ └── master
│ ├── remotes
│ │ └── origin
│ │ ├── develop
│ │ └── master
│ └── tags
└── sourcetreeconfig
这些文件的作用如下:

COMMIT_EDITMSG:保存最近一次 commit message 提供给用户使用;
FETCH_HEAD:保存本地的 FETCH_HEAD 记录,用于 git fetch 时和远程仓库的版本号做对比;
HEAD:这个文件包含了一个当前 branch 的引用,通过这个文件 git 可以得到下一次 commit 的parent;
config:当前仓库的 git 配置文件;
description:仓库的描述信息,主要给 gitweb 等 git 托管系统使用;
hooks:这个目录存放一些 shell 脚本,可以设置特定的git命令后触发相应的脚本;
index:这个文件就是暂存区(stage),是一个二进制文件;
info:当前仓库的一些信息,里面有一个 exclude 文件,记录了被 .gitignore 忽略的文件;
logs:保存所有的更新引用记录,里面的 refs 文件夹,分文件记录了各个分支的更新引用记录;
objects:该目录存放所有的 git 对象,对象的 SHA1 哈希值的前 2 位是文件夹名称,后 38 位是对象文件名。
refs:具体的引用,Reference Specification,这个目录一般包括三个子文件夹,heads、remotes和 tags,比如,heads 中的 master 文件标识了当前仓库 master 分支指向的当前 commit,以此类推;
sourcetreeconfig:Source Tree 的配置信息。

上一篇 下一篇

猜你喜欢

热点阅读