Git⾯试真题(10题)

作者 : admin 本文共14136个字,预计阅读时间需要36分钟 发布时间: 2024-06-9 共3人阅读

目录

1. 说说你对版本管理的理解?常⽤的版本管理⼯具有哪些?

1.1. 是什么

1.2. 有哪些

1.2.1. 本地版本控制系统

1.2.2. 集中式版本控制系统

1.2.3. SVN

1.2.4. CVS

2. 说你对Git的理解?

2.1. 是什么

2.2. ⼯作原理

3. 说说Git常⽤的命令有哪些?

4. 说说Git 中 HEAD、⼯作树和索引之间的区别?

5. 说说 git 发⽣冲突的场景?如何解决?

6. 说说Git中 fork, clone,branch这三个概念,有什么区

7. 说说对git pull 和 git fetch 的理解?有什么区别?

8.说说你对git rebase 和 git merge的理解?区别?

9. 说说你对git reset 和 git revert 的理解?区别?9.1. 是什么

10. 说说你对git stash 的理解?应⽤场景?


1. 说说你对版本管理的理解?常⽤的版本管理⼯具有哪些?

1.1. 是什么

版本控制(Version control),是维护⼯程蓝图的标准作法,能追踪⼯程蓝图从诞⽣⼀直到定案的过 程。此外,版本控制也是⼀种软件⼯程技巧,借此能在软件开发的过程中,确保由不同⼈所编辑的同⼀ 程序⽂件都得到同步

透过⽂档控制,能记录任何⼯程项⽬内各个模块的改动历程,并为每次改动编上序号

⼀种简单的版本控制形式如下:赋给图的初版⼀个版本等级“A”。当做了第⼀次改变后,版本等级改 为“B”,以此类推 版本控制能提供项⽬的设计者,将设计恢复到之前任⼀状态的选择权。简⾔之,你的修改只要提到到版本控制系统,基本都可以找回,版本控制系统就像⼀台时光机器,可以

让你回到任何⼀个时间点

1.2. 有哪些

1
版本控制系统在当今的软件开发中,被认为是理所当然的配备⼯具之⼀,根据类别可以分成:


本地版本控制系统


集中式版本控制系统


分布式版本控制系统

1.2.1. 本地版本控制系统

结构如下图所示:

优点:


简单,很多系统中都有内置


适合管理⽂本,如系统配置

缺点:


其不⽀持远程操作,因此并不适合多⼈版本开发

1.2.2. 集中式版本控制系统

结构如下图所示:

优点:


适合多⼈团队协作开发


代码集中化管理

缺点:


单点故障


必须联⽹,⽆法单机⼯作

代表⼯具有
SVN

CVS

1.2.3. SVN

TortoiseSVN
是⼀款⾮常易于使⽤的跨平台的 版本控制/版本控制/源代码控制软件

1.2.4. CVS

CVS
是版本控制系统,是源配置管理(SCM)的重要组成部分。使⽤它,您可以记录源⽂件和⽂档的历史记录。⽼牌的版本控制系统,它是基于客户端/服务器的⾏为使得其可容纳多⽤户,构成⽹络也很⽅便。这⼀特性使得 CVS
成为位于不同地点的⼈同时处理数据⽂件(特别是程序的源代码)时的⾸

1.2.4.1.
分布式版本控制系统

结构如下图:

优点:


适合多⼈团队协作开发


代码集中化管理

可以离线⼯作

每个计算机都是⼀个完整仓库

分布式版本管理系统每个计算机都有⼀个完整的仓库,可本地提交,可以做到离线⼯作,则不⽤像集中管理那样因为断⽹情况⽽⽆法⼯作代表⼯具为 Git
、 HG:

Git
是⽬前世界上最先进的分布式版本控制系统,旨在快速⾼效地处理从⼩型到⼤型项⽬的所有事务

特性:易于学习,占⽤内存⼩,具有闪电般快速的性能

使⽤
Git

Gitlab
搭建版本控制环境是现在互联⽹公司最流⾏的版本控制⽅式

Mercurial
是⼀个免费的分布式源代码管理⼯具。它可以有效地处理任何规模的项⽬,并提供简单直 观的界⾯

Mercurial
是⼀种轻量级分布式版本控制系统,采⽤
Python
语⾔实现,易于学习和使⽤,扩展性

强 版本控制系统的优点如下:

记录⽂件所有历史变化,这是版本控制系统的基本能⼒

随时恢复到任意时间点,历史记录功能使我们不怕改错代码了

⽀持多功能并⾏开发,通常版本控制系统都⽀持分⽀,保证了并⾏开发的可⾏

