三道 google 风格 git 面试题及其解答

第一题: 把配置文件推送到了远程仓库,怎样删除远程仓库的该配置文件,本地还要用到这个文件。

这种操做失误,比较常见。通常这样解决:git

git rm --cached filename
echo filename >> .gitignore
复制代码

先解释第二步,本地须要,远程仓库不须要,确定是要把那个文件写入 .gitignore 文件里面。 不然之后还要删除。程序员

第一步则是把该文件从 git 的暂存区域中删除。暂存区域,就是 index 区域。github

见一下亲人:bash

111

git 三个区,git rm filename, 会把文件从工做区 Working Directory 和暂存区域 Staging Area 中删除。本地还要用,就不能这么搞。ui

git rm --cached filename, 则把文件从暂存区域 Staging Area 删除,保留工做区的,咱们通常编辑见到的。spa

这种状况就是已经 commit 了,生成快照,文件进了版本库 Commit History,而后 push, 远程库与本地库同步一下。设计

这个时候,直接 push 到远程,无效。由于没有新的快照,也就是没有新的 commit id. 本地与远程的历史 log 是一致的。 修改文件,add 再 commit, push 提交过去,就会生效。指针

第二题: git 如何解决代码冲突

解决冲突三连

git stash 
git pull 
git stash pop 
复制代码

操做就是把本身修改的代码隐藏,而后把远程仓库的代码拉下来,而后把本身隐藏的修改的代码释放出来,让 git 自动合并。接着找 <<<<<<<, 哪里冲突哪里改。code

若是要代码库的文件彻底覆盖本地版本,

git reset --hard commit id
git pull
复制代码

前面两招挺管用的,场景就是合做的远程仓库上,别人作了一些改动,我没有 commit , 而后把别人的 commit 拉下来。cdn

刚进入公司的时候,没办法,我也常常这么作

增强版就来了

场景就是合做的远程仓库上,别人作了一些改动,我在本地也作了一些 commit , 而后把别人的 commit 拉下来,再把个人更改添加上去。接着找 <<<<<<<, 哪里冲突哪里改。

这个时候,先检查一下个人本地仓库与合做的远程仓库的最近的一个共同 commit id.

git reset commit id
git stash 
git pull 
git stash pop 
复制代码

git reset commit id 的做用是取消暂存文件。将 HEAD 的指针指向 commit id,修改了暂存区域 Staging Area 和版本库 Commit History,工做区沙盒 Working Directory 保持原样。

亲人来了,看图加深一下理解:

屏幕快照 2019-06-28 下午4.14.00.png

  • git reset commit id就是 git reset -mixed commit id,移动 HEAD,更新索引,即更新 staging area。移动 HEAD 分支的指向,使索引看起来像 HEAD。效果上看,就是取消了 commit id 之后的,add 和 commit .

  • git reset --soft commit id,就是移动 HEAD。移动 HEAD 分支的指向,本质上是撤销了上一次 git commit 命令。

当你在运行 git commit 时,Git 会建立一个新的提交,并移动 HEAD 所指向的分支来使其指向该提交。

当你将它 reset 回 HEAD~(HEAD 的父结点)时,其实就是把该分支移动回原来的位置,而不会改变索引和工做目录。

  • git reset --hard commit id, 移动 HEAD,更新索引,更新工做目录。三件事情,全作了。前两件事情,已经说了。更新工做目录,让工做目录看起来像索引。从效果上看,就是撤销一切修改,本地文件状态同 commit id 的那时候。

第三题: 何时合并分支用 git rebase, 不用 git merge ?

git rebasegit merge 均可以用于合并分支,从 feature 分支上,取得新的提交 commits , 而后运用到 master 分支上(固然运用到其余分支上也行)。

可是路子不一样

merge 是合并,rebase 是变基

变基怎么变?

aaa

看图可知: git rebase 有一个移动 base , 改变合并基准的操做

直观的理解: git rebase 作的事情,就是先移指针,再移结点。

  • 先移指针:master 分支以前分出的 feature 分支的 commit id, 是 feature 分支的基准 base.

在 feature 分支上 git rebase master,就把 feature 分支的基准 base 移动到 master 分支最新的 commit id 上。

  • 再移结点: 把 feature 分支上新增的提交 commit id ,放到新的 base 结点后面。准确一些,就是把 feature 分支上新作的修改操做,从新应用到 master 分支的 HEAD 结点上。

举个例子:

合并分支前:

A <- B <- C    [master]
^
 \
  D <- E       [branch]
复制代码

根结点是 A, 最初是 A , 在 A 状态,分出去了分支 branch

git merge 是这样合并的:

A <- B <- C
^         ^
 \         \
  D <- E <- F
复制代码

提交到 C 的 master 分支和提交到 E 的 branch 分支,直接合并,通常是合并到 master, 有冲突解决冲突。

看图可知: 采用 git merge ,不改变原来的 commit id, 会产生新的提交 commit id

项目协做成员比较多,通常须要使用 git rebase, 固然也能够这样git merge, git merge --squash feeature

若是使用 git merge ,极可能这样,

555

这样看,就很不舒服。须要采用 git rebase 修改历史:

git rebase 是这样合并的:

A <- B <- C <- `D` <- `E`
复制代码

把 feature 分支( 例子中是 branch 分支)的提交 commits ,移动到 master 分支的顶端。

使用 rebase, 看起来更加 nice, 更加直观,历史就是一条直线嘛,没什么枝枝岔岔的。

看图可知: 使用 rebase 后,把 feature 分支上 commit 拿来后,commit id 改掉了。而且没有建立合并的公共节点 commit id

6666

有的团队采用 git rebase 工做流,有的采用 git merge 工做流,git rebase 工做流要求对 git 的理解深一些,商用多一些, feature 作好了,用 git rebase 合并。

这样加 feature 怎么加的,看 log 比较明朗。不然看 log, 上一条 feature A, 下一条 feature B , 不是很职业程序员。

git rebase 工做流,通常这么实操, 在 feature 分支上 git rebase master, 切到 master 分支上后, git merge feature, 这时候 merge 也没作什么事情,就是把 master 分支的 HEAD 结点,移动到 feature 的 HEAD 结点, 两个分支这时候状态同步了。

git merge 工做流民用挺合适的,他的设计很是符合直觉,玩 github 开源,比较合适。由于多人写做,git flow 工做流,不是很好统一

若是你采用 git rebase 工做流,你团队其余人不知道,你这么搞,commit id 修改了,与他们本地库的对不上,大家对你的意见可能会比较大

毕竟 git 采用分支,就是不冒犯别人代码的意思

相关文章
相关标签/搜索