太強了,看程序員小姐姐如何用動圖展現10大Git命令!

選自dev.to           做者:Lydia Halliecss

機器之心編譯        參與:Panda、杜偉git

原文連接:https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1程序員

git merge、git rebase、git reset、git revert、git fetch、git pull、git reflog……你知道這些 git 命令執行的到底是什麼任務嗎?若是你還有些分不清楚,那千萬不能錯過這篇文章。在本文中,熟知 JavaScript、TypeScript、GraphQL、Serverless、AWS、Docker 和 Golang 的 21 歲年輕軟件顧問 Lydia Hallie 經過動圖形式直觀地介紹了這些經常使用 git 命令的工做過程,包你過目不忘。web



儘管 Git 是一款很是強大的工具,但若是我說 Git 用起來簡直是噩夢,大多數人也會認同個人說法。我發如今使用 Git 時,在頭腦裏可視化地想象它會很是有用:當我執行一個特定命令時,這些分支會如何交互,又會怎樣影響歷史記錄?爲何當我在 master 上執行硬重啓,force push 到原分支以及 rimraf 咱們的 .git 文件夾時,個人同事哭了?

我以爲建立一些最經常使用且最有用的 Git 命令的可視化示例會是一個完美的用例!下面我將介紹的不少命令都有可選參數——你可使用這些參數來改變對應命令的行爲。而個人示例只會涵蓋命令的默認行爲,而不會添加(或添加太多)可選配置!

本文做者Lydia Hallie。

合併

擁有多個分支是很方便的,這樣能夠將不一樣的新修改互相隔離開,並且還能確保你不會意外地向生產代碼推送未經許可或破損的代碼修改。但一旦這些修改獲得了批准許可,咱們就須要將其部署到咱們的生產分支中!

可將一個分支的修改融入到另外一個分支的一種方式是執行 git merge。Git 可執行兩種類型的合併:fast-forward 和 no-fast-forward。如今你可能分不清,但咱們立刻就來看看它們的差別所在。

Fast-forward (—ff)

在當前分支相比於咱們要合併的分支沒有額外的提交(commit)時,能夠執行 fast-forward 合併。Git 很懶,首先會嘗試執行最簡單的選項:fast-forward!這類合併不會建立新的提交,而是會將咱們正在合併的分支上的提交直接合併到當前分支。


完美!如今,咱們在 dev 分支上所作的全部改變都合併到了 master 分支上。那麼 no-fast-forward 又是什麼意思呢?

No-fast-foward (—no-ff)

若是你的當前分支相比於你想要合併的分支沒有任何提交,那固然很好,但很遺憾現實狀況不多如此!若是咱們在當前分支上提交咱們想要合併的分支不具有的改變,那麼 git 將會執行 no-fast-forward 合併。

使用 no-fast-forward 合併時,Git 會在當前活動分支上建立新的 merging commit。這個提交的父提交(parent commit)即指向這個活動分支,也指向咱們想要合併的分支!


沒什麼大不了的,完美的合併!如今,咱們在 dev 分支上所作的全部改變都合併到了 master 分支上。

合併衝突

儘管 Git 可以很好地決定如何合併分支以及如何向文件添加修改,但它並不老是能徹底本身作決定。當咱們想要合併的兩個分支的同一文件中的同一行代碼上有不一樣的修改,或者一個分支刪除了一個文件而另外一個分支修改了這個文件時,Git 就不知道如何取捨了。

在這樣的狀況下,Git 會詢問你想要保留哪一種選擇?假設在這兩個分支中,咱們都編輯了 README.md 的第一行。



若是咱們想把 dev 合併到 master,就會出現一個合併衝突:你想要標題是 Hello! 仍是 Hey!?

當嘗試合併這些分支時,Git 會向你展現衝突出現的位置。咱們能夠手動移除咱們不想保留的修改,保存這些修改,再次添加這個已修改的文件,而後提交這些修改。

完成!儘管合併衝突每每很讓人厭煩,但這是合理的:Git 不該該瞎猜咱們想要保留哪些修改。
微信


變基(Rebasing)

咱們剛看到可經過執行 git merge 將一個分支的修改應用到另外一個分支。另外一種可將一個分支的修改融入到另外一個分支的方式是執行 git rebase。

git rebase 會將當前分支的提交複製到指定的分支之上。



完美,如今咱們在 dev 分支上獲取了 master 分支上的全部修改。

變基與合併有一個重大的區別:Git 不會嘗試肯定要保留或不保留哪些文件。咱們執行 rebase 的分支老是含有咱們想要保留的最新近的修改!這樣咱們不會遇到任何合併衝突,並且能夠保留一個漂亮的、線性的 Git 歷史記錄。

上面這個例子展現了在 master 分支上的變基。可是,在更大型的項目中,你一般不須要這樣的操做。git rebase 在爲複製的提交建立新的 hash 時會修改項目的歷史記錄。

若是你在開發一個 feature 分支而且 master 分支已經更新過,那麼變基就很好用。你能夠在你的分支上獲取全部更新,這能防止將來出現合併衝突。

交互式變基(Interactive Rebase)

在爲提交執行變基以前,咱們能夠修改它們!咱們可使用交互式變基來完成這一任務。交互式變基在你當前開發的分支上以及想要修改某些提交時會頗有用。