多⼈协作并⾏开发,对于多⼈协作项⽬,⽀持多⼈协作开发的版本管理将事半功倍

2. 说你对Git的理解?

2.1. 是什么

git,是⼀个分布式版本控制软件,最初⽬的是为更好地管理
Linux
内核开发⽽设计

分布式版本控制系统的客户端并不只提取最新版本的⽂件快照,⽽是把代码仓库完整地镜像下来。这么 ⼀来,任何⼀处协同⼯作⽤的服务器发⽣故障,事后都可以⽤任何⼀个镜像出来的本地仓库恢复
项⽬开始,只有⼀个原始版仓库,别的机器可以 clone
这个原始版本库,那么所有
clone
的机器, 它们的版本库其实都是⼀样的,并没有主次之分 所以在实现团队协作的时候,只要有⼀台电脑充当服务器的⻆⾊,其他每个⼈都从这个“服务器”仓库 cl

one
⼀份到⾃⼰的电脑上,并且各⾃把各⾃的提交推送到服务器仓库⾥,也从服务器仓库中拉取别⼈的 提交 github 实际就可以充当这个服务器⻆⾊,其是⼀个开源协作社区,提供
Git
仓库托管服务,既可以 让别⼈参与你的开源项⽬,也可以参与别⼈的开源项⽬

2.2. ⼯作原理

当我们通过
git init
创建或者
git clone
⼀个项⽬的时候,项⽬⽬录会隐藏⼀个
.git
⼦⽬录,

其作⽤是⽤来跟踪管理版本库的

Git
中所有数据在存储前都计算校验和,然后以校验和来引⽤,所以在我们修改或者删除⽂件的时

候,
git
能够知道

Git
⽤以计算校验和的机制叫做 SHA-1 散列(hash,哈希), 这是⼀个由 40 个⼗六进制字符(0-

9 和 a-f)组成字符串,基于 Git 中⽂件的内容或⽬录结构计算出来,如下:

当我们修改⽂件的时候,
git
就会修改⽂件的状态,可以通过
git status
进⾏查询,状态情况如

下:

已修改(modified):表示修改了⽂件,但还没保存到数据库中。

已暂存(staged):表示对⼀个已修改⽂件的当前版本做了标记,使之包含在下次提交的快照中。

已提交(committed):表示数据已经安全的保存在本地数据库中。

⽂件状态对应的,不同状态的⽂件在
Git
中处于不同的⼯作区域,主要分成了四部分:

⼯作区:相当于本地写代码的区域,如 git clone ⼀个项⽬到本地,相当于本地克隆了远程仓库项⽬

的⼀个副本

暂存区:暂存区是⼀个⽂件,保存了下次将提交的⽂件列表信息,⼀般在 Git 仓库⽬录中

本地仓库:提交更新,找到暂存区域的⽂件,将快照永久性存储到 Git 本地仓库

远程仓库:远程的仓库,如 github

LaTeX

复制代码
2.3.
命令

从上图可以看到,
git
⽇常简单的使⽤就只有上图6个命令:


add


commit


push


pull


clone


checkout

3. 说说Git常⽤的命令有哪些?

3.1.
前⾔

git
的操作可以通过命令的形式如执⾏,⽇常使⽤就如下图6个命令即可

9
实际上,如果想要熟练使⽤,超过60多个命令需要了解,下⾯则介绍下常⻅的的
git
命令

3.2.
有哪些

3.3.
配置

Git
⾃带⼀个
git config
的⼯具来帮助设置控制
Git
外观和⾏为的配置变量,在我们安装完

git
之后,第⼀件事就是设置你的⽤户名和邮件地址

后续每⼀个提交都会使⽤这些信息,它们会写⼊到你的每⼀次提交中,不可更改

设置提交代码时的⽤户信息命令如下:


git config [–global] user.name “[name]”


git config [–global] user.email “[email address]”

3.3.1.
启动

⼀个
git
项⽬的初始有两个途径,分别是:


git init [project-name]:创建或在当前⽬录初始化⼀个git代码库


git clone url:下载⼀个项⽬和它的整个代码历史

3.3.2.
⽇常基本操作

在⽇常⼯作中,代码常⽤的基本操作如下:


git init 初始化仓库,默认为 master 分⽀


git add . 提交全部⽂件修改到缓存区


git add 提交某些⽂件到缓存区


git diff 查看当前代码 add后,会 add 哪些内容


git diff –staged查看现在 commit 提交后,会提交哪些内容


git status 查看当前分⽀状态


git pull 拉取远程仓库的分⽀与本地当前分⽀合并


git pull : 拉取远程仓库的分⽀与本地某个分⽀合并


git commit -m “” 提交代码到本地仓库,并写提交注释


