三道 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 採用分支,就是不冒犯別人代碼的意思

相關文章
相關標籤/搜索