Git的反悔操作(一)

概述

這次主要來講講Git的反悔操作,自己平時(shí)在寫代碼的過程中經(jīng)常會(huì)出現(xiàn)想要棄用所有的改動(dòng)或回滾到上一次commit的情況。Git上的反悔操作有resetrebaserevert等,每個(gè)操作各有區(qū)別和對(duì)應(yīng)的使用場(chǎng)景,這里做下總結(jié)。

Git的反悔操作有兩大類:

  • 撤銷改動(dòng) ( Undoing Change )
  • 重寫歷史 ( Rewriting History )

文章大部分翻譯于 Undoing ChangesRewriting history,并結(jié)合了自己的一些理解和補(bǔ)充。

撤銷改動(dòng)(Undoing Change)

git checkout

git checkout有三個(gè)不同的功能:切換分支、回滾至某個(gè)commit、回滾一個(gè)文件至某個(gè)commit。切換分支是git checkout最常見的功能,不做介紹,這里主要介紹下它在撤銷文件改動(dòng)上的應(yīng)用。

回滾至某個(gè)commit

git chekcout <commit>

上面的命令是回滾到工作目錄中指定的 commit 上,這是一個(gè) 只讀 操作,不會(huì)影響到當(dāng)前工作區(qū)的狀態(tài),它在你查看舊版本的文件時(shí)不會(huì)損壞你的代碼倉庫。通常,HEAD指向master分支或其他本地分支,當(dāng)使用git checkout回滾到以前的 commit 時(shí),HEAD就不再指向某個(gè)分支了,而是直接指向一個(gè)commit,這時(shí)就叫做detached HEAD狀態(tài)。

切換到detached HEAD狀態(tài)時(shí),會(huì)有一個(gè)警告。

警告

這個(gè)警告是告訴你,你現(xiàn)在做的所有事情與你開發(fā)項(xiàng)目的其余工作區(qū)是分離的,即所有的改動(dòng)與本地倉庫的任一分支都無關(guān),不會(huì)影響到其他的分支的狀態(tài)。如果你準(zhǔn)備在detached HEAD狀態(tài)下開發(fā)新的feature,那將會(huì)沒有分支允許你回退這里,當(dāng)你不可避免地切換到其他分支時(shí),將沒有任何辦法引用到這個(gè)feature。你可以把detached HEAD狀態(tài)看作是正在一個(gè)未命名的分支上。

HEADdetached HEAD 的區(qū)別可以參考 How can I reconcile detached HEAD with master/origin?

將英文翻譯為中文經(jīng)常會(huì)詞不達(dá)意,很難把握,建議還是看英文原文:)。

示例

假設(shè)你正在進(jìn)行一次瘋狂的重構(gòu),但現(xiàn)在你不確定是否要繼續(xù)下去。這時(shí)你想要看一下開始這次重構(gòu)之前項(xiàng)目原來的樣子,首先你需要找到你想要查看的版本的ID。

git log --oneline

假設(shè)你的項(xiàng)目歷史看起來像下面這樣:

b7119f2 Continue doing crazy things
872fa7e Try something crazy
a1e8fb5 Make some important changes to hello.py
435b61d Create hello.py
9773e52 Initial import

你可以使用git checkout查看Make some important changes to hello.py這次commit,如下:

git checkout a1e8fb5

這讓你的工作區(qū)切換到了a1e8fb5comimit的狀態(tài)。你可以查看文件、編譯項(xiàng)目、運(yùn)行測(cè)試用例,甚至編輯文件,完全不用擔(dān)心丟失項(xiàng)目“當(dāng)前”的狀態(tài),你在這里做的所有修改都不會(huì)被保存到項(xiàng)目中。當(dāng)你想要繼續(xù)那次瘋狂的重構(gòu)時(shí),你需要回到項(xiàng)目的“當(dāng)前”狀態(tài)。

git checkout master

回滾一個(gè)文件至某個(gè)commit

git checkout <commit> <file>

回滾一個(gè)文件到以前的一個(gè)版本,這個(gè)操作會(huì) 影響 當(dāng)前工作區(qū)的狀態(tài)。

你可以在一個(gè)新的快照中重新提交這個(gè)舊版本,當(dāng)然也包含其他任何文件。實(shí)際上,checkout的這個(gè)用法和revert類似,只不過是僅針對(duì)一個(gè)文件。