git commit -v 提交时显示所有diff信息

10

git commit –amend [file1] [file2] 重做上⼀次commit,并包括指定⽂件的新变化

关于提交信息的格式,可以遵循以下的规则:


feat: 新特性,添加功能


fix: 修改 bug


refactor: 代码重构


docs: ⽂档修改


style: 代码格式修改, 注意不是 css 修改


test: 测试⽤例修改


chore: 其他修改, ⽐如构建流程, 依赖管理

3.3.3.
分⽀操作


git branch 查看本地所有分⽀


git branch -r 查看远程所有分⽀


git branch -a 查看本地和远程所有分⽀


git merge 合并分⽀


git merge –abort 合并分⽀出现冲突时,取消合并,⼀切回到合并前的状态


git branch 基于当前分⽀,新建⼀个分⽀


git checkout –orphan 新建⼀个空分⽀(会保留之前分⽀的所有⽂件)


git branch -D 删除本地某个分⽀


git push : 删除远程某个分⽀


git branch 从提交历史恢复某个删掉的某个分⽀


git branch -m 分⽀更名


git checkout 切换到本地某个分⽀


git checkout / 切换到线上某个分⽀


git checkout -b 把基于当前分⽀新建分⽀,并切换为这个分⽀

3.3.4.
远程同步

远程操作常⻅的命令:


git fetch [remote] 下载远程仓库的所有变动


git remote -v 显示所有远程仓库


git pull [remote] [branch] 拉取远程仓库的分⽀与本地当前分⽀合并

11

git fetch 获取线上最新版信息记录,不合并


git push [remote] [branch] 上传本地指定分⽀到远程仓库


git push [remote] –force 强⾏推送当前分⽀到远程仓库,即使有冲突


git push [remote] –all 推送所有分⽀到远程仓库

3.3.5.
撤销


git checkout [file] 恢复暂存区的指定⽂件到⼯作区


git checkout [commit] [file] 恢复某个commit的指定⽂件到暂存区和⼯作区


git checkout . 恢复暂存区的所有⽂件到⼯作区


git reset [commit] 重置当前分⽀的指针为指定commit,同时重置暂存区,但⼯作区不变


git reset –hard 重置暂存区与⼯作区,与上⼀次commit保持⼀致


git reset [file] 重置暂存区的指定⽂件,与上⼀次commit保持⼀致,但⼯作区不变


git revert [commit] 后者的所有变化都将被前者抵消,并且应⽤到当前分⽀

reset
:真实硬性回滚,⽬标版本后⾯的提交记录全部丢失了

revert
:同样回滚,这个回滚操作相当于⼀个提价,⽬标版本后⾯的提交记录也全部都有

3.3.6.
存储操作

你正在进⾏项⽬中某⼀部分的⼯作,⾥⾯的东⻄处于⼀个⽐较杂乱的状态,⽽你想转到其他分⽀上进⾏

⼀些⼯作,但⼜不想提交这些杂乱的代码,这时候可以将代码进⾏存储


git stash 暂时将未提交的变化移除


git stash pop 取出储藏中最后存⼊的⼯作状态进⾏恢复,会删除储藏


git stash list 查看所有储藏中的⼯作


git stash apply 取出储藏中对应的⼯作状态进⾏恢复,不会删除储藏


git stash clear 清空所有储藏中的⼯作


git stash drop 删除对应的某个储藏

3.4.
总结

git
常⽤命令速查表如下所示:

4. 说说Git 中 HEAD、⼯作树和索引之间的区别?

4.1.
HEAD

13
14


git
中,可以存在很多分⽀,其本质上是⼀个指向
commit
对象的可变指针,⽽
Head
是⼀个特

别的指针,是⼀个指向你正在⼯作中的本地分⽀的指针

简单来讲,就是你现在在哪⼉,HEAD 就指向哪⼉

例如当前我们处于
master
分⽀,所以
HEAD
这个指针指向了
master
分⽀指针

然后通过调⽤
git checkout test
切换到
test
分⽀,那么

HEAD
则指向
test
分⽀,如下图:
15

但我们在
test
分⽀再⼀次
commit
信息的时候,
HEAD
指针仍然指向了
test
分⽀指针,⽽
tes

t
分⽀指针已经指向了最新创建的提交,如下图:

这个
HEAD
存储的位置就在
.git/HEAD
⽬录中,查看信息可以看到

HEAD
指向了另⼀个⽂件
16

这个⽂件的内容是⼀串哈希码,⽽这个哈希码正是
master
分⽀上最新的提交所对应的哈希码

所以,当我们切换分⽀的时候,
HEAD
指针通常指向我们所在的分⽀,当我们在某个分⽀上创建新的提