在咱們正在 rebase 的提交上,咱們能夠執行如下 6 個動做:


  • reword:修改提交信息;app

  • edit:修改此提交;less

  • squash:將提交融合到前一個提交中;編輯器

  • fixup:將提交融合到前一個提交中,不保留該提交的日誌消息;工具

  • exec:在每一個提交上運行咱們想要 rebase 的命令;fetch

  • drop:移除該提交。


很棒!這樣咱們就能徹底控制咱們的提交了。若是你想要移除一個提交,只需 drop 便可。


若是你想把多個提交融合到一塊兒以便獲得清晰的提交歷史,那也沒有問題!

交互式變基能爲你在 rebase 時提供大量控制,甚至能夠控制當前的活動分支。
重置(Resetting)

當咱們不想要以前提交的修改時,就會用到這個命令。也許這是一個 WIP 提交或者多是引入了 bug 的提交,這時候就要執行 git reset。

git reset 能讓咱們再也不使用當前檯面上的文件,讓咱們能夠控制 HEAD 應該指向的位置。

軟重置

軟重置會將 HEAD 移至指定的提交(或與 HEAD 相比的提交的索引),而不會移除該提交以後加入的修改!

假設咱們不想保留添加了一個 style.css 文件的提交 9e78i,並且咱們也不想保留添加了一個 index.js 文件的提交 035cc。可是,咱們確實又想要保留新添加的 style.css 和 index.js 文件!這是軟重置的一個完美用例。


輸入 git status 後,你會看到咱們仍然能夠訪問在以前的提交上作過的全部修改。這很好,這意味着咱們能夠修復這些文件的內容,以後再從新提交它們!


硬重置

有時候咱們並不想保留特定提交引入的修改。不一樣於軟重置,咱們應該再也無需訪問它們。Git 應該直接將總體狀態直接重置到特定提交以前的狀態:這甚至包括你在工做目錄中和暫存文件上的修改。


Git 丟棄了 9e78i 和 035cc 引入的修改,並將狀態重置到了 ec5be 的狀態。

還原(Reverting)

另外一種撤銷修改的方法是執行 git revert。經過對特定的提交執行還原操做,咱們會建立一個包含已還原修改的新提交。

假設 ec5be 添加了一個 index.js 文件。但以後咱們發現其實咱們不再須要由這個提交引入的修改了。那就還原 ec5be 提交吧!


完美!提交 9e78i 還原了由提交 ec5be 引入的修改。在撤銷特定的提交時,git revert 很是有用,同時也不會修改分支的歷史。

揀選(Cherry-picking)

當一個特定分支包含咱們的活動分支須要的某個提交時,咱們對那個提交執行 cherry-pick!對一個提交執行 cherry-pick 時,咱們會在活動分支上建立一個新的提交,其中包含由揀選出來的提交所引入的修改。


假設 dev 分支上的提交 76d12 爲 index.js 文件添加了一項修改,而咱們但願將其整合到 master 分支中。咱們並不想要整個 dev 分支,而只須要這個提交!


如今 master 分支包含 76d12 引入的修改了。
取回(Fetching)

若是你有一個遠程 Git 分支,好比在 GitHub 上的分支,當遠程分支上包含當前分支沒有的提交時,可使用取回。好比當合並了另外一個分支或你的同事推送了一個快速修復時。

經過在這個遠程分支上執行 git fetch,咱們就可在本地獲取這些修改。這不會以任何方式影響你的本地分支:fetch 只是單純地下載新的數據而已。


如今咱們能夠看到自上次推送以來的全部修改了。這些新數據也已經在本地了,咱們能夠決定用這些新數據作什麼了。
拉取(Pulling)

儘管 git fetch 可用於獲取某個分支的遠程信息,但咱們也能夠執行 git pull。git pull 其實是兩個命令合成了一個:git fetch 和 git merge。當咱們歷來源拉取修改時,咱們首先是像 git fetch 那樣取回全部數據,而後最新的修改會自動合併到本地分支中。


很好,咱們如今與遠程分支完美同步了,而且也有了全部最新的修改!
Reflog

每一個人都會犯錯,但犯錯其實沒啥!有時候你可能感受你把 git repo 徹底搞壞了,讓你想徹底刪了了事。

git reflog 是一個很是有用的命令,能夠展現已經執行過的全部動做的日誌。包括合併、重置、還原,基本上包含你對你的分支所作的任何修改。


若是你犯了錯,你能夠根據 reflog 提供的信息經過重置 HEAD 來輕鬆地重作!

假設咱們實際上並不須要合併原有分支。當咱們執行 git reflog 命令時,咱們能夠看到這個 repo 的狀態在合併前位於 HEAD@{1}。那咱們就執行一次 git reset,將 HEAD 從新指向在 HEAD@{1} 的位置。


咱們能夠看到最新的動做已被推送給 reflog。



---END---



推薦閱讀:
看了微信的暗黑模式後,我也適配了一波安卓!
五種牛逼程序員,你屬於哪種?
Kotlin1.4-M1發佈,終於支持Kotlin interface SAM轉換了!
【文末送書】Flutter自定義實現神奇動效的卡片切換視圖
Android消息推送MQTT實戰
Android Native Hook技術你知道多少?
JVM史上最最最完整深刻解析!萬字長文!


每個「在看」,我都當成真的喜歡

本文分享自微信公衆號 - 技術最TOP(Tech-Android)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息