示例

如果你只對(duì)單個(gè)文件感興趣,你可以使用 git checkout 獲取到該文件的舊版本。比如,如果你只想要看看 某次commit下的hello.py文件,可以使用下面的命令:

git checkout a1e8fb5 hello.py

記住,不像切換commit,這會(huì)影響當(dāng)前項(xiàng)目的狀態(tài)。這個(gè)舊版本的文件的狀態(tài)會(huì)變?yōu)?Change to be committed,給你一個(gè)機(jī)會(huì)將該文件恢復(fù)到先前的版本。

如果你決定不需要保留這個(gè)舊版本了,你可以切換到最近的版本,如下:

git checkout HEAD hello.py

git revert

git revert 可以撤銷一個(gè)已提交的快照(snapshot),但它解決的是如何撤銷已提交的被引入的改動(dòng),并生成內(nèi)容來追加一個(gè)新的提交,而不是從項(xiàng)目的歷史中移除這個(gè)提交,這避免了丟失歷史記錄,這對(duì)于項(xiàng)目的每一次修改的歷史記錄的完整性來說非常重要,并這是服務(wù)于可靠的多人協(xié)作開發(fā)的。

git revert <commit>

這句命令會(huì)撤銷這次<commit>所有被引入的改動(dòng),生成一個(gè)新的commit,并應(yīng)用在當(dāng)前分支上。

當(dāng)你想從你的項(xiàng)目歷史中移除一個(gè)完整的commit時(shí),就應(yīng)該使用git revert。比如,你正在追蹤一個(gè)Bug并發(fā)現(xiàn)它是在一次單一的commit中被引入的,你可以手動(dòng)進(jìn)行修改,刪除有Bug的代碼來修復(fù)它,然后提交一個(gè)新的快照,但這樣很麻煩,效率也很低,你更應(yīng)該做的是,使用git revert自動(dòng)完成,撤銷這次commit所有被引入的改動(dòng)。

Reverting vs. Resetting

很重要的一點(diǎn),revert是對(duì)一次單一的commit的撤銷,并不是真正意義上的回滾。它不是通過移除項(xiàng)目中一次commit后面的所有提交來“回滾”之前的狀態(tài),實(shí)際上那樣的操作在Git上被叫做reset,而不是revert

比起resetrevert有兩個(gè)重要的好處:

  • revert不會(huì)改變項(xiàng)目的歷史。如果那些commits已經(jīng)推到了共享的代碼倉庫,它會(huì)是一個(gè)“安全”的操作。為什么改變共享代碼倉庫的歷史是危險(xiǎn)的,請(qǐng)看后面的git reset的介紹。

  • revert可以作用于歷史中 任意 的單一的commit節(jié)點(diǎn),然而reset只能做到從當(dāng)前 最新 的commit開始回滾。比如說,如果你想要只撤銷一次舊的指定的commit,使用git reset,你則必須移除該commit和該commit之后出現(xiàn)的所有commits,然后再把那些隨后的commit重新提交。毫無疑問,這種撤銷的方式一點(diǎn)都不優(yōu)雅。

示例1

下面的例子是git revert的一個(gè)簡(jiǎn)單示例,提交了一個(gè)快照,然后立即使用revert撤銷了它。

# Edit some tracked files

# Commit a snapshot
git commit -m "Make some changes that will be undone"

# Revert the commit we just created
git revert HEAD

注意:在revert后,第4次commit仍然被保留在項(xiàng)目歷史中,git revert新增了一個(gè)新的commit來撤銷它的改動(dòng),而不是刪除它。結(jié)果就是,第3次和第5次commit的代碼是完全一樣的,第4次commit依然保留在歷史中,以防我們想要重新回滾到這里。

示例2

假設(shè)你發(fā)現(xiàn)在某次commit中引入了一個(gè)bug,你想使用 git revert來回滾。查看歷史:

git log --oneline

項(xiàng)目歷史如下:

417e4a9 commit 4
427d76b commit 3
1642475 introduced a bug
71d3ef7 commit 1
bf4f6f6 git initial

使用 revert 回滾到 1642475

git revert 1642475

但你會(huì)發(fā)現(xiàn)沒有想象中那么簡(jiǎn)單,而是發(fā)生沖突了,報(bào)錯(cuò)如下:

error: could not revert 1642475... introduced a bug
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

revert 僅僅是撤銷introduced a bug這一commit的改動(dòng),默認(rèn)會(huì)生成一個(gè)新的commit提交,但在它之后還有commit 3commit 4,它們的改動(dòng)不會(huì)被影響,依然保留在工作區(qū)中,因此產(chǎn)生了沖突。你可以手動(dòng)解決沖突后commit,但這卻是個(gè)麻煩且不優(yōu)雅的方式。因?yàn)?code>1642475、427d76b417e4a9這幾個(gè)commit的改動(dòng)被一起合并在暫存區(qū)中,如果你修改的不止一個(gè)文件,那手動(dòng)解決沖突將會(huì)非常麻煩。解決方式是,默認(rèn) 生成新的commit,并按順序回滾。

先強(qiáng)制結(jié)束revert

git revert --abort

按順序回滾

git revert 417e4a9 --no-commit
git revert 427d76b --no-commit
git revert 1642475 --no-commit  
git revert --continue

git revert --continue,會(huì)生成帶默認(rèn)message的commit。

更多參數(shù)說明詳見:git-revert-document

git reset

如果git revert是以一個(gè)"安全""的方式來撤銷改動(dòng),那你可以認(rèn)為git reset是一種 危險(xiǎn) 的方式。當(dāng)你使用git reset后,將沒有辦法恢復(fù)原樣,它是一個(gè)永恒的撤銷,因?yàn)槟切ヽommits不再被任何refreflog引用。在使用這個(gè)工具時(shí)請(qǐng)務(wù)必謹(jǐn)慎,因?yàn)樗?code>git命令中唯一一個(gè)潛在的使你的努力付諸東流的命令。

git reset是一個(gè)功能豐富的命令,它可以用于移除已提交的快照,但它更多的是用來撤銷暫存區(qū)和工作區(qū)的改動(dòng),另一種情況是,它應(yīng)該只用于撤銷本地的改動(dòng)(不應(yīng)該reset那些已經(jīng)與其他開發(fā)者共享了的快照)。

用法

git reset <file>

從暫存區(qū)中移除指定的文件,但保留工作區(qū)不變。它unstage一個(gè) 文件且沒有覆蓋任何改動(dòng)。

把文件加入暫存區(qū)叫做stage,文件修改過但還未使用git add加入暫存區(qū)叫做unstage

git reset

重置暫存區(qū)匹配至最近的一次commit,但保留工作區(qū)不變。它unstage所有 文件且沒有覆蓋任何改動(dòng),讓你有機(jī)會(huì)從頭開始重建暫存快照。

git reset --hard

重置暫存區(qū)和工作區(qū)匹配至最近的一次commit。除了unstage所有文件外,-- hard還告訴Git也一并覆蓋工作區(qū)的所有改動(dòng),也就是說,這個(gè)操作撤銷了所有未提交的改動(dòng),所以在使用它前,請(qǐng)確定你是真的想丟棄本地的開發(fā)。

git reset <commit>

將當(dāng)前分支的HEAD移動(dòng)至<commit>,重置暫存區(qū)匹配至<commit>,但不包括工作區(qū)。從<commit>開始的所有改動(dòng)會(huì)被駐留在工作區(qū),這讓你可以使用更干凈、更原子性的快照來重新提交項(xiàng)目歷史。

git reset --hard <commit>

將當(dāng)前分支的HEAD移動(dòng)至<commit>以及重置暫存區(qū)和工作區(qū)匹配至<commit>。它不僅撤銷了未提交的改動(dòng),還撤銷了<commit>之后的所有commits。

討論

正如上面提及到的,git reset是用來從一個(gè)代碼倉庫中移除改動(dòng)的。沒有-- hard標(biāo)記時(shí),git reset通過unstage改動(dòng)或撤銷(uncommit)一系列已提交的快照來清理干凈代碼倉庫,然后重頭開始重建它們。當(dāng)一個(gè)試驗(yàn)已經(jīng)往可怕的方向發(fā)展時(shí),-- hard標(biāo)記就派上用場(chǎng)了,你需要一個(gè)干凈的工作空間。