交时,分⽀指针总是会指向当前分⽀的最新提交

所以,HEAD指针 ——–> 分⽀指针 ——–> 最新提交


Git
管理下,⼤家实际操作的⽬录被称为⼯作树,也就是⼯作区域

在数据库和⼯作树之间有索引,索引是为了向数据库提交作准备的区域,也被称为暂存区域

Git
在执⾏提交的时候,不是直接将⼯作树的状态保存到数据库,⽽是将设置在中间索引区域的状态

保存到数据库

因此,要提交⽂件,⾸先需要把⽂件加⼊到索引区域中。

所以,凭借中间的索引,可以避免⼯作树中不必要的⽂件提交,还可以将⽂件修改内容的⼀部分加⼊索

引区域并提交

4.2.
⼯作树和索引

$ cat .git/HEAD

ref: refs/heads/master

$ cat .git/refs/heads/master

7406a10efcc169bbab17827aeda189aa20376f7f

1

2

3

4

5

Plain Text

复制代码
17

从所在的位置来看:

HEAD 指针通常指向我们所在的分⽀,当我们在某个分⽀上创建新的提交时,分⽀指针总是会指向

当前分⽀的最新提交

⼯作树是查看和编辑的(源)⽂件的实际内容

索引是放置你想要提交给 git仓库⽂件的地⽅,如⼯作树的代码通过 git add 则添加到 git 索引中,

通过git commit 则将索引区域的⽂件提交到 git 仓库中

⼀般情况下,出现分⽀的场景有如下:

多个分⽀代码合并到⼀个分⽀时

多个分⽀向同⼀个远端分⽀推送

具体情况就是,多个分⽀修改了同⼀个⽂件(任何地⽅)或者多个分⽀修改了同⼀个⽂件的名称

如果两个分⽀中分别修改了不同⽂件中的部分,是不会产⽣冲突,直接合并即可

应⽤在命令中,就是
push

pull

stash

rebase
等命令下都有可能产⽣冲突情况,从本质

上来讲,都是
merge

patch
(应⽤补丁)时产⽣冲突

4.3.
区别

5. 说说 git 发⽣冲突的场景?如何解决?

5.1.
是什么


18

在本地主分值
master
创建⼀个
a.txt
⽂件,⽂件起始位置写上
master commit
,如下:

然后提交到仓库:

git add a.txt

git commit -m ‘master first commit’

创建⼀个新的分⽀
featurel1
分⽀,并进⾏切换,如下:

然后修改
a.txt
⽂件⾸⾏⽂字为
featurel commit
,然后添加到暂存区,并开始进⾏提交到仓

库:

git add a.txt

git commit -m ‘featurel first change’

然后通过
git checkout master
切换到主分⽀,通过
git merge
进⾏合并,发现不会冲突

此时
a.txt
⽂件的内容变成
featurel commit
,没有出现冲突情况,这是因为
git
在内部发⽣

了快速合并

如果此时切换到
featurel
分⽀,将⽂件的内容修改成
featrue second commit
,然后提交到本

地仓库

然后切换到主分⽀,如果此时在
a.txt
⽂件再次修改,修改成
mastet second commit
,然后再

次提交到本地仓库

此时,
master
分⽀和
feature1
分⽀各⾃都分别有新的提交,变成了下图所示:

5.2.
分析

如果当前分⽀的每⼀个提交(commit)都已经存在另⼀个分⽀⾥了,git 就会执⾏⼀个“快速向前”(fast

forward)操作

git 不创建任何新的提交(commit),只是将当前分⽀指向合并进来的分⽀

git checkout -b featurel1

1

Plain Text

复制代码
这种情况下,⽆法执⾏快速合并,只能试图把各⾃的修改合并起来,但这种合并就可能会有冲突

现在通过
git merge featurel
进⾏分⽀合并,如下所示:

从冲突信息可以看到,
a.txt
发⽣冲突,必须⼿动解决冲突之后再提交


git status
同样可以告知我们冲突的⽂件:

打开
a.txt
⽂件,可以看到如下内容:

19
20

git

<<<<<<<

=======

>>>>>>>
标记出不同分⽀的内容:

<<<<<<< 和 ======= 之间的区域就是当前更改的内容

======= 和 >>>>>>> 之间的区域就是传⼊进来更改的内容

现在要做的事情就是将冲突的内容进⾏更改,对每个⽂件使⽤
git add
命令来将其标记为冲突已解

决。 ⼀旦暂存这些原本有冲突的⽂件,
Git
就会将它们标记为冲突已解决然后再提交:

git add a.txt

git commit -m “conflict fixed”

