[譯] 淚流滿面的 11 個 Git 面試題
(給 伯樂線上 加星標,看經典文章 )
編譯:伯樂線上/BEASTQ
在今年的 Stack Overflow 開發者調查報告中,超過 70% 的開發者使用 Git,使其成為世界上使用人數最多的版本控制系統。Git 通常用於開源和商業軟體開發,對個人、團隊和企業都頗有益處。
Q1: 什麼是 Git 復刻(fork)?復刻(fork)、分支(branch)和克隆(clone)之間有什麼區別?
主題:Git 難度::star::star:
-
復刻(fork) 是對儲存倉庫(repository)進行的遠端的、伺服器端的拷貝,從源頭上就有所區別。復刻實際上不是 Git 的範疇。它更像是個政治/社會概念。
-
克隆(clone) 不是復刻,克隆是個對某個遠端倉庫的本地拷貝。克隆時,實際上是拷貝整個源儲存倉庫,包括所有歷史記錄和分支。
-
分支(branch) 是一種機制,用於處理單一儲存倉庫中的變更,並最終目的是用於與其他部分程式碼合併。
:link:來源:https://stackoverflow.com/questions/3329943/git-branch-fork-fetch-merge-rebase-and-clone-what-are-the-differences/
Q2: “拉取請求(pull request)”和“分支(branch)”之間有什麼區別?
主題:Git 難度::star::star:
-
分支(branch) 是程式碼的一個獨立版本。
-
拉取請求(pull request) 是當有人用倉庫,建立了自己的分支,做了些修改併合併到該分支(把自己修改應用到別人的程式碼倉庫)。
:link:來源: https://stackoverflow.com/questions/19059838/whats-the-difference-between-a-pull-request-and-a-branch
Q3: “git pull”和“git fetch”之間有什麼區別?
主題:Git 難度::star::star:
簡單來說,git pull 是 git fetch + git merge。
-
當你使用 pull,Git 會試著自動為你完成工作。它是上下文(工作環境)敏感的,所以 Git 會把所有拉取的提交合併到你當前處理的分支中。pull 則是 自動合併提交而沒有讓你複查的過程。如果你沒有細心管理你的分支,你可能會頻繁遇到衝突。
-
當你 fetch,Git 會收集目標分支中的所有不存在的提交,並將這些提交儲存到本地倉庫中。但Git 不會把這些提交合併到當前分支中。這種處理邏輯在當你需要保持倉庫更新,在更新檔案時又希望處理可能中斷的事情時,這將非常實用。而將提交合併到主分支中,則該使用 merge。
:link:來源:https://stackoverflow.com/questions/292357/what-is-the-difference-between-git-pull-and-git-fetch
Q4: 如在 Git 恢復先前的提交?
主題:Git 難度::star::star::star:
假設你的情形是這樣,其中 C 是你的 HEAD,(F) 是你檔案的狀態。
(F) A-B-C ↑ master
要修改提交中的更改:
git reset --hard HEAD~1
現在 B 是 HEAD,因為你使用了 --hard,所以你的檔案將重置到提交 B 時的狀態。
要撤銷提交但保留更改:
git reset HEAD~1
現在我們告訴 Git 將 HEAD 指標移回(後移)一個提交(B),並保留檔案原樣,然後你可以 git status 來顯示你已經檢入 C 的更改。
撤銷提交但保留檔案和索引:
git reset --soft HEAD~1
執行此操作後,git status,你講看到索引中的檔案跟以前一致。
:link:來源:https://stackoverflow.com/questions/927358/how-to-undo-the-most-recent-commits-in-git
Q5: 什麼是“git cherry-pick”?
主題:Git 難度::star::star::star:
命令 git cherry-pick 通常用於把特定提交從儲存倉庫的一個分支引入到其他分支中。常見的用途是從維護的分支到開發分支進行向前或回滾提交。
這與其他操作(例如:合併(merge)、變基(rebase))形成鮮明對比,後者通常是把許多提交應用到其他分支中。
小結:
git cherry-pick <commit-hash>
:link:來源: https://stackoverflow.com/questions/9339429/what-does-cherry-picking-a-commit-with-git-mean
Q6: 解釋 Forking 工作流程的優點
主題:Git 難度::star::star::star:
Forking 工作流程 與其他流行的 Git 工作流程有著根本的區別。它不是用單個服務端倉庫充當“中央”程式碼庫,而是為每個開發者提供自己的服務端倉庫。Forking 工作流程最常用於公共開源專案中。
Forking 工作流程的主要優點是可以彙集提交貢獻,又無需每個開發者提交到一箇中央倉庫中,從而實現乾淨的專案歷史記錄。開發者可以推送(push)程式碼到自己的服務端倉庫,而只有專案維護人員才能直接推送(push)程式碼到官方倉庫中。
當開發者準備釋出本地提交時,他們的提交會推送到自己的公共倉庫中,而不是官方倉庫。然後他們向主倉庫提交請求拉取(pull request),這會告知專案維護人員有可以整合的更新。
:link:來源:https://www.atlassian.com/git/tutorials/comparing-workflows/forking-workflow
Q7: 告訴我 Git 中 HEAD、工作樹和索引之間的區別?
主題:Git 難度::star::star::star:
-
該工作樹/工作目錄/工作空間是你看到和編輯的(源)檔案的目錄樹。
-
該索引/中轉區(staging area)是個在 /.git/index,單一的、龐大的二進位制檔案,該檔案列出了當前分支中所有檔案的 SHA1 檢驗和、時間戳和檔名,它不是個帶有檔案副本的目錄。
-
HEAD是當前檢出分支的最後一次提交的引用/指標。
:link:來源: https://stackoverflow.com/questions/3689838/whats-the-difference-between-head-working-tree-and-index-in-git
Q8: 你能解釋下 Gitflow 工作流程嗎?
主題:Git 難度::star::star::star:
Gitflow 工作流程使用兩個並行的、長期執行的分支來記錄專案的歷史記錄,分別是 master 和 develop 分支。
-
Master,隨時準備釋出線上版本的分支,其所有內容都是經過全面測試和核準的(生產就緒)。
-
Hotfix,維護(maintenance)或修復(hotfix)分支是用於給快速給生產版本修復打補丁的。修復(hotfix)分支很像釋出(release)分支和功能(feature)分支,除非它們是基於 master 而不是 develop 分支。
-
Develop,是合併所有功能(feature)分支,並執行所有測試的分支。只有當所有內容都經過徹底檢查和修復後,才能合併到 master 分支。
-
Feature,每個功能都應留在自己的分支中開發,可以推送到 develop 分支作為功能(feature)分支的父分支。
:link:來源:https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow
Q9: 什麼時候應使用 “git stash”?
主題:Git 難度::star::star::star:
git stash 命令把你未提交的修改(已暫存(staged)和未暫存的(unstaged))儲存以供後續使用,以後就可以從工作副本中進行還原。
回顧:
$ git status
On branch master
Changes to be committed :
new file : style . css
Changes not staged for commit :
modified : index . html
$ git stash
Saved working directory and index state WIP on master : 5002d47 our new homepage
HEAD is now at 5002d47 our new homepage
$ git status
On branch master
nothing to commit , working tree clean
我們可以使用暫存(stash)的一個地方是,如果我們發現在上次提交中忘記了某些內容,並且已經開始在同一分支中處理下一個提交了:
# Assume the latest commit was already done
# start working on the next patch, and discovered I was missing something
# stash away the current mess I made
$ git stash save
# some changes in the working dir
# and now add them to the last commit:
$ git add - u
$ git commit -- ammend
# back to work!
$ git stash pop
:link:來源: https://www.atlassian.com/git/tutorials/saving-changes/git-stash
Q10: 如何從 git 中刪除檔案,而不將其從檔案系統中刪除?
主題:Git 難度::star::star::star::star:
如果你在 git add 過程中誤操作,你最終會新增不想提交的檔案。但是,git rm 則會把你的檔案從你暫存區(索引)和檔案系統(工作樹)中刪除,這可能不是你想要的。
換成 git reset 操作:
git reset filename # or echo filename >> .gitingore # add it to .gitignore to avoid re-adding it
上面意思是,git reset <paths> 是 git add <paths> 的逆操作。
:link:來源:https://www.codementor.io/citizen428/git-tutorial-10-common-git-problems-and-how-to-fix-them-aajv0katd
Q11: 是麼時候使用“git rebase”代替“git merge”?
主題:Git 難度::star::star::star::star::star:
這兩個命令都是把修改從一個分支整合到另一個分支上,它們只是以非常不同的方式進行。
考慮一下場景,在合併和變基前:
A <- B <- C [ master ]
^
\
D <- E [ branch ]
在 git merge master 之後:
A <- B <- C
^ ^
\ \
D <- E <- F
在 git rebase master 之後:
A <- B <- C <- D <- E
使用變基時,意味著使用另一個分支作為整合修改的新基礎。
何時使用:
-
如果你對修改不夠果斷,請使用合併操作。
-
根據你希望的歷史記錄的樣子,而選擇使用變基或合併操作。
更多需要考慮的因素:
-
分支是否與團隊外部的開發人員共享修改(如開源、公開專案)?如果是這樣,請不要使用變基操作。變基會破壞分支,除非他們使用 git pull --rebase,否則這些開發人員將會得到損壞的或不一致的倉庫。
-
你的開發團隊技術是否足夠嫻熟?變基是一種破壞性操作。這意味著,如果你沒有正確使用它,你可能會丟失提交,並且/或者會破壞其他開發者倉庫的一致性。
-
分支本身是否代表有用的資訊?一些團隊使用功能分支(branch-per-feature)模式,每個分支代表一個功能(或錯誤修復,或子功能等)。在此模式中,分支有助於識別相關提交的集合。在每個開發人員分支(branch-per-developer)模式中,分支本身不會傳達任何其他資訊(提交資訊已有作者)。則在這種模式下,變基不會有任何破壞。
-
是否無論如何都要還原合併?恢復(如在撤銷中)變基,是相當困難的,並且/或者在變基中存在衝突時,是不可能完成的。如果你考慮到日後可能需要恢復,請使用合併操作。
:link:來源:https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge
看完本文有收穫?請分享給更多人
關注「伯樂線上」加星標,看 精選 IT 職場文章