reset是被設(shè)計(jì)來撤銷 本地 的改動(dòng)的,而revert是被設(shè)計(jì)來安全地撤銷 公有 的commit的。出于完全不同的目的,這兩個(gè)命令的執(zhí)行結(jié)果也不同:reset是完全地移除有改動(dòng)的地方,而revert則是維持原來的改動(dòng),使用一個(gè)新的commit來達(dá)到撤銷的目的。

不要重置公有的歷史

當(dāng)<commit后面的任一快照被推送到公有倉庫時(shí),你就不應(yīng)該使用git reset <commit>,推送一個(gè)commit到公有倉庫后,就必須假設(shè)其他開發(fā)者是依賴于它的。刪除一個(gè)其他團(tuán)隊(duì)成員在此基礎(chǔ)上持續(xù)開發(fā)的commit會(huì)引發(fā)團(tuán)隊(duì)協(xié)作上的嚴(yán)重問題,當(dāng)他們嘗試與你的代碼倉庫同步時(shí),就像一大塊項(xiàng)目歷史突然地消失了。

下面的例子就是當(dāng)你嘗試reset一個(gè)公有的commit時(shí)會(huì)發(fā)生的。

一旦你在reset后新增一個(gè)commit,Git會(huì)認(rèn)為你本地的歷史與origin/master背道而馳了,當(dāng)合并commit時(shí),需要先同步你的代碼倉庫,這就有可能使你的團(tuán)隊(duì)感到迷惑和無助。

所以重點(diǎn)就是,你打算用git reset <commit>來撤銷你那糟糕的試驗(yàn)時(shí),請(qǐng)確保它只作用于本地(還沒被推送至遠(yuǎn)程服務(wù)器)的改動(dòng)。如果你需要修復(fù)一個(gè)公有的commit,請(qǐng)使用git revert,因?yàn)樗菫榱诉@個(gè)目的而被設(shè)計(jì)的。

示例

Unstage 一個(gè)文件

假設(shè)有兩個(gè)文件hello.pymain.py,已經(jīng)被添加到Git倉庫中,修改這兩文件并進(jìn)行提交。

# Edit both hello.py and main.py

# Stage everything in the current directory
git add .

# Realize that the changes in hello.py and main.py
# should be committed in different snapshots

# Unstage main.py
git reset main.py

# Commit only hello.py
git commit -m "Make some changes to hello.py"

# Commit main.py in a separate snapshot
git add main.py
git commit -m "Edit main.py"

正如你所看到的,你可以使用git resetunstage掉一些不小心加入暫存區(qū)但又與此次commit無關(guān)的文件,讓你的commits保持高度的專一。

移除本地的commits

接下來的例子展示了一個(gè)更高級(jí)的使用情況,它示范了你在一個(gè)新的試驗(yàn)上工作了一段時(shí)間并在提交了一些快照后,決定徹底拋棄它這整個(gè)過程究竟發(fā)生了什么。

# Create a new file called `foo.py` and add some code to it

# Commit it to the project history
git add foo.py
git commit -m "Start developing a crazy feature"

# Edit `foo.py` again and change some other tracked files, too

# Commit another snapshot
git commit -a -m "Continue my crazy feature"

# Decide to scrap the feature and remove the associated commits
git reset --hard HEAD~2

git reset HEAD~2這句命令讓當(dāng)前分支回滾了兩個(gè)提交,實(shí)際上,從項(xiàng)目歷史上刪除了我們剛剛創(chuàng)建的兩個(gè)快照。請(qǐng)記住,這種類型的reset應(yīng)該只用在未推送到遠(yuǎn)程服務(wù)器的commits上,絕不要在那些已經(jīng)被推送至公有倉庫的commits上執(zhí)行上面的操作。

git clean

git clean從工作區(qū)移除未追蹤的文件。這的確是一個(gè)更方便的命令,因?yàn)樗褂?code>git status瑣細(xì)地查看哪些文件未追蹤,然后手動(dòng)刪除它們。就像普通的rm命令一樣,git clean是不可恢復(fù)的,所以在運(yùn)行它之前請(qǐng)確保你是真的想要?jiǎng)h除那些未追蹤的文件。

git clean命令經(jīng)常和git reset --hard一起被執(zhí)行,reset僅僅影響已追蹤的文件,因此需要git clean來單獨(dú)清理未追蹤的文件,這兩個(gè)命令相結(jié)合可以讓你的工作區(qū)回滾到一個(gè)特定的commit的確切狀態(tài)。