此时
master
分⽀和
feature1
分⽀变成了下图所示:

使⽤
git log
命令可以看到合并的信息:


21


Git
⽆法⾃动合并分⽀时,就必须⾸先解决冲突,解决冲突后,再提交,合并完成

解决冲突是把
Git
合并失败的⽂件⼿动编辑为我们希望的内容,再提交

fork
,英语翻译过来就是叉⼦,动词形式则是分叉,如下图,从左到右,⼀条直线变成多条直线

转到
git
仓库中,
fork
则可以代表分叉、克隆 出⼀个(仓库的)新拷⻉

5.3.
总结

6. 说说Git中 fork, clone,branch这三个概念,有什么区

别?

6.1.
是什么

6.1.1.
fork
包含了原来的仓库(即upstream repository,上游仓库)所有内容,如分⽀、Tag、提交

如果想将你的修改合并到原项⽬中时,可以通过的 Pull Request 把你的提交贡献回 原仓库

6.1.2.
clone

clone
,译为克隆,它的作⽤是将⽂件从远程代码仓下载到本地,从⽽形成⼀个本地代码仓

执⾏
clone
命令后,会在当前⽬录下创建⼀个名为
xxx
的⽬录,并在这个⽬录下初始化⼀个
.git

⽂件夹,然后从中读取最新版本的⽂件的拷⻉

默认配置下远程
Git
仓库中的每⼀个⽂件的每⼀个版本都将被拉取下来

6.1.3.
branch

branch
,译为分⽀,其作⽤简单⽽⾔就是开启另⼀个分⽀, 使⽤分⽀意味着你可以把你的⼯作从开

发主线上分离开来,以免影响开发主线

Git
处理分⽀的⽅式⼗分轻量,创建新分⽀这⼀操作⼏乎能在瞬间完成,并且在不同分⽀之间的切换

操作也是⼀样便捷

在我们开发中,默认只有⼀条
master
分⽀,如下图所示:

22
通过
git branch
可以创建⼀个分⽀,但并不会⾃动切换到新分⽀中去

通过
git checkout
可以切换到另⼀个
testing
分⽀

23
24

当你在
github
发现感兴趣开源项⽬的时候,可以通过点击
github
仓库中右上⻆
fork
标识的按

钮,如下图:

点击这个操作后会将这个仓库的⽂件、提交历史、issues和其余东⻄的仓库复制到⾃⼰的
github
仓库

中,⽽你本地仓库是不会存在任何更改

然后你就可以通过
git clone
对你这个复制的远程仓库进⾏克隆

6.2.
如何使⽤

6.2.1.
fork
25

后续更改任何东⻄都可以在本地完成,如
git add

git commit
⼀系列的操作,然后通


push
命令推到⾃⼰的远程仓库

如果希望对⽅接受你的修改,可以通过发送
pull requests
给对⽅,如果对⽅接受。则会将你的修

改内容更新到仓库中

整体流程如下图


github
中,开源项⽬右侧存在
code
按钮,点击后则会显示开源项⽬
url
信息,如下图所示:

6.2.2.
clone
通过
git clone xxx
则能完成远程项⽬的下载

6.2.3.
branch

可通过
git branch
进⾏查看当前的分⽀状态,

如果给了
–list
,或者没有⾮选项参数,现有的分⽀将被列出;当前的分⽀将以绿⾊突出显示,并标

有星号

以及通过
git branch
创建⼀个新的分⽀出来

6.3.
区别

其三者区别如下:


fork 只能对代码仓进⾏操作,且 fork 不属于 git 的命令,通常⽤于代码仓托管平台的⼀种“操作”


clone 是 git 的⼀种命令,它的作⽤是将⽂件从远程代码仓下载到本地,从⽽形成⼀个本地代码仓


branch 特征与 fork 很类似,fork 得到的是⼀个新的、⾃⼰的代码仓,⽽ branch 得到的是⼀个代

码仓的⼀个新分⽀

7. 说说对git pull 和 git fetch 的理解?有什么区别?

26
27

先回顾两个命令的定义

git fetch 命令⽤于从另⼀个存储库下载对象和引⽤

git pull 命令⽤于从另⼀个存储库或本地分⽀获取并集成(整合)

再来看⼀次
git
的⼯作流程图,如下所示:

可以看到,
git fetch
是将远程主机的最新内容拉到本地,⽤户在检查了以后决定是否合并到⼯作本

机分⽀中


git pull
则是将远程主机的最新内容拉下来后直接合并,即:
git pull = git fetch + gi

t merge
,这样可能会产⽣冲突,需要⼿动解决

在我们本地的
git
⽂件中对应也存储了
git
本地仓库分⽀的
commit ID
和 跟踪的远程分⽀的
co

