操作指南)
目錄一預(yù)備1.1 Git 介紹1.2 Git 下載安裝二Git基本操作2.1 創(chuàng)建并配置本地倉庫2.2 工作區(qū)、暫存區(qū)、版本庫2.3 添加文件2.4 修改文件2.5 版本回退2.6 撤銷修改2.7 刪除文件三分支管理3.1 關(guān)于分支3.2 分支操作3.3 刪除分支3.4 合并沖突3.5 分支模式3.6 分支策略3.7 bug分支3.8 強(qiáng)制刪除分支一預(yù)備1.1 Git 介紹相信各位都有了解這個(gè)場景老板要你寫一個(gè)技術(shù)文檔你提交了第一版老板說有瑕疵需要修改然后提交了第二版接著是第三版、第四版等等之后當(dāng)你提交到第十版時(shí)老板突然說“還是用第一版吧”。這種時(shí)候我們?nèi)绻轻槍Φ谝话娴谋旧磉M(jìn)行后面版本的修改這種時(shí)候我們就沒辦法把第十版恢復(fù)成第一版了所以我們一般會(huì)將前置版本進(jìn)行一個(gè)復(fù)制直接修改復(fù)制后的文檔作為最新的版本。但是一個(gè)公司不止一個(gè)員工每個(gè)員工也不止一個(gè)老板所以當(dāng)版本一多維護(hù)這些版本也就變的相當(dāng)困難比如每個(gè)版本修改的具體內(nèi)容、時(shí)間等等所以版本控制器就誕生了。版本控制器作用是記錄每次版本的修改以及版本迭代的一個(gè)管理系統(tǒng)。Git 就是目前最主流的版本控制器。對于開發(fā)人員來說Git控制的就是項(xiàng)目中的源代碼文檔。注意事項(xiàng)對于Git記錄每次修改的內(nèi)容只針對 .txt、網(wǎng)頁html以及各種源程序代碼這種文本形式的文件但對于圖片音頻視頻這種抽象的二進(jìn)制文件無法準(zhǔn)確追蹤具體的修改內(nèi)容。1.2 Git 下載安裝①Centos安裝很簡單執(zhí)行下面命令即可sudo yum -y install git //下載安裝Gitgit --version //查看Git版本②Ubuntu安裝以 Release 22.04為參考部分云服務(wù)器有時(shí)候會(huì)內(nèi)置Git可以先直接在命令行輸入git看輸出結(jié)果下面是有Git 的結(jié)果如果沒有g(shù)it則輸入下面指令安裝sudo apt-get install git -ygit --version順便一提下面的命令可以快速查看Ubuntu版本號lsb_release -a③Windows安裝可以參考視頻3.安裝git和圖形化界面工具_(dá)嗶哩嗶哩_bilibili建議可以先參考視頻在Windows本地完成Git的安裝然后和視頻里一樣至少完成一次代碼的add、commit和push提交對Git的理解和學(xué)習(xí)有很大幫助二Git基本操作2.1 創(chuàng)建并配置本地倉庫只要有權(quán)限Git是可以控制電腦上的額所有格式的文件的但是如果Git直接對電腦上的文件進(jìn)行管理肯定不行所以我們必須要把需要管理的文件放在Git的倉庫中進(jìn)行管理首先是創(chuàng)建本地倉庫git init一個(gè)本地倉庫創(chuàng)建出來還不能直接用需要先新增兩個(gè)配置項(xiàng)用戶名稱name、用戶email地址git config user.name 名稱填在這里 git config user.email 同上 git config -l如果需要?jiǎng)h除配置項(xiàng)需要使用命令git config --unset user.name git config --unset user.email添加或刪除配置還有一個(gè)--global可選選項(xiàng)這表示這臺(tái)機(jī)器上所有的Git倉庫都會(huì)用這個(gè)配置git config [--global] user.name git config [--global] user.email git config [--global] --unset user.name git config [--global] --unset user.email2.2 工作區(qū)、暫存區(qū)、版本庫我們先在這個(gè)目錄下touch 一個(gè) ReadMe.txt 文件作為被管理文件讓git來管理但是僅僅在該目錄下touch一個(gè)文件這個(gè)文件還不能被Git管理因?yàn)檫@個(gè)目錄還不是本地倉庫真正的本地倉庫其實(shí)是 .git 文件也叫做版本庫。當(dāng)然也不能直接進(jìn)入 .git 目錄進(jìn)行操作①工作區(qū)我們把 ReadMe.txt 寫在我們這個(gè)目錄下這個(gè)目錄就稱為“工作區(qū)”。對工作區(qū)的操作有三種添加文件也就是touch也算是對工作區(qū)的修改修改文件文件數(shù)量名稱不變文件內(nèi)容改變也算修改了工作區(qū)刪除文件當(dāng)完成上面的操作之后我們就將工作區(qū) add 進(jìn)暫存區(qū)stage中②暫存區(qū)暫存區(qū)也可以叫索引存在于 .git 目錄里但是放進(jìn)暫存區(qū)里還不算將工作區(qū)內(nèi)容真正寫入版本庫里還需要通過一個(gè) commit 操作將暫存區(qū)操作提交到 master 分支下這個(gè)后面再詳細(xì)介紹③版本庫前面已經(jīng)介紹過 .git 文件就是版本庫不過這個(gè)版本庫不單單只是一個(gè)“ 庫 ”里面還有很多用于git操作的可執(zhí)行文件等等使用 tree 命令可以查看④附加object 對象庫對象庫也存在于版本庫中作用是用于保存對工作區(qū)的修改內(nèi)容比如我添加了一個(gè)文件、修改了一個(gè)文件這些操作都會(huì)額外維護(hù)到這個(gè)對象庫里里面有很多git對象每個(gè)對象都存儲(chǔ)著對工作區(qū)的修改。每當(dāng)工作區(qū) add 一次都會(huì)額外添加一個(gè) git 對象放到這個(gè)對象庫里。所以前面說暫存區(qū)也可以叫做索引也是因?yàn)闀捍鎱^(qū)存的也不是工作區(qū)文件的一比一復(fù)制而是一個(gè)個(gè)的指針指向?qū)ο髱熘忻看蝍dd對應(yīng)的git對象2.3 添加文件①一次完整的提交使用命令如下git add file //支持多個(gè)文件文件名之間用空格分開 git add . //一次提交所有文件 git commit -m 輸入自定義提交備注 //將暫存區(qū)文件全部提交進(jìn)版本庫然后可以通過下面命令打印提交記錄git log不過如果提交次數(shù)過多也可以加個(gè)參數(shù)讓時(shí)間由早到晚順序不變打印記錄git log --prettyoneline②查看 .git 文件當(dāng)進(jìn)行一次提交后再 tree .git 可以發(fā)現(xiàn)確實(shí)多了很多東西由于很大就不截圖了只展示部分其中多了add前沒有的index文件并且如果打印HEAD文件可以發(fā)現(xiàn)確實(shí)是指向了master文件前面也說了index和master里面也并不是存的原原本本的文件而是針對這些文件修改內(nèi)容的索引為當(dāng)前最近一次提交的提交ID然后我們可以用下面命令來查看詳細(xì)信息git cat-file -p 對象庫id①觀察這個(gè)id可以發(fā)現(xiàn)這個(gè)id的前2個(gè)字符對應(yīng) .git 目錄里objects目錄的一個(gè)子目錄然后后面的字符對應(yīng)文件名通過命令查看這個(gè)id可以查找到最近一次提交的信息②與上面一樣里面的id也可以找到對應(yīng)的文件比如圖片里查找綠色標(biāo)記id就找到了我們提交的三個(gè)文件③每個(gè)提交的文件也有對應(yīng)的id查找這個(gè)id就可以查看該文件內(nèi)容如圖2.4 修改文件Git可以追蹤管理文件但Git管理的并不是文件本身而是對文件的修改操作下面命令可以查看目前倉庫的狀態(tài)也就查看上一次提交到該命令執(zhí)行時(shí)是否對文件進(jìn)行過修改git status由于代碼不斷增多我們是沒辦法自己準(zhǔn)確記得針對哪些文件的哪些修改的所以git也提供了部分命令讓我們可以查看暫存區(qū)和工作區(qū)的差異或者版本庫和工作區(qū)的差異git diff 文件名 //查看工作區(qū)與暫存區(qū)差異 git diff READ -- 文件名 //查看工作區(qū)與版本庫差異當(dāng)修改后也需要通過添加文件的add和commit命令分別添加進(jìn)暫存區(qū)和版本庫才能完成修改同步2.5 版本回退Git可以控制版本當(dāng)前版本出現(xiàn)問題需要回退到以前版本Git肯定也能回退版本本質(zhì)是回退版本庫的內(nèi)容git reset [--soft | --mixed | --hard] [HEAD]--soft這個(gè)參數(shù)表示該回退操作不影響工作區(qū)和暫存區(qū)內(nèi)容只修改版本庫內(nèi)容--mixed為默認(rèn)項(xiàng)表示不影響工作區(qū)內(nèi)容對暫存區(qū)和版本庫內(nèi)容進(jìn)行回退常用于需要重寫修改備注情況--hard將三個(gè)區(qū)的內(nèi)容全部回退不過由于會(huì)覆蓋掉工作區(qū)內(nèi)容導(dǎo)致未add的代碼消失所以該參數(shù)需要慎用HEAD指定需要回退的commit id下面是hard的演示如果我后悔了想回退回退怎么辦呢同樣也可以通過commit id 回退回退但是我們屏幕是有限的commit id又很長一旦顯示的內(nèi)容過多可能我們就沒法找到以前查看的commit id了所以我們可以通過下面命令查看歷史的git命令效果類似命令行的history命令git reflog由于我們的回退操作只是更改了HEAD指針指向的commit對象內(nèi)容所以回退操作的執(zhí)行速度很快2.6 撤銷修改有下面三種情況我們一一講解①我在工作區(qū)寫了代碼還沒add也就是想讓代碼恢復(fù)到上一個(gè)版本我們可以直接手動(dòng)刪除新加的代碼但是這樣肯定不現(xiàn)實(shí)一來浪費(fèi)時(shí)間二來可能會(huì)誤刪正確代碼導(dǎo)致bug雖然我們可以通過git diff 區(qū)對比差異然后刪但是也非常浪費(fèi)時(shí)間同時(shí)不建議使用 git reset --hard 強(qiáng)制回退因?yàn)槲覀円部赡芏啻蝍dd進(jìn)了暫存區(qū)但是還沒有commit也會(huì)導(dǎo)致代碼丟失所以我們可以使用下面命令讓工作區(qū)文件回到最近一次add 或 commit 的狀態(tài)git checkout -- [file]②已經(jīng)add了但還沒有commit這種情況下是工作區(qū)內(nèi)容和暫存區(qū)內(nèi)容同步了所以不能再使用 git checkout 回退所以我們得先使用git reset --mixed 讓暫存區(qū)和版本庫同步由于 --mixed 是默認(rèn)項(xiàng)可以省略然后再使用 checkou 回退同第一種情況③已經(jīng)add了并且也 commit 了這種情況我們只能通過 2.5 版本回退介紹的使用 git reset --hard HEAD 回退到上一個(gè)版本了不過只限于把我們本地的版本庫同步到遠(yuǎn)程后面章節(jié)會(huì)介紹附加關(guān)于git reset 的HEAD參數(shù)再回退情況下這個(gè)參數(shù)可以不原原本本復(fù)制前面版本的那一大串字符串比如HEAD 表示當(dāng)前版本HEAD^上一個(gè)版本HEAD^^上上一個(gè)版本也可以用 ~數(shù)字 表示HEAD~0表示當(dāng)前版本HEAD~1表示上一個(gè)版本HEAD~2上上一個(gè)版本2.7 刪除文件我們有兩種方法方法一方法二可以將上面三步縮短為兩步git rm filename三分支管理3.1 關(guān)于分支前面我們說過./git 目錄里面有一個(gè) HEAD 文件里面保存了master而這個(gè)master里面保存的是對于最近一次提交的git對象指針我們每一次提交都可以看作一個(gè)分支有了master指針我們就可以通過它找到我們的每一次提交不是說master指針指向的是最新的提交嗎前面的提交怎么拿到呢如下圖3.2 分支操作①創(chuàng)建分支首先是查看我們本地的分支git branch我們前面說HEAD指向的是master指針現(xiàn)在可以改正說法了HEAD 指向的是master分支這也代表著其實(shí)HEAD也可以指向其它的分支HEAD指向的分支就是我們目前的工作分支創(chuàng)建分支就是在查看分支命令基礎(chǔ)上在后面加上名字即可git branch dyk可以看到我們創(chuàng)建的 dyk 分支里面也存了一個(gè)提交id和master一樣因?yàn)閯?chuàng)建分支時(shí)默認(rèn)會(huì)也會(huì)填充最近的一次提交id②切換分支前面我們撤銷修改命令里面有兩個(gè)橫杠現(xiàn)在把兩個(gè)橫杠去掉就變成了切換分支命令啦git checkout dyk此時(shí) * 位置改變了并且顏色也改變了誰是目前的工作分支一目了然③查看分支差異我們先在dyk分支上提交修改然后切換回master分支這是因?yàn)棰芎喜⒎种ё詈缶褪菍⑽覀兊膍aster分支和dyk分支合并讓其它分支的修改同步到master分支上git merge dyk此時(shí)master的指針也指向了dyk指向的提交id了3.3 刪除分支刪除分支用到的命令為git branch -d dyk注意如果處于某個(gè)分支下再刪除這個(gè)分支會(huì)報(bào)錯(cuò)3.4 合并沖突問題什么是合并沖突解答簡單來說就是在master分支對ReadMe文件做了修改然后同時(shí)在dyk分支上也對ReadMe文件做了修改這時(shí)我們再去嘗試合并的話git 就不知道應(yīng)該保留哪一個(gè)分支的結(jié)果了這個(gè)問題和多線程安全問題很類似我們先創(chuàng)建切換一個(gè)分支然后在dyk上對ReadMe進(jìn)行修改然后切換回master分支再進(jìn)行修改此時(shí)再嘗試合并會(huì)報(bào)錯(cuò)并會(huì)修改ReadMe文件顯示沖突內(nèi)容此時(shí)我們需要我們開發(fā)人員自己來解決覺得需要保留哪個(gè)代碼此時(shí)我們在master分支下刪掉沖突內(nèi)容并再次commit提交一定要重新提交即可附加如何更直觀看到分支合并的情況呢使用git log 命令的參數(shù)即可git log --graph --prettyoneline --abbrev-commit可以看到完整的分支線內(nèi)容包括歷史提交3.5 分支模式我們再創(chuàng)建一個(gè)分支然后對ReadM文件修改并提交然后我們再切回master并合并再打印日志這時(shí)候可以發(fā)現(xiàn)我們打印的日志顯示此次提交不顯示具體的提交信息就是無法知道這次提交是正常commit提交的還是用merge合并出來的會(huì)丟失部分分支信息而在上面的合并沖突場景下我們明顯能看到屏幕坐標(biāo)有兩條岔開后又合并的線這是因?yàn)槟欠N場景下就不是 Fast-forward 模式了所以能看到合并的信息所以 Git 鼓勵(lì)我們禁用 Fast-forward 模式在 merge 命令添加參數(shù)即可git merge --no-ff -m 日志寫這里 dyk1然后切換回master分支不使用 Fast-forward 模式進(jìn)行合并此時(shí)再打印日志就會(huì)顯示合并信息了通過日志可以看到禁用 Fast-forward 模式就是在master分支上重新生成了一次commit提交然后一并將 dyk 分支也同步到這個(gè)master提交上來了3.6 分支策略在實(shí)際開發(fā)場景中我們寫的代碼肯定是要經(jīng)過層層測試和驗(yàn)證最終達(dá)到要求才能放生產(chǎn)環(huán)境里去的而對于Git來說我們上面的master分支就是生產(chǎn)環(huán)境其它的分支就是開發(fā)和測試環(huán)境。所以分支策略就是指現(xiàn)在其它分支上寫代碼最后經(jīng)過層層測試再把分支 上的代碼合并到master分支上作為發(fā)布版本。注意我們的分支不一定只能和master分支合并分支與分支之間也可以進(jìn)行合并就好比一家公司下有很多部門每個(gè)部門下也有很多小組一樣類似多叉樹。3.7 bug分支我們使用程序或者app時(shí)或多或少都會(huì)遇到過閃退卡死等等情況因?yàn)槲覀兊纳a(chǎn)環(huán)境線上環(huán)境也不是100%穩(wěn)定的也就是master分支也可能會(huì)有bug這種情況的解決辦法一般是臨時(shí)創(chuàng)建一個(gè)新的分支專門來修復(fù)bug。然后合并分支最后刪除或備份臨時(shí)分支。不過這樣合并分支的操作我們前面已經(jīng)做過很多次了這個(gè)小章節(jié)主要是了解一下另一種場景下面我們就來模擬一下簡單場景我們在一個(gè)分支進(jìn)行了部分代碼開發(fā)還沒有提交這時(shí)候master中有了bug先創(chuàng)建dyk2分支此時(shí)還未提交切回master的話會(huì)發(fā)現(xiàn)這時(shí)候我們不想讓dyk2的修改影響master需要使用另一個(gè)命令git stash //表示將工作區(qū)內(nèi)容進(jìn)行保存保存到哪里了呢保存在了.git 目錄下不過需要注意的是只有被Git管理追蹤的文件才能進(jìn)行保存操作比如我直接在目錄下touch一個(gè)file3文件不進(jìn)行任何操作直接git stash的話不會(huì)被存儲(chǔ)然后我們新建一個(gè)專門修復(fù)bug的分支然后就是正常的合并操作了我們在這個(gè)分支里完成對ReadMe文件的修改然后和master合并然后刪除這個(gè)分支bug搞定之后我們還得接著回dyk2分支去開發(fā)開發(fā)完成之后我們提交不過此時(shí)因?yàn)閷aster分支bug的修改沒有同步到dyk2上同時(shí)dyk2上新開發(fā)的代碼也沒有同步到master分支上這個(gè)時(shí)候如果master分支和dyk2合并很大可能會(huì)出現(xiàn)沖突但如果我們?nèi)ナ謩?dòng)解決沖突的話也有很大可能產(chǎn)生新的bug。但是我們的目的是保證master的穩(wěn)定性所以我們可以反過來先讓master和我們的分支去合并直接在我們自己的分支上做出修改讓合并沖突的問題在dyk2分支上進(jìn)行修改確認(rèn)無誤后再與主master合并即可。然后就是在dyk2上完成修改并提交最后切回master合并就可以了最后可以選擇刪除 fix_bug分支不過有些公司可能會(huì)要求備份3.8 強(qiáng)制刪除分支開發(fā)過程中有很多新功能會(huì)被加入進(jìn)來同樣的也肯定會(huì)有新功能被移除那么假如我正在開發(fā)一個(gè)新功能然后這個(gè)功能被砍了我不得已只能刪除這個(gè)分支但如果我們在這個(gè)分支開發(fā)了一些內(nèi)容并且也commit提交了使用git branch -d 命令刪除的話會(huì)報(bào)錯(cuò)然后切回master分支然后刪除dyk2分支然后后面還給了我們一個(gè)提示說如果我們確認(rèn)要?jiǎng)h除這個(gè)需要運(yùn)行這個(gè)命令其實(shí)就是把小寫d改成了大寫D