測試:你來給我講講git吧,我一直想了解一下git
me:你不是會用git么
測試:呃,只是能用舀患,其實(shí)不知道怎么回事
me:好吧,那我就跟你講講气破,這個(gè)git啊聊浅,它...
me:這我不知道從哪開始講起啊,要不你說說你想聽點(diǎn)什么吧測試:比如我們常用的pull现使,push低匙,rebase和merge命令,我就一直不太明白push和rebase還有merge的區(qū)別
me:看來你是真的不明白碳锈,一般人都會問rebase和merge的區(qū)別顽冶。那我就從pull和push開始說吧,你知道git分本地和遠(yuǎn)程倉庫么
測試:這個(gè)知道的售碳,之前有人跟我講過git分成本地文件强重,本地倉庫和遠(yuǎn)程倉庫
me:沒毛病绞呈,為了方便后面跟你講的東西,我先復(fù)習(xí)一下
幾個(gè)文件分布
- (working copy)工作區(qū):就是本地文件间景,這也是你真正改代碼的地方佃声,其實(shí)你可以認(rèn)為它和git還沒啥關(guān)系
- (stagging)暫存區(qū):是本地文件和本地倉庫的中間地帶,你可以認(rèn)為在這個(gè)地方的文件就是即將要提交到git倉庫的
- (local repo)本地倉庫:這個(gè)是你機(jī)器上的git倉庫倘要,你可以把它理解為游戲存檔
- (remote repo)遠(yuǎn)端倉庫:這個(gè)是真·git倉庫圾亏,你可以把它理解成上傳到服務(wù)器上可以和別人共用的游戲存檔
測試:這個(gè)stagging是個(gè)什么東西,我怎么沒聽說過封拧?
me:別急召嘶,還沒復(fù)習(xí)完,我們再來復(fù)習(xí)一下平常用的最多的幾個(gè)命令
各區(qū)域交互流程
- git add .:add命令負(fù)責(zé)把工作區(qū)的文件添加到暫存區(qū)哮缺,我想很多人都喜歡這么玩弄跌,畢竟這么玩最方便,不過我不會用git命令尝苇,我都是用工具的铛只,所以我不這么玩。喜歡用命令的話可以去翻翻官網(wǎng)的add命令教程糠溜,反正我不看
- git commit -m "add README.md": commit 命令把暫存區(qū)的數(shù)據(jù)提交到本地倉庫淳玩,之前說過我喜歡用工具,所以也不會這個(gè)命令非竿,有興趣的可以去看官網(wǎng)...
- git push: push命令把本地倉庫的數(shù)據(jù)推到遠(yuǎn)端倉庫蜕着,push命令的玩法還挺多的,但是還是同上红柱,我不會承匣,看官網(wǎng)
- git pull: pull命令把遠(yuǎn)端倉庫的代碼拉取到本地倉庫,官網(wǎng)~
測試:哦锤悄,我說怎么每次commit之前都要add一下韧骗,原來是這樣,commit只會提交暫存區(qū)的數(shù)據(jù)對吧
me:可以這么理解零聚,不過commit也可以通過 -a參數(shù)來隱式調(diào)用add袍暴,比如‘git commit –a –m "add README.md"’就相當(dāng)于“git add .”和“git commit -m "add README.md"”,
測試:好的我知道了隶症,那merge和rebase呢
merge和reabse的區(qū)別
image.png
me:比如你現(xiàn)在拉一個(gè)feature分支改了代碼(4政模,5),正準(zhǔn)備合并到上去蚂会,但是這時(shí)候發(fā)現(xiàn)別人已經(jīng)提交了一個(gè)版本(3)上去了淋样,這個(gè)時(shí)候如果沒有merge和rebase操作,你該怎么辦呢
測試:颂龙。习蓬。纽什。
me: 你看這樣行不行措嵌,我把自己本地的改動(dòng)全部刪掉躲叼,然后從新沖遠(yuǎn)端進(jìn)行一次pull操作,更新成最新的代碼企巢,然后再重新改一次枫慷。
測試:那多麻煩,而且我也不記得改過寫什么了...
me:我只是做一個(gè)假設(shè)浪规,其實(shí)你可以認(rèn)為rebase就是再做這個(gè)事情
rebase
me:還有另一種方案或听,我進(jìn)行一次新的提交,把遠(yuǎn)端和和自己改的合并到一起笋婿,像這樣
merge
測試:所以這就是merge對吧me:嗯誉裆,這就是merge做的事情。當(dāng)然merge和rebase都是基于branch缸濒,或者準(zhǔn)確的說是基于commit的足丢,這里雖然說是同一個(gè)分支,但是遠(yuǎn)端和本地其實(shí)是有不同的版本的
測試:好的庇配,那之前他們說的把commit合成一個(gè)是什么意思
rebase -i合成commit
me:還是之前的例子斩跌,你進(jìn)行了兩次commit(4和5),但是現(xiàn)在你發(fā)現(xiàn)其實(shí)這兩次提交你在做同一個(gè)事情捞慌,只是花了比較長的時(shí)間耀鸦,不得不分兩次提交,那么現(xiàn)在你想把它搞成一次提交怎么辦呢
me:如果是我啸澡,我就會把本地的全給刪了袖订,然后重新把所有的修改重新做一次,然后只commit一次
測試:哦嗅虏!懂了著角,這就是rebase做的事情是吧
me:是的,你可以這么理解旋恼,但是rebase這個(gè)命令有點(diǎn)復(fù)雜吏口,我們一般會使用--interactive指令來在rebase操作中對每個(gè)commit進(jìn)行處理。每個(gè)commit我們都可以進(jìn)行以下處理
- pick:表示這次提交在rebase之后會被完整保留下來冰更,包括注釋
- reword:表示這次提交在rebase之后會被保留下來产徊,但不包括注釋
- squash:表示這次提交會被合并到前一次提交里面去
- edit:我沒用過,據(jù)說可以在同一個(gè)commit id下改代碼蜀细,不看
- fixup:沒用過舟铜,據(jù)說和squash差不多,不看
- exec:什么鬼奠衔,不看
測試:還有這么厲害的操作啊谆刨,我抽時(shí)間去看看
me:還有什么想知道的么
測試:嗯...對了塘娶,還有個(gè)reset,這個(gè)是什么意思
reset命令
me:reset命令用來回滾你當(dāng)前分支的提交痊夭,你可以把它理解為rollback
測試:這個(gè)我知道刁岸,那我看他們用reset的時(shí)候喜歡后面跟一個(gè)--hard是什么意思
me:好問題!其實(shí)reset回滾有三種級別soft她我,mixed和hard虹曙,你應(yīng)該還記得我之前提過的工作區(qū)、暫存區(qū)和本地倉庫的概念番舆。首先你要明確酝碳,reset命令是會回滾本地倉庫的版本的,然后再來看這三個(gè)回滾級別有啥區(qū)別
- soft:聽名字就知道這個(gè)回滾是很軟的~恨狈,這種情況會回滾倉庫中的版本疏哗,但是你修改過的文件會保留到工作區(qū)和暫存區(qū),就是說你回滾了倉庫代碼禾怠,但是你打開編譯器發(fā)現(xiàn)代碼還是最新的返奉,然后你commit一下它又和reset之前一樣了
- hard:這是很強(qiáng)硬的回滾!這種情況會回滾你的分支版本刃宵、暫存區(qū)和工作區(qū)衡瓶,就是說不管你本地的修改,還是被add到暫存區(qū)的東西牲证,還是commit的東西哮针,都沒有了
- mixed:這個(gè)就是上面兩個(gè)的折衷了,這種情況會回滾你的分支版本和暫存區(qū)坦袍,但是你修改過的文件還會保留到工作區(qū)十厢,就是說你打開編譯器發(fā)現(xiàn)代碼還是最新的,然后通過add和commit操作又可以變會reset之前的樣子
Tips
這些命令都沒有這么簡單
??這里講到了add捂齐、commit蛮放、push、pull奠宜、merge包颁、rebase、reset這些命令压真,我只是簡單提了一下最常用的用法娩嚼,但是這些命令本身是有點(diǎn)復(fù)雜的(畢竟官網(wǎng)一個(gè)命令就可以寫好幾頁),有興趣的可以去具體了解一下滴肿,反正我不看岳悟,太麻煩
工具是個(gè)好東西
??人,能制造工具并能熟練使用工具進(jìn)行勞動(dòng)的高等動(dòng)物,這是新華字典說的贵少,不是我說的呵俏。
??我覺得git命令還好,但是使用命令行來進(jìn)行諸如diff滔灶、rebase之類的操作普碎,實(shí)在有點(diǎn)反人類,工作中多用用工具還是很能提高效率的。比如JetBrains那一套里面集成的git工具,eclipse里面集成的git工具哮伟,tortoise git晒奕,source tree,這些都不錯(cuò)(我都用過唆鸡,最喜歡JetBrains全家桶涝影,雖然我用eclipse寫代碼)
??當(dāng)然,學(xué)習(xí)的時(shí)候争占,用一用命令會讓你對這些動(dòng)作又更清晰的認(rèn)知