mmit ID
,对应⽂件如下:

.git/refs/head/[本地分⽀]

.git/refs/remotes/[正在跟踪的分⽀]

使⽤
git fetch
更新代码,本地的库中
master

commitID
不变

7.1.
是什么


28

但是与
git
上⾯关联的那个
orign/master

commit ID
发⽣改变

这时候本地相当于存储了两个代码的版本号,我们还要通过
merge
去合并这两个不同的代码版本

也就是
fetch
的时候本地的
master
没有变化,但是与远程仓关联的那个版本号被更新了,接下来就

是在本地
merge
合并这两个版本号的代码

相⽐之下,使⽤
git pull
就更加简单粗暴,会将本地的代码更新⾄远程仓库⾥⾯最新的代码版本,

如下图:
29

⼀般远端仓库⾥有新的内容更新,当我们需要把新内容下载的时候,就使⽤到
git pull
或者
git f

etch
命令

⽤法如下:

例如从远程的
origin
仓库的
master
分⽀下载代码到本地并新建⼀个
temp
分⽀

如果上述没有冒号,则表示将远程
origin
仓库的
master
分⽀拉取下来到本地当前分⽀

这⾥
git fetch
不会进⾏合并,执⾏后需要⼿动执⾏
git merge
合并,如下:

7.2.
⽤法

7.2.1.
fetch

git fetch <
远程主机名
> <
远程分⽀名
>:<
本地分⽀名
>

1

Plain Text

复制代码

git fetch origin master:temp

1

Plain Text

复制代码
30

两者的⽤法⼗分相似,
pull
⽤法如下:

例如将远程主机
origin

master
分⽀拉取过来,与本地的
branchtest
分⽀合并,命令如下:

同样如果上述没有冒号,则表示将远程
origin
仓库的
master
分⽀拉取下来与本地当前分⽀合并

相同点:

在作⽤上他们的功能是⼤致相同的,都是起到了更新代码的作⽤

不同点:

git pull是相当于从远程仓库获取最新版本,然后再与本地分⽀merge,即git pull = git fetch + git

merge

相⽐起来,git fetch 更安全也更符合实际要求,在 merge 前,我们可以查看更新情况,根据实际情

况再决定是否合并

7.2.2.
pull

7.3.
区别

8.
说说你对git rebase 和 git merge的理解?区别?

git merge temp

1

Plain Text

复制代码

git pull <
远程主机名
> <
远程分⽀名
>:<
本地分⽀名
>

1

Plain Text

复制代码

git pull origin master:branchtest

1

Plain Text

复制代码
31

在使⽤
git
进⾏版本管理的项⽬中,当完成⼀个特性的开发并将其合并到
master
分⽀时,会有

两种⽅式:

git merge

git rebase

git rebase

git merge
都有相同的作⽤,都是将⼀个分⽀的提交合并到另⼀分⽀上,但是在

原理上却不相同

⽤法上两者也⼗分的简单:

将当前分⽀合并到指定分⽀,命令⽤法如下:

将当前分⽀移植到指定分⽀或指定
commit
之上,⽤法如下:

8.说说你对git rebase 和 git merge的理解?区别?

8.1.
是什么

8.1.1.
git merge

8.1.2.
git rebase

git merge xxx

1

Plain Text

复制代码

git rebase -i

1

Plain Text

复制代码
32

常⻅的参数有
–continue
,⽤于解决冲突之后,继续执⾏
rebase

通过
git merge
将当前分⽀与
xxx
分⽀合并,产⽣的新的
commit
对象有两个⽗节点

如果“指定分⽀”本身是当前分⽀的⼀个直接⼦节点,则会产⽣快照合并

举个例⼦,
bugfix
分⽀是从
master
分⽀分叉出来的,如下所示:

合并
bugfix
分⽀到
master
分⽀时,如果
master
分⽀的状态没有被更改过,即
bugfix
分⽀

的历史记录包含
master
分⽀所有的历史记录

所以通过把
master
分⽀的位置移动到
bugfix
的最新分⽀上,就完成合并

如果
master
分⽀的历史记录在创建
bugfix
分⽀后⼜有新的提交,如下情况:

这时候使⽤
git merge
的时候,会⽣成⼀个新的提交,并且
master
分⽀的
HEAD
会移动到新的分

⽀上,如下:

8.2.
⼆、分析

8.2.1.
git merge

git rebase –continue

1

Plain Text

复制代码
33

从上⾯可以看到,会把两个分⽀的最新快照以及⼆者最近的共同祖先进⾏三⽅合并,合并的结果是⽣成

⼀个新的快照