用法

git clean -n

執(zhí)行git clean的“演習(xí)”。這向您展示哪個(gè)文件將會(huì)被刪除,但不會(huì)真正地執(zhí)行。

git clean -f

從當(dāng)前工作區(qū)中移除未追蹤的文件。-f(force)標(biāo)記是必需的,除非clean.requireForce選項(xiàng)被設(shè)為false(默認(rèn)是true)。這不會(huì)移除.gitignore指定的未追蹤的文件。

git clean -f <path>

移除未追蹤的文件,但僅限于操作指定的路徑。

git clean -df

從當(dāng)前工作區(qū)中移除未追蹤的文件和目錄。

git clean -xf

從當(dāng)前工作區(qū)中移除未追蹤的文件,包括Git忽略的文件。

討論

當(dāng)你在本地倉庫中做了一些令人尷尬的開發(fā)想要銷毀證據(jù)時(shí),git reset --hardgit clean -f會(huì)是你最好的朋友,運(yùn)行著兩個(gè)命令將會(huì)使你的工作區(qū)回滾至最近的一次commit,還你一個(gè)干凈的工作區(qū)。

git cleanbuild后清理工作區(qū)是很有用的,比如,你可以很容易地移除.o.exe等C編譯器生成的二進(jìn)制文件,這是偶爾打包項(xiàng)目發(fā)布前的必要步驟,-x選項(xiàng)達(dá)到這個(gè)目的特別方便。

記住,一起使用git resetgit clean是唯一一個(gè)具有潛在威脅的永久地刪除提交的命令,所以請(qǐng)謹(jǐn)慎使用。事實(shí)上,在使用git clean時(shí),-f是必須的,Git`的維護(hù)者甚至將它作為最基本的操作,而很多人會(huì)忘記的這一重要步驟,但這也預(yù)防了愚蠢行為而一不小心突然地刪除所有辛辛苦苦寫的代碼。

示例

下面的例子撤銷了工作區(qū)所有的改動(dòng),包括新增的文件。假設(shè)你已經(jīng)提交了一些快照,然后正在嘗試一些些新的開發(fā),但不知道自己做了什么導(dǎo)致了一些錯(cuò)誤,想要撤銷然后重新開始。

# Edit some existing files
# Add some new files
# Realize you have no idea what you're doing

# Undo changes in tracked files
git reset --hard

# Remove untracked files
git clean -df

運(yùn)行完reset/clean一系列命令后,工作區(qū)和暫存區(qū)回滾到最近的commit,git status將會(huì)告訴你這是一個(gè)干凈的工作區(qū),你現(xiàn)在可以準(zhǔn)備重新開始了。

注意,那些新增的文件沒有被加入暫存區(qū),它們不會(huì)被git reset --hard影響,必須使用git clean刪除它們。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,196評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,688評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,456評(píng)論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,955評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評(píng)論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,195評(píng)論 0 287
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,725評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,608評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,802評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評(píng)論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,048評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評(píng)論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,424評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,762評(píng)論 2 372

推薦閱讀更多精彩內(nèi)容

  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,526評(píng)論 1 26
  • 一 Git配置和倉庫初始化 下面會(huì)介紹Git的使用,每個(gè)小節(jié)里會(huì)講解各個(gè)功能在命令行中的實(shí)現(xiàn)方式,并在每小節(jié)的最后...
    Happioo閱讀 3,406評(píng)論 0 5
  • 你看,我已經(jīng)不是那個(gè)只靠嘴上說說的關(guān)心就滿足就感動(dòng)的不要不要的小姑娘了。。。 在背叛欺騙和等待中成長,我也會(huì)變得開...
    楚沐沐閱讀 228評(píng)論 0 1
  • 滴答滴答……今天的雨一直在持續(xù),忽大忽小,忽密忽疏。 北方的天氣有些任性,冷空氣說來就來,溫度瞬間下降,仿佛一腳踏...
    銀子姐閱讀 298評(píng)論 1 2
  • 概述 上一篇主要講解了YYMemoryCache的文件結(jié)構(gòu),分析了YYMemoryCache類的相關(guān)方法,本章主要...
    egoCogito_panf閱讀 3,812評(píng)論 3 11