一又兵、Git是什么带兜?
- 是一個(gè)開(kāi)源的分布式版本控制系統(tǒng)枫笛,可以有效、高速的處理從很小到非常 大的項(xiàng)目版本管理刚照。 Git 是 Linus Torvalds 為了幫助管理 Linux 內(nèi)核開(kāi)發(fā)而開(kāi)發(fā)的一個(gè)開(kāi)放源碼的版本控制軟件刑巧。
二、Git的安裝?
1. 下載Git
2. 下載完成后啊楚,打開(kāi)安裝包選好安裝的目錄吠冤,直接一直點(diǎn)擊 next> (其他都是默認(rèn)值),遇到Install直接進(jìn)行安裝恭理。
3. 驗(yàn)證Git的安裝正確拯辙,按下win鍵+r 打開(kāi)cmd(運(yùn)行窗口)輸入下列指令:
git --version
-
若安裝正確會(huì)出現(xiàn)下面的圖(1),若不正確請(qǐng)重新安裝颜价。
三涯保、Github賬號(hào)注冊(cè)--倉(cāng)庫(kù)創(chuàng)建
1. 進(jìn)入Github官網(wǎng),注冊(cè)賬號(hào)頁(yè)面周伦。
- Username 創(chuàng)建你的Github賬戶(hù)名
- Email 填寫(xiě)你的郵箱
- Password 你的登陸密碼
2. 注冊(cè)成功頁(yè)面夕春。
- 選擇Free
-
Continue 進(jìn)行下一步
點(diǎn)擊右上角+號(hào) 點(diǎn)擊進(jìn)入 New repository
3. 創(chuàng)建倉(cāng)庫(kù)
-
出現(xiàn)郵箱驗(yàn)證
點(diǎn)擊箭頭處驗(yàn)證
-
進(jìn)入New repository(創(chuàng)建新倉(cāng)庫(kù))
輸入倉(cāng)庫(kù)名如:test(測(cè)試)
- 進(jìn)入添加文件形成倉(cāng)庫(kù)
使用markdown語(yǔ)言進(jìn)行書(shū)寫(xiě) - 寫(xiě)完后點(diǎn)擊地下的commit new file完成倉(cāng)庫(kù)創(chuàng)建
四、建立Git與Github的配置
-
鼠標(biāo)右鍵桌面打開(kāi)Git Bash Here輸入以下代碼完成配置
- 一個(gè)寫(xiě)注冊(cè)名专挪,一個(gè)寫(xiě)郵箱
五及志、Git大致工作流程
1. 在硬盤(pán)中創(chuàng)建一個(gè)文件夾(git 倉(cāng)庫(kù)),右鍵Git Bash Here寨腔,接下來(lái)創(chuàng)建的所有文件都將放入里面
2. 下一步點(diǎn)擊下圖的紅標(biāo)處復(fù)制地址
3. 右鍵打開(kāi)(git 倉(cāng)庫(kù))的Git Bash Here,粘貼地址速侈,完成倉(cāng)庫(kù)的下載
這就是遠(yuǎn)程倉(cāng)庫(kù)東西的儲(chǔ)存到Git中
4. 同樣我們也可以在本地git 倉(cāng)庫(kù)中創(chuàng)建 c.txt 上傳,先進(jìn)入test文件夾中脆侮,然后由 工作目錄 上傳到 暫存區(qū)
5. 然后執(zhí)行g(shù)it commt上傳到 本地倉(cāng)庫(kù) 锌畸,進(jìn)入添加c.txt的注釋
6. 做完這些只是提交到了本地倉(cāng)庫(kù),如果想要提交到Github上的倉(cāng)庫(kù)靖避,我們要執(zhí)行g(shù)it push潭枣,出現(xiàn)
7. 之后讓你輸入你的Github用戶(hù)名,然后彈出一個(gè)讓你輸入密碼的對(duì)話(huà)框輸入密碼幻捏,完成上傳到 遠(yuǎn)程倉(cāng)庫(kù)
然后你就在Github的倉(cāng)庫(kù)中看到你的上傳和注釋
- 同理我們也可以將在遠(yuǎn)程倉(cāng)庫(kù)中添加或修改盆犁,點(diǎn)擊箭頭指的Create new file,添加文件名d.txt然后編輯篡九,點(diǎn)擊最下邊的綠色地方完成保存谐岁。接下來(lái),添加到我們的本地倉(cāng)庫(kù)榛臼,執(zhí)行輸入git pull,完成添加
總結(jié)圖
六伊佃、Git文件狀態(tài)
1.右鍵Git Bash Here,執(zhí)行g(shù)it init test,在git 倉(cāng)庫(kù)創(chuàng)建了test文件夾里面會(huì)有一個(gè).git文件夾(如果沒(méi)有點(diǎn)擊此電腦功能區(qū)的查看,在文件的擴(kuò)展名和隱藏的項(xiàng)目都打上對(duì)勾)
2.然后cd test進(jìn)入文件test中沛善,執(zhí)行touch init創(chuàng)建init文件
3.根據(jù)第五部分的總結(jié)圖我們知道git無(wú)非是 工作目錄-暫存區(qū)-本地倉(cāng)庫(kù)-遠(yuǎn)程倉(cāng)庫(kù) 的儲(chǔ)存航揉、提取、編譯金刁。那麼他們的轉(zhuǎn)換關(guān)系的執(zhí)行步驟是什么呢帅涂?
-
上傳文件init议薪,如圖
- 其中上傳init文件時(shí),可進(jìn)行修改執(zhí)行語(yǔ)句:vi init
進(jìn)入修改面然后就是通過(guò)我上面說(shuō)到的編輯命令 - 想要查看 工作目錄-暫存區(qū)-本地倉(cāng)庫(kù) 文件通過(guò)vi init修改后的區(qū)別可通過(guò)此圖
git diff --cached 查看本地倉(cāng)庫(kù)與暫存區(qū)儲(chǔ)存的區(qū)別
git diff 查看暫存區(qū)與工作目錄儲(chǔ)存的區(qū)別
git diff HEAD 查看本地倉(cāng)庫(kù)與工作目錄儲(chǔ)存的區(qū)別
七媳友、深入Git的儲(chǔ)存
1.同樣在git 倉(cāng)庫(kù)創(chuàng)建test文件夾(步驟一樣斯议,同時(shí)顯示.git文件),繼續(xù)創(chuàng)建一個(gè)echo文件名稱(chēng)a.txt包含內(nèi)容123
echo "123">a.txt
2. 上傳到暫存區(qū)
git add a.txt
- 暫存區(qū)只存儲(chǔ)了文件的名稱(chēng)和hash值
3. 通過(guò)命令取去查看暫存區(qū)存儲(chǔ)的內(nèi)容
git ls-files -s
- 得出的是hash內(nèi)容我們通過(guò)執(zhí)行
git cat-file -p (hash值如圖)
- 圖中hash值為190a(寫(xiě)前4為就可以)由查看暫存區(qū)得出
4. 下來(lái)進(jìn)行暫存區(qū)內(nèi)容創(chuàng)建文件夾提交到本地倉(cāng)庫(kù)
git commit -m'創(chuàng)建文件夾a.txt'
-
得到如圖醇锚,注意只有數(shù)列(暫存區(qū)為name a.txt哼御,對(duì)象庫(kù)為commit 41cb tree c490 blob 190a 為我們所得,其它的是我們創(chuàng)建的另一個(gè)b.txt所作的對(duì)比顯示 parent)
- 除了commit 對(duì)象焊唬,其它的commit都有一個(gè)或多個(gè)parent
八艇搀、Git分支
1> Git分支
1. 如果我們想看當(dāng)前test我們都有哪些提交?
- 執(zhí)行
git log
命令查看遞交完整內(nèi)容 - 我們?nèi)绻幌肟磆ash值則執(zhí)行
git log --oneline
就可看到hash值
2. 當(dāng)前我們只有一個(gè)分支求晶,那就是git幫我們創(chuàng)建的Master分支,通過(guò)執(zhí)行ll .git/refs/heads/
我們可以看到分支master
- 下來(lái)通過(guò)執(zhí)行
cat .git/refs/heads/master
來(lái)查看master的內(nèi)容(指的是最新的提交)衷笋,可以發(fā)現(xiàn)是一個(gè)hash值(為最新提交的hash值) - Git不允許空提交芳杏,但執(zhí)行
git commit --allow-empty -m'空提交'
就可以空提交執(zhí)行git log --oneline
可以看到內(nèi)容 - master指向的永遠(yuǎn)是最新的提交
3. 創(chuàng)建新分支和運(yùn)用
- 執(zhí)行
git branch dev
這時(shí)我們就創(chuàng)建了一個(gè)dev分支 - 執(zhí)行
git branch
查看我們的分支
dev
master
- 兩個(gè)分支前面有?號(hào)的代表我們?cè)谀囊粋€(gè)上面正進(jìn)行工作
- 切換分支,執(zhí)行
git checkout dev
切換到dev分支上 - 同時(shí)我們也有簡(jiǎn)單方法辟宗,執(zhí)行
git checkout -b dev
直接創(chuàng)建并轉(zhuǎn)到該分支下 - 我們也可以執(zhí)行
git log --oneline --decorate
來(lái)查看會(huì)有哪些分支爵赵,和這些分支在哪個(gè)commit上
總結(jié)小圖
4.遞交后分支的改變
- 通過(guò)圖片我們可以看出遞交了功能1和功能2,如果我們假定功能2有bug
- 我們需要在master上創(chuàng)建一個(gè)新分支進(jìn)行操作我們可以執(zhí)行
git branch bug_22 ad6a
分支后面是master指向commit的hash值ad6a - 我們?cè)谕ㄟ^(guò)
git checkout bug_22
跳轉(zhuǎn)到bug_22分支上泊脐,也就是在master上進(jìn)行操作 - 我們執(zhí)行
git log --oneline
查看所有內(nèi)容空幻,你會(huì)發(fā)現(xiàn)只有空提交和兩個(gè)創(chuàng)建文件的提交,其實(shí)這證明我們的這些都是在一個(gè)分支上面進(jìn)行的容客,證明bug_22也在master上建成的 - 下來(lái)執(zhí)行
git log --oneline --all
來(lái)查看全部?jī)?nèi)容秕铛,將會(huì)看到全部?jī)?nèi)容,執(zhí)行git long --oneline --all --decorate
可以看到分支名稱(chēng) - 下來(lái)遞交bug_22缩挑,執(zhí)行
git commit --allow-empty -m‘修改bug_22'
但两,因?yàn)閎ug其實(shí)是我們假設(shè)的,這里遞交的bug_22還是空提交 - 因?yàn)樘峤皇怯许樞虻墓┲茫宰屓藭?huì)有感覺(jué)是dev功能2的副提交谨湘,下來(lái)執(zhí)行
git log --oneline --all --decorate --graph
這里的意思使用圖形法進(jìn)行展示 - 這個(gè)就是bug修復(fù)好的提交但我們每次要查看有順序提交圖芥丧,要執(zhí)行很多命令紧阔,所以git給我們了一個(gè)別名可以讓我們,很快的得出
- 執(zhí)行
git config alias.logg "log --oneline --all --decorate --graph"
這樣我們下次只要執(zhí)行git logg
就可得出同樣的圖表展示
總結(jié)圖
- 圖中執(zhí)行
git checkout .
命令是续担,比如我們?cè)诠ぷ髂夸泴?duì)文件進(jìn)行了修改但覺(jué)得改的不對(duì)擅耽,我們想要回到add .遞交到暫存區(qū)的內(nèi)容,我們執(zhí)行此令就用暫存區(qū)的內(nèi)容將工作目錄覆蓋赤拒,然后在上面操作 - 同樣執(zhí)行
git checkout HEAD .
是本地倉(cāng)庫(kù)和暫存區(qū)中的覆蓋秫筏,看圖
2> stash命令
1. stash是把我們?cè)诠ぷ鲄^(qū)和暫存區(qū)做的修改诱鞠,臨時(shí)的放到一個(gè)地方,這個(gè)地方不是暫存區(qū)
- 因?yàn)槲覀円袚Q到a所以得知git告訴我們你的b可能被替換这敬,請(qǐng)你提交或者stash
- 我們執(zhí)行
git status
查看我們的工作狀態(tài)航夺,得知做了修改但未提交 - 下來(lái)我們執(zhí)行
git stash
,把我們?cè)诠ぷ髂夸浐蜁捍鎱^(qū)做的修改存到一個(gè)地方崔涂,執(zhí)行git status
會(huì)發(fā)現(xiàn)我們的工作目錄和暫存區(qū)和本地倉(cāng)庫(kù)內(nèi)容一致阳掐,非常干凈 - 同樣我們執(zhí)行
git stash list
來(lái)看我們存儲(chǔ)的東西,它會(huì)添加一些注釋 - 執(zhí)行
git stash show -p stash@{0}
就可查看我們添加的東西 - 我們也可以執(zhí)行
git stash pop
來(lái)將我們存到里面的東西拿出來(lái) - 執(zhí)行
cat b
查看我們正在操作的目錄缭保,可以看出有我們的修改 - 這主要用于我們工作中的突發(fā)狀況,出現(xiàn)a文件出現(xiàn)bug我們要去修改蝙茶,但我們正在操作的b文件做了一半不足于提交(怕備注不清楚艺骂,容易搞混),我們可以用stash作為中間橋梁
- 執(zhí)行
git stash drop stash@{0}
可以用來(lái)刪除這個(gè)stash
3> 分支合并
1. 我們先轉(zhuǎn)到master分支隆夯,執(zhí)行git checkout master
钳恕。執(zhí)行git merge b
將b分支合并到master上,這樣我們前面所說(shuō)master指向b分支蹄衷,下來(lái)master就有了b分支上面所有的修改了忧额。
因?yàn)閎分支在master上做過(guò)修改所以,所以合并時(shí)可以看到fast-forward提交
2. 我們?cè)賹分支也合并進(jìn)去愧口,用到的是三方合并睦番。
指:
- 當(dāng)前分支(提交)的內(nèi)容
- 要合并的分支(提交)內(nèi)容
3.共同的一個(gè)祖先提交的內(nèi)容
- 這也就介紹兩種合并一種快速的,一種三方合并的
4> 分支合并之沖突解決
1. 執(zhí)行git checkout master
轉(zhuǎn)到master上修改文件init存儲(chǔ)并提交
2. 轉(zhuǎn)到a上修改a的init文件同樣提交
3. 轉(zhuǎn)到master上合并這兩個(gè)init
- 紅線處說(shuō)合并有沖突在init文件上耍属,有了默指MERING不會(huì)幫我們提交
4. 我們可以用Git自帶的默指工具托嚣,執(zhí)行git mergetool
會(huì)給你推薦工具(不方便)我們點(diǎn)回車(chē),下來(lái)退出編輯頁(yè)面恬涧,問(wèn)你y/n 回答n注益。我們自己配置方便的工具
5. 在這里我們用到idea合并,下載并打開(kāi)
- 下來(lái)把我們的地址D:\Git 倉(cāng)庫(kù)\ck(我自己的)寫(xiě)進(jìn)去
- 打開(kāi)之后我們創(chuàng)建一個(gè)file名稱(chēng).gitignore
6. 打開(kāi)后溯捆,我們點(diǎn)擊左下角version control 打開(kāi)Git顯示里面有一個(gè)unversioned files里面是Git不能管理的東西丑搔,所以我們要在.gitignore中寫(xiě)一些東西
- 不打算讓Git管理的文件,可以寫(xiě)到這里面
7. ctrl+k開(kāi)始提交commit massge進(jìn)行添加說(shuō)明(內(nèi)容:添加gitignore)提揍,下來(lái)我們可以在左下角log看到commit的數(shù)形結(jié)構(gòu)啤月,右下角中
可以切換分支,現(xiàn)在我們就用master
-
下來(lái)我們開(kāi)始合并分支
-
點(diǎn)擊最終的merge changes劳跃,進(jìn)去選上我們要合并的分支a谎仲,點(diǎn)merge,他會(huì)檢測(cè)到?jīng)_突我們繼續(xù)點(diǎn)擊merge進(jìn)入這個(gè)
- 下來(lái)我們手動(dòng)進(jìn)行合并刨仑,點(diǎn)擊111和222中間兩個(gè)X號(hào)旁邊的箭頭郑诺,ctrl+z可以撤消夹姥,也就是放棄添加,添加完后點(diǎn)擊右下方Apply
- 下來(lái)點(diǎn)擊ctrl+k開(kāi)始提交辙诞,添加合并說(shuō)明辙售,下來(lái)可以查看左邊的init文件,可以看出里面已經(jīng)合并
-
我們也可以用sourcetree查看
出現(xiàn)合并分支a飞涂,這就是合并兩個(gè)沖突文件的合并
九旦部、認(rèn)識(shí)rebase
1> rebase
1. 我們先依靠前面所學(xué)的知識(shí),創(chuàng)建處在surcetree如圖的分支結(jié)構(gòu)
git init rbs //創(chuàng)建rbs文件倉(cāng)庫(kù)
cd rbs //切換到rbs倉(cāng)庫(kù)下
touch c0 //在master上執(zhí)行創(chuàng)建c0
git add . //放入暫存區(qū)
git commit -m'c0' //提交c0
touch c1
git add .
git commit -m'c1'
git branch dev //創(chuàng)建新分支dev
touch c2
git add .
git commit -m'c2'
touch c3
git add .
git commit -m'c3'
git checkout dev //切換到dev上執(zhí)行
touch c4
git add .
git commit -m'c4'
touch c5
git add .
git commit -m'c5'
git logg //我們之前命名的logg较店,以圖表形式展示
2. 先切換到master分支上士八,rebase也就是變基操作,如
我們本來(lái)c4和c5是由c1為基礎(chǔ)創(chuàng)建提交的梁呈,但我們經(jīng)過(guò)rebase婚度,將c4和c5接到c3后面,這就是變基操作
- 下來(lái)我們進(jìn)行操作官卡,把c5和c4變基到c3陕见,
- 執(zhí)行
git rebase --onto master master dev
,進(jìn)行變基味抖,其中第一個(gè)master表示在master上變基到c3后面,第二個(gè)為master dev表示dev比master多出的文件灰粮,如c4和c5仔涩,所以總的操作為把dev多于master的c4和c5變基到c3后面,我們通過(guò)sourcetree進(jìn)行對(duì)比 - 其中發(fā)現(xiàn)c4和c5的hash值也發(fā)生了改變粘舟,因?yàn)閏ommit的hash值跟父parent有關(guān)熔脂,既然變基操作改變了父parent,那么commit的hash值也改變了柑肴,但提交的修改內(nèi)容未改變
- 下來(lái)我們發(fā)現(xiàn)master指向的是c3霞揉,dev指向的是c5',我們要讓master也指向c5'(通過(guò)rebase晰骑,c3和c5有了共同的提交線适秩,master和dev在同一上面),先切換到master上硕舆,執(zhí)行
git merge dev
進(jìn)行默指秽荞,因?yàn)樵谕痪€上所以Git用Fast-forward的默指命令
總結(jié)圖
其中rebase是和merge做對(duì)比用的
- 對(duì)比兩者rebase更干凈,如果我們想讓分支變得更簡(jiǎn)潔抚官,就用rebase
- 當(dāng)然如果我們的遞交push到遠(yuǎn)程倉(cāng)庫(kù)了扬跋,那么我們最好不要用rebase
2> 交互式rebase
建議先看之后的內(nèi)容reset命令再回過(guò)來(lái)看這片內(nèi)容
1. 交互式rebase
-
首先我們創(chuàng)建一個(gè)交互式環(huán)境,如圖
切換到dev分支上
- 下來(lái)執(zhí)行
git rebase -i --onto master master dev
來(lái)進(jìn)行交互式pick提交凌节,接上去 - 其中還分為很多種類(lèi)钦听,下來(lái)我們執(zhí)行
git reset -- hard 3ef5
將它還原到上一提交洒试,也就是圖1 - 下來(lái)我們?nèi)タ纯雌渌N類(lèi),執(zhí)行
git rebase -i --onto master master dev
朴上,進(jìn)入這個(gè) - hash值旁邊是命令的選項(xiàng)垒棋,下來(lái)我們介紹這些命令
p;pick=應(yīng)用這個(gè)提交
r;reword=修改提交的說(shuō)明
e;edit=可以修改提交,可以把提交拆分成好幾個(gè)余指,在進(jìn)行rebase
s;squash=合并提交捕犬,比如我們可以把d1和d2合并到d0再提交
f;fixup=在同條件與squash一樣,但fixup會(huì)丟棄d1的說(shuō)明酵镜,squash會(huì)保留
x;exec=執(zhí)行一個(gè)命令用來(lái)測(cè)試編譯或運(yùn)行的成功
d;drop=可以去掉某個(gè)提交碉碉,比如把d0前面的pick改為d,則b0將不會(huì)rebase到m2后邊
- 這次我們把d1前面的pick改為r淮韭,修改d1的說(shuō)明垢粮,改為b111
下來(lái)我們接著用這些命令,操作一樣執(zhí)行git reset -- hard 3ef5
將它還原靠粪,再執(zhí)行git rebase -i --onto master master dev
選取其他命令 - 我們選用e蜡吧,修改d1添加一個(gè)文件b1-0將他們整體合并rebase到m2后
git commit --amend
提交一個(gè)新的文件進(jìn)去 - 繼續(xù)我們的命令使用,先完成上述還原操作占键,和命令選擇操作昔善,我們使用命令s,將d1和d2前面的改為s,出現(xiàn)
git log
查看 - 下來(lái)還原铃岔,并進(jìn)入命令選擇,將d1前面改為d返咱,去掉d1文件
這就是交互式的rebase讓我們有更多的命令去選,完成一些強(qiáng)大的功能牍鞠,但push上去的commit最好別用rebase咖摹,會(huì)讓提交更亂
3> cherry-pick
-
cherry-pick
命令是把某個(gè)提交所對(duì)應(yīng)的修改應(yīng)用到我們當(dāng)前的分支上 - 比如我們用交互式rebase環(huán)境進(jìn)行也就是圖1,我們先切換到master分支上难述,然后執(zhí)行
ll
查看里面只有m0 m1 m2文件萤晴,我們想要d1應(yīng)用到我們的master分支上,執(zhí)行git cherry-pick 369d
就可以了 - 因此我們想用哪個(gè)提交的修改胁后,cherry-pick可以直接幫助我們應(yīng)用過(guò)來(lái)
十硫眯、遠(yuǎn)程分支
1> 遠(yuǎn)程分支
1.先打開(kāi)Github創(chuàng)建一個(gè)新倉(cāng)庫(kù)git-test和加入一個(gè)README文件,克隆地址
- 打開(kāi)git將遠(yuǎn)程倉(cāng)庫(kù)的東西克隆下來(lái)择同,執(zhí)行
git clone 復(fù)制的地址
- 執(zhí)行
cd git-test
進(jìn)入git-test里面两入,同時(shí)再用sourcetree將git-test打開(kāi) - 執(zhí)行
git branch -a
既能查看本地分支也能查看遠(yuǎn)程分支,其中origin代表了我們的哪個(gè)遠(yuǎn)程倉(cāng)庫(kù)
2. 我們?cè)贕ithub中創(chuàng)建一個(gè)問(wèn)件c0敲才,提交備注為c0
- 執(zhí)行
git fetch
進(jìn)行遠(yuǎn)程下載裹纳,在執(zhí)行git merge origin/master
得到 - 我們?cè)僭谶h(yuǎn)程倉(cāng)庫(kù)建一個(gè)c1文件择葡,這次我們執(zhí)行
git pull
一開(kāi)始我們提到過(guò),你會(huì)發(fā)現(xiàn)它代替了git fetch和git merge origin/master兩個(gè)命令
2>跟蹤分支
1. 跟蹤分支是在本地分支和遠(yuǎn)程分支建立了一種關(guān)系剃氧,git pull就是完成遠(yuǎn)程更新和跟蹤遠(yuǎn)程的master分支將它merge到本地master分支上敏储,同樣git push也是使用跟蹤提交到遠(yuǎn)程倉(cāng)庫(kù)
- 執(zhí)行
git branch -vv
就可以查看到master的跟蹤分支,就是origin/master
2. 在GitHub中創(chuàng)建一個(gè)dev分支朋鞍,執(zhí)行git fetch
更新到本地
- 再執(zhí)行
git checkout dev
轉(zhuǎn)到dev分支git checkout dev
命令是基于遠(yuǎn)程的dev分支建立本地的dev并轉(zhuǎn)到dev中,并將遠(yuǎn)程的dev分支設(shè)置為本地dev分支的跟蹤分支 - 如果我們?cè)赿ev上做修改已添,push時(shí)他就會(huì)提交到遠(yuǎn)程的dev上,同理master也一樣
十一滥酥、Git的reset命令和revert命令
1> reset命令
執(zhí)行
git reset chash --[.|filename]
是重置我們的暫存區(qū)更舞,吧commit內(nèi)容覆蓋過(guò)去
執(zhí)行git reset --soft chash
,更新commit的hash值坎吻,不會(huì)更新暫存區(qū)和工作區(qū)的
執(zhí)行git reset --mixed chash
缆蝉,把commit覆蓋到暫存區(qū),但不會(huì)更改工作目錄
執(zhí)行git reset --hard chash
瘦真,重置commit刊头,重置暫存區(qū)和工作區(qū)
1. 我們創(chuàng)建一個(gè)rst倉(cāng)庫(kù),創(chuàng)建一個(gè)c0文件诸尽,暫存然后提交原杂,再創(chuàng)建一個(gè)c1文件,暫存您机。執(zhí)行git ls-files -s
來(lái)查看現(xiàn)在暫存區(qū)的內(nèi)容
現(xiàn)在暫存區(qū)有c1和c0兩個(gè)暫存文件
- 執(zhí)行
git ls-tree master
污尉,來(lái)查看commit里面,有一個(gè)c0文件 - 執(zhí)行
ll
往产,查看工作目錄里面有c0和c1兩個(gè)文件 - 執(zhí)行
git status
來(lái)查看狀態(tài),c1沒(méi)提交 - 執(zhí)行
git reset master
或git reset -- .
某宪,再執(zhí)行git status
來(lái)查看狀態(tài)仿村,c1變?yōu)槲锤櫟奈募前裞ommit覆蓋到了暫存區(qū)兴喂,所以c1就沒(méi)有了蔼囊,可以通過(guò)查看暫存區(qū),發(fā)現(xiàn)只有c0衣迷,別commit覆蓋了 -
我們可以得出git reset是git add . 的反向操作
2. 下來(lái)我們?cè)俟ぷ髂夸浵聦1文件暫存并提交畏鼓,執(zhí)行git log --oneline --all --decorate --graph
,來(lái)看提交樹(shù)
- 比如我們發(fā)現(xiàn)提交c1是提交說(shuō)明寫(xiě)錯(cuò)了不行該寫(xiě)c1行該寫(xiě)新提交文件c1
- 我們讓master指向之前提交的c0的commit壶谒,再進(jìn)行提交去修改提交內(nèi)容
- 所以執(zhí)行
git reset --soft master^
或git reset --soft 上一個(gè)提交的hash值(c0的)
云矫,下來(lái)我們看一下?tīng)顟B(tài),發(fā)現(xiàn)c1處于暫存區(qū)等待提交汗菜,然后進(jìn)行提交 - 當(dāng)讓Git也給我們提供一個(gè)簡(jiǎn)單的修改最近提交方式让禀,執(zhí)行
git commit --amend -m'c1'
挑社,于是我們將提交說(shuō)明新提交文件c1又改為c1
3. 下來(lái)看下一個(gè)命令把commit的內(nèi)容覆蓋暫存區(qū),但不會(huì)更改工作區(qū)的命令
- 執(zhí)行
git reset --mixed master^
巡揍,把master的上一個(gè)提交的c0覆蓋過(guò)去痛阻,然后我們?cè)俨榭礌顟B(tài)發(fā)現(xiàn)c1變?yōu)槲锤櫟模绻覀兛垂ぷ髂夸浝锩娴膬?nèi)容ll
我們發(fā)現(xiàn)c1繼續(xù)存在 - 下來(lái)我們?cè)賹1提交
4.下來(lái)說(shuō)git reset --hard master^
腮敌,你會(huì)發(fā)現(xiàn)狀態(tài)是干凈的阱当,工作目錄,暫存區(qū)糜工,以及commit都保持一致
- 一切回歸上一個(gè)c0弊添,c1文件刪除
2> revert命令
1. 我們繼續(xù)使用交互式rebase的文件環(huán)境,圖1啤斗,切換到dev分支下表箭,比如我們不想提交d2,執(zhí)行git revert 3ef5
得
- revert“d2”是撤銷(xiāo)的
- 我們發(fā)現(xiàn)d0有問(wèn)題钮莲,我們執(zhí)行revert免钻,我們發(fā)現(xiàn)d0撤銷(xiāo)了
2. 下來(lái)我們回到最初,圖1崔拥,執(zhí)行把dev默指到master上
如果我們發(fā)現(xiàn)合過(guò)來(lái)的代碼有問(wèn)題
- 如果我們執(zhí)行revert會(huì)發(fā)現(xiàn)報(bào)錯(cuò)
- 我們執(zhí)行
git show b362
极舔,發(fā)現(xiàn)指向兩個(gè)merge一個(gè)m2一個(gè)d2,如果我們要回到dev進(jìn)行的merge链瓦,則執(zhí)行git revert -m 2 b362
拆魏,就可以了 - 其實(shí)這里面可以用reset進(jìn)行修改,但我們說(shuō)了如果push了慈俯,那么revert將會(huì)更好渤刃,因此在一些已經(jīng)push,我們更多用的式revert
學(xué)到這里我們Git已經(jīng)贴膘,可以進(jìn)行一些東西的操作了
**介紹兩本學(xué)習(xí)Git的書(shū)卖子,Pro Git 和 Git權(quán)威指南 **