同样,
master
分⽀的历史记录在创建
bugfix
分⽀后⼜有新的提交,如下情况:

通过
git rebase
,会变成如下情况:

在移交过程中,如果发⽣冲突,需要修改各⾃的冲突,如下:

8.2.2.
git rebase
34

rebase
之后,
master

HEAD
位置不变。因此,要合并
master
分⽀和
bugfix
分⽀

从上⾯可以看到,
rebase
会找到不同的分⽀的最近共同祖先,如上图的

B

然后对⽐当前分⽀相对于该祖先的历次提交,提取相应的修改并存为临时⽂件(⽼的提交
X

Y

也没

有被销毁,只是简单地不能再被访问或者使⽤)

然后将当前分⽀指向⽬标最新位置
D
, 然后将之前另存为临时⽂件的修改依序应⽤

从上⾯可以看到,
merge

rebasea
都是合并历史记录,但是各⾃特性不同:

通过
merge
合并分⽀会新增⼀个
merge commit
,然后将两个分⽀的历史联系起来

其实是⼀种⾮破坏性的操作,对现有分⽀不会以任何⽅式被更改,但是会导致历史记录相对复杂

rebase
会将整个分⽀移动到另⼀个分⽀上,有效地整合了所有分⽀上的提交

主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了
git merge

需的不必要的合并提交

8.3.
区别

8.3.1.
merge

8.3.2.
rebase

9. 说说你对git reset 和 git revert 的理解?区别?9.1. 是什么

9.1.1.
git reset

reset
⽤于回退版本,可以遗弃不再使⽤的提交

执⾏遗弃时,需要根据影响的范围⽽指定不同的参数,可以指定是否复原索引或⼯作树内容

35
9.1.2.
git revert

在当前提交后⾯,新增⼀次提交,抵消掉上⼀次提交导致的所有变化,不会改变过去的历史,主要是⽤

于安全地取消过去发布的提交

9.2.
如何⽤

9.2.1.
git reset

36
37

当没有指定
ID
的时候,默认使⽤
HEAD
,如果指定

ID

,那么就是基于指向

ID

去变动暂存区或⼯

作区的内容

⽇志
ID
可以通过查询,可以
git log
进⾏查询,如下:

常⻅命令如下

–mixed(默认):默认的时候,只有暂存区变化

–hard参数:如果使⽤ –hard 参数,那么⼯作区也会变化

–soft:如果使⽤ –soft 参数,那么暂存区和⼯作区都不会变化

//
没有指定
ID,
暂存区的内容会被当前
ID
版本号的内容覆盖,⼯作区不变

git reset

//
指定
ID
,暂存区的内容会被指定
ID
版本号的内容覆盖,⼯作区不变

git reset

1

2

3

4

5

Plain Text

复制代码

commit a7700083ace1204ccdff9f71631fb34c9913f7c5 (HEAD -> master)

Author: linguanghui

Date: Tue Aug 17 22:34:40 2021 +0800

second commit

commit e31118663ce66717edd8a179688a7f3dde5a9393

Author: linguanghui

Date: Tue Aug 17 22:20:01 2021 +0800

first commit

1

2

3

4

5

6

7

8

9

10

11

Plain Text

复制代码
38


git reset
⽤法基本⼀致,
git revert
撤销某次操作,此次操作之前和之后的

commit

history
都会保留,并且把这次撤销,作为⼀次最新的提交,如下:

如果撤销前⼀个版本,可以通过如下命令:

撤销前前⼀次,如下:

9.2.2.
git revert

git revert

1

Plain Text

复制代码

git revert HEAD

1

Plain Text

复制代码

git revert HEAD^

1

Plain Text

复制代码
9.3.
区别

撤销(revert)被设计为撤销公开的提交(⽐如已经push)的安全⽅式,
git reset
被设计为重设本

地更改

因为两个命令的⽬的不同,它们的实现也不⼀样:重设完全地移除了⼀堆更改,⽽撤销保留了原来的更

改,⽤⼀个新的提交来实现撤销

两者主要区别如下:


git revert是⽤⼀次新的commit来回滚之前的commit,git reset是直接删除指定的commit


git reset 是把HEAD向后移动了⼀下,⽽git revert是HEAD继续前进,只是新的commit的内容和要

revert的内容正好相反,能够抵消要被revert的内容


在回滚这⼀操作上看,效果差不多。但是在⽇后继续 merge 以前的⽼版本时有区别

git revert是⽤⼀次逆向的commit“中和”之前的提交,因此⽇后合并⽼的branch时,之前提交合并的代

码仍然存在,导致不能够重新合并

但是git reset是之间把某些commit在某个branch上删除,因⽽和⽼的branch再次merge时,这些被回

滚的commit应该还会被引⼊


如果回退分⽀的代码以后还需要的情况则使⽤
git revert
, 如果分⽀是提错了没⽤的并且不想

让别⼈发现这些错误代码,则使⽤ git reset

10. 说说你对git stash 的理解?应⽤场景?

10.1.
是什么

39
40

stash,译为存放,在 git 中,可以理解为保存当前⼯作进度,会把暂存区和⼯作区的改动进⾏保存,这

些修改会保存在⼀个栈上

后续你可以在任何时候任何分⽀重新将某次的修改推出来,重新应⽤这些更改的代码

默认情况下,
git stash
会缓存下列状态的⽂件:

添加到暂存区的修改(staged changes)

Git跟踪的但并未添加到暂存区的修改(unstaged changes)

但以下状态的⽂件不会缓存:

在⼯作⽬录中新的⽂件(untracked files)

被忽略的⽂件(ignored files)

如果想要上述的⽂件都被缓存,可以使⽤
-u
或者
–include-untracked
可以⼯作⽬录新的⽂件,

使⽤
-a
或者
–all
命令可以当前⽬录下的所有修改

关于
git stash
常⻅的命令如下:

git stash

git stash save

git stash list

git stash pop

git stash apply

git stash show

git stash drop

git stash clear

保存当前⼯作进度,会把暂存区和⼯作区的改动保存起来

git stash save
可以⽤于存储修改.并且将
git
的⼯作状态切回到
HEAD
也就是上⼀次合法提交

10.2.
如何使⽤

10.2.1.
git stash

10.2.2.
git stash save
41

如果给定具体的⽂件路径,
git stash
只会处理路径下的⽂件.其他的⽂件不会被存储,其存在⼀些参

数:

–keep-index 或者 -k 只会存储为加⼊ git 管理的⽂件

–include-untracked 为追踪的⽂件也会被缓存,当前的⼯作空间会被恢复为完全清空的状态

-a 或者 –all 命令可以当前⽬录下的所有修改,包括被 git 忽略的⽂件

显示保存进度的列表。也就意味着,
git stash
命令可以多次执⾏,当多次使⽤
git stash
命令

后,栈⾥会充满未提交的代码,如下:

其中,
stash@{0}

stash@{1}
就是当前
stash
的名称

git stash pop
从栈中读取最近⼀次保存的内容,也就是栈顶的
stash
会恢复到⼯作区

也可以通过
git stash pop
+
stash
名字执⾏恢复哪个
stash
恢复到当前⽬录

如果从
stash
中恢复的内容和当前⽬录中的内容发⽣了冲突,则需要⼿动修复冲突或者创建新的分⽀

来解决冲突

将堆栈中的内容应⽤到当前⽬录,不同于
git stash pop
,该命令不会将内容从堆栈中删除

也就说该命令能够将堆栈的内容多次应⽤到⼯作⽬录中,适应于多个分⽀的情况

同样,可以通过
git stash apply
+
stash
名字执⾏恢复哪个
stash
恢复到当前⽬录

查看堆栈中最新保存的
stash
和当前⽬录的差异

通过使⽤
git stash show -p
查看详细的不同

通过使⽤
git stash show stash@{1}
查看指定的
stash
和当前⽬录差异

10.2.3.
git stash list

10.2.4.
git stash pop

10.2.5.
git stash apply

10.2.6.
git stash show
10.2.7.
git stash drop

git stash drop
+
stash
名称表示从堆栈中移除某个指定的stash

10.2.8.
git stash clear

删除所有存储的进度

10.3.
应⽤场景

当你在项⽬的⼀部分上已经⼯作⼀段时间后,所有东⻄都进⼊了混乱的状态, ⽽这时你想要切换到另⼀

个分⽀或者拉下远端的代码去做⼀点别的事情

但是你创建⼀次未完成的代码的
commit
提交,这时候就可以使⽤
git stash

例如以下场景:

当你的开发进⾏到⼀半,但是代码还不想进⾏提交 ,然后需要同步去关联远端代码时.如果你本地的代码和

远端代码没有冲突时,可以直接通过
git pull
解决

但是如果可能发⽣冲突怎么办.直接
git pull
会拒绝覆盖当前的修改,这时候就可以依次使⽤下述的

命令:


git stash


git pull


git stash pop

或者当你开发到⼀半,现在要修改别的分⽀问题的时候,你也可以使⽤
git stash
缓存当前区域的代

42

git stash:保存开发到⼀半的代码


git commit -m ‘修改问题’


git stash pop:将代码追加到最新的提交之后

43

本站无任何商业行为
个人在线分享 » Git⾯试真题(10题)
E-->