Git 的基本操作、開發(fā)流程、實(shí)用技巧總結(jié)

Git 是什么?

Git 是一個(gè)分布式的代碼管理容器,本地和遠(yuǎn)端都保有一份相同的代碼。
Git 倉(cāng)庫(kù)主要是由是三部分組成:本地代碼,緩存區(qū),提交歷史,這幾乎是所有操作的本質(zhì),但是為了文章更加簡(jiǎn)單易懂,就不圍繞這塊展開了,有興趣的可以去了解下。
開門見山,我們直接來說說 Git 有哪些常見的操作。

Git 有哪些常規(guī)操作?

我們簡(jiǎn)單說說Git有哪些常規(guī)操作,能夠讓我們應(yīng)付簡(jiǎn)單的開發(fā)需求。

克隆代碼

? 克隆遠(yuǎn)端代碼

git clone http://git.code.oa.com/QCFE/sqlserver.git

? 查看本地的代碼狀態(tài)

// 可以明確的呈現(xiàn)出本地倉(cāng)庫(kù)的狀態(tài)
// 哪些文件發(fā)生改動(dòng),哪些文件已經(jīng)提交到本機(jī)
// 以及一些操作指示。
git status
git status

? 同步遠(yuǎn)端分支變化

// 拉取指定分支的變化
git fetch origin master 
// 拉取所有分支的變化
git fetch 
// 拉取所有分支的變化,并且將遠(yuǎn)端不存在的分支同步移除【推薦】
git fetch -p 

? 同步遠(yuǎn)端代碼變化。

// 都是先 git fetch,然后執(zhí)行合并操作
// 不同的是,git pull 執(zhí)行的是 git merge,git pull -r 執(zhí)行的是git rebase
git pull origin master 
git pull -r origin master

關(guān)于 git merge 和 git rebase 各自的優(yōu)劣,后文會(huì)詳細(xì)介紹。

這部分主要介紹了關(guān)于代碼克隆,同步遠(yuǎn)端代碼變化的相關(guān)操作。接下來,我們看看關(guān)于本地代碼的一些操作。

操作 commit

首先我們要明確一個(gè)概念:就是每個(gè) commit 都是一份完整的代碼狀態(tài),用一個(gè) commitID 來唯一標(biāo)志。


git log --stat 可以讓你的 commit 記錄更清晰

從某個(gè)角度上來說,Git維護(hù)的就是一個(gè)commitID樹,分別保存著不同狀態(tài)下的代碼。
所以你對(duì)代碼的任何修改,最終都會(huì)反映到 commit 上面去。

? 新增 commit

// 添加文件到緩存區(qū),然后提交到本地倉(cāng)庫(kù)
git add files
git commit -m '提交備注'

? 撤銷 commit

// 會(huì)將提交記錄回滾,代碼不回滾
git reset b14bb52

// 會(huì)將提交記錄和代碼全部回滾
git reset --hard b14bb52

// 將部分代碼文件回滾
git checkout -- files

? 合并 commit
合并 commit,本質(zhì)上合并兩份不同狀態(tài)下的代碼。

// Git 提供了兩種合并 commit 的方式
git merge master
git rebase master

那么 git rebase 和 git merge 到底有什么區(qū)別呢?
merge是兩個(gè)分支處理沖突后,新增一個(gè) commit 追加到master上。
rebase是將someFeature分支上的commit記錄追加到主分支上,值得注意的是,這個(gè)時(shí)候他的commit其實(shí)已經(jīng)發(fā)生變化。


image.png

相對(duì)來說,git merge 處理沖突更直接,而git rebase 能夠保證清晰的 commit 記錄。

合并 commit 的時(shí)候,通常會(huì)發(fā)生沖突。
可以全局搜索特殊字符比如<<<,找到需要處理的代碼位置,然后認(rèn)真分析應(yīng)該保留哪一部分代碼。

處理沖突

在團(tuán)隊(duì)協(xié)作的時(shí)候,分支是必不可少的。那么應(yīng)該如何對(duì)分支進(jìn)行操作呢?

操作分支

所謂的分支其實(shí)就是一個(gè)指向 commitID 的指針,你可以去.git/refs/heads里去看看。

cat .git/refs/heads/master

通常情況下,我們建議分支至少能夠明確的標(biāo)記功能名稱,如果能標(biāo)記用戶就更好了,比如qixiu/feature

? 查看分支


git branch -a

可以同時(shí)看到本地分支和遠(yuǎn)端分支,配合上前文介紹的 git fetch -p 可以第一時(shí)間查看到最新的分支信息。

? 新增本地分支
其實(shí)就是創(chuàng)建一個(gè)指針指向某一個(gè) commitID。

// git branch qixiu/feature + git checkout qixiu/feature
// 從當(dāng)前分支新增一個(gè)新的分支qixiu/feature
// 一般情況下,我們應(yīng)該從master或者其他穩(wěn)定分支來新增分支
git checkout -b qixiu/feature // 新建分支
git checkout qixiu/feature // 切換分支

? 刪除本地分支
其實(shí)就是移除一個(gè)指向 commitID 的指針。

// 刪除本地分支,如果本地還有未合并的代碼,則不能刪除
git branch -d qixiu/feature
// 強(qiáng)制刪除本地分支
git branch -D qixiu/feature 

? 新增遠(yuǎn)端分支
通常情況下,我們是新建本地分支,然后更新到遠(yuǎn)端的方式來新增一個(gè)遠(yuǎn)端分支

git push origin qixiu/feature

? 刪除遠(yuǎn)端分支
同樣,我們也是通過更新到遠(yuǎn)端的方式來刪除一個(gè)遠(yuǎn)端分支

// 等同于git push origin -d qixiu/feaure
git push origin :qixiu/feature

簡(jiǎn)單匯總一下

上面說的可能有些分散,這兒簡(jiǎn)單總結(jié)一下有哪些經(jīng)常使用的操作:

git status // 查看本地代碼狀態(tài)
git add files // 添加代碼到緩存區(qū)
git commit -m '提交內(nèi)容的備注' // 提交代碼到本地倉(cāng)庫(kù)
git checkout -b branchName // 不加-b就是普通切換分支
git fetch -p // 同步遠(yuǎn)端分支狀態(tài)
git pull -r origin branchName // fetch遠(yuǎn)端代碼到本地,并且以rebase的方式合并代碼
git push origin branchName // 更新本地代碼到遠(yuǎn)端

以上幾條命令已經(jīng)能夠應(yīng)付日常的操作,稍微復(fù)雜一些的場(chǎng)景后文會(huì)介紹

基于基本操作,在實(shí)際項(xiàng)目中,我們應(yīng)該怎么利用 Git 實(shí)現(xiàn)協(xié)作呢?

Git 有哪些比較好的實(shí)踐?

Git 有一些成熟的開發(fā)流程,比較主流的有兩種:基于功能分支的開發(fā)流程GitFlow開發(fā)流程
相對(duì)來時(shí),我更推薦前者,如果是復(fù)雜的大型項(xiàng)目,推薦GitFlow開發(fā)流程。
接下來,簡(jiǎn)單介紹下這兩種協(xié)作模式。

基于功能分支的協(xié)作模式

基于功能分支的開發(fā)流程其實(shí)就是一句話:用分支來承載功能開發(fā),開發(fā)結(jié)束之后就合并到 master 分支。
他的優(yōu)點(diǎn)是能夠保證master分支的整潔,同時(shí)還能讓分支代碼邏輯集中,也便于 CodeReview。

分支命名規(guī)范

推薦使用如下格式:ownerName/featureName。
這樣既便于知道分支覆蓋的功能,也便于找到分支的負(fù)責(zé)人。以后清理分支的時(shí)候也很方便。

開發(fā)流程

? 從 master 切出一個(gè)新分支

git checkout -b qixiu/newFeature

? 開發(fā)一些新功能,然后提交
建議較多頻次的提交代碼到本地倉(cāng)庫(kù),以便能夠更靈活的保存或撤銷修改。
此外為了保證提交日志的清晰,建議備注清楚的注釋。

git status
git add files // 挑選需要提交的文件,或者全部提交
git commit -m '提交備注'
git push origin qixiu/newFeature

? 如果功能開發(fā)完成,可以發(fā)起一個(gè)CodeReview流程
? 如果代碼測(cè)試通過,合并到 master,然后準(zhǔn)備上線

// 冗余版 合并到 master
git checkout master 
git pull -r origin master
git checkout qixiu/newFeature
git rebase master // 處理沖突
git checkout master
git merge qixiu/newFeature
git push origin master

// 精簡(jiǎn)版 合并到 master
git checkout qixiu/newFeature
git pull -r origin master // 將master的代碼更新下來,并且rebase處理沖突
git push origin master // 將本地代碼更新到遠(yuǎn)端

有幾點(diǎn)需要注意:
不要在master合并代碼,保證master的可用性很重要。
確保在正確的分支執(zhí)行正確的操作。
無論是處理沖突還是更新遠(yuǎn)端代碼,請(qǐng)保有敬畏之心。

到此,一個(gè)正常的基于功能分支的開發(fā)流程就完成了。接下來看看另外一個(gè)開發(fā)流程。

GitFlow 開發(fā)流程

GitFlow 比前文講的基于功能分支的開發(fā)流程要復(fù)雜得多,它更適合大型的復(fù)雜項(xiàng)目。
它圍繞項(xiàng)目發(fā)布流程定義了一個(gè)嚴(yán)格的分支模型,所有的開發(fā)流程都是圍繞這個(gè)嚴(yán)格的分支模型進(jìn)行。
而這個(gè)模型約定了每個(gè)分支的角色,以及他們?nèi)绾螠贤ā?/p>

我們先來看看 GitFlow 開發(fā)流程中幾個(gè)約定的分支,以及他們各自承擔(dān)的角色是怎么樣的?


GitFlow 開發(fā)流程

? Master分支:用于存放線上版本代碼,可以方便的給代碼打版本號(hào)。
? Develop分支:用于整合 Feature 分支。
? Feature分支:某個(gè)功能的分支,從 Develop 分支切出,并且功能完成時(shí)又合并回 Develop 分支,不直接和
Master 分支交互。
? Release分支:通常對(duì)應(yīng)一個(gè)迭代。將一個(gè)版本的功能全部合并到 Develop 分支之后,從 Develop 切出一個(gè) Release 分支。這個(gè)分支不在追加新需求,可以完成 bug 修復(fù)、完善文檔等工作。務(wù)必記住,代碼發(fā)布后,需要將其合并到 Master 分支,同時(shí)也要合并到 Develop 分支。
? Hotfix分支:緊急修復(fù)的分支,是唯一可以從 Master 切出的分支,一旦修復(fù)了可以合并到 Master 分支和 Develop 分支。

從每個(gè)分支的功能和約定可以看出,它流程多約束多,對(duì)于小規(guī)模應(yīng)用并不適合。
當(dāng)然 GitFlow 有一些輔助工具 gitflow 可以自動(dòng)化的完成這些任務(wù),對(duì)于大型項(xiàng)目也很有幫助。

前面講了 Git 有哪些基本操作,然后介紹了兩個(gè)主流的工作流程。
接下來我們看看 Git 有哪些特別的技巧值得一提。

Git 有哪些小技巧?

Git 操作除了基本的代碼管理功能,還有一些小技巧能夠讓你眼前一亮。

git reflog,查看操作記錄

這個(gè)我一定要放在第一個(gè)介紹,因?yàn)樗?jīng)數(shù)次解救了我的代碼


git reflog

仔細(xì)看上圖,reflog 記錄了你所有的 git 命令操作,對(duì)于復(fù)原某些莫名其妙的場(chǎng)景或者回滾誤操作有極大的幫助。

試想一個(gè)場(chǎng)景:你使用 git reset --hard commitID 把本地開發(fā)代碼回滾到了一個(gè)之前的版本,而且還沒有推到遠(yuǎn)端,怎么才能找回丟失的代碼呢?
你如果使用 git log 查看提交日志,并不能找回丟棄的那些 commitID。
而 git reflog 卻詳細(xì)的記錄了你每個(gè)操作的 commitID,可以輕易的讓你復(fù)原當(dāng)時(shí)的操作并且找回丟失的代碼。
當(dāng)然,如果你丟失的代碼都沒有提交記錄,那么恭喜你,你的代碼真的丟了。

壓縮日志

這也是一個(gè)很實(shí)用的功能,前文提過,我們?cè)陂_發(fā)中的時(shí)候盡量保持一個(gè)較高頻率的代碼提交,這樣可以避免不小心代碼丟失。但是真正合并代碼的時(shí)候,我們并不希望有太多冗余的提交記錄,而且 rebase 合并代碼的時(shí)候,會(huì)把每個(gè) commit 都處理一下,有時(shí)候會(huì)造成冗余的工作。
所以,壓縮日志之后不經(jīng)能讓 commit 記錄非常整潔,同時(shí)也便于使用 rebase 合并代碼。

那么,如何壓縮commit記錄呢?
? 使用 git log 找到起始 commitID
? git reset commitID,切記不要用 --hard 參數(shù)
? 重新 git add && git commit
? git push -f origin branchName,因?yàn)闀?huì)有沖突,所以需要強(qiáng)制覆蓋遠(yuǎn)端分支,請(qǐng)務(wù)必謹(jǐn)慎。
? 合并到 master 中,然后更新遠(yuǎn)端 master。

此外還有兩種壓縮日志的辦法:
git commit --amend:追加 commit 到上一個(gè) commit 上。
git rebase -i:通過交互式的 rebase,提供對(duì)分支 commit 的控制,從而可以清理混亂的歷史。

git rebase -i

從實(shí)際應(yīng)用來說,三種日志壓縮都很優(yōu)秀,git reset 更簡(jiǎn)單,git rebase -i 更細(xì)膩。

git rebase,合并代碼

前文簡(jiǎn)單介紹了 git rebasegit merge 的區(qū)別,坦率講,他們各有優(yōu)劣。
git rebase 能讓你的 commit 記錄非常整潔,無論是線上回滾還是 CodeReview 都更輕松;但卻是一個(gè)有隱患的操作,使用時(shí)務(wù)必謹(jǐn)慎。
git merge 操作更安全,同時(shí)也更簡(jiǎn)單;但卻會(huì)增加一些冗余的 commit 記錄。

這兒簡(jiǎn)單說說 rebase 的合并流程和注意事項(xiàng)吧。看下圖


image.png

有三個(gè)點(diǎn)需要注意:
? rebase 先找出共同的祖先節(jié)點(diǎn)
? 從祖先節(jié)點(diǎn)把 pay 分支的提交記錄摘下來,然后 rebase 到 master 分支
? rebase 之后的 commitID 其實(shí)已經(jīng)發(fā)生了變化
尤其是第三點(diǎn),經(jīng)常會(huì)讓人誤操作,所以務(wù)必注意。

試想一下,開發(fā)過程中,如果我們頻繁的 rebase master 分支,會(huì)有什么后果呢?


image.png

當(dāng)你不斷 rebase master 的時(shí)候,其實(shí)你本地的 d 都變成了 d` ,再要和遠(yuǎn)端 pay 分支保持一致,你的本地分支 commit 記錄已經(jīng)不堪入目了。

另外要注意,絕不要在公共的分支上使用 rebase!!!

image.png

所以,為了安全,團(tuán)隊(duì)可以考慮采用 merge。

pull request,方便CodeReview

Git 不僅提供了代碼托管以及代碼開發(fā)的幫助,還提供了代碼審核類似的功能。
當(dāng)我們?cè)诠δ芊种ч_發(fā)完成之后,可以發(fā)起一個(gè) pull request 請(qǐng)求,選擇需要對(duì)比的兩個(gè)分支


新建 pull request

它會(huì)創(chuàng)建一個(gè) pull request,制定相關(guān)人員來對(duì)代碼進(jìn)行 review。
通常情況下,團(tuán)隊(duì)?wèi)?yīng)該鼓勵(lì)交叉 review,涉及到公共代碼的時(shí)候,一定要讓相關(guān)人 review。
當(dāng)然這塊如果能結(jié)合更優(yōu)秀的 CodeReview 工具,能夠有更好的體驗(yàn)。

git hook,Git 的生命周期

這個(gè)大多數(shù)人應(yīng)該都,聽說過,git操作有它自身的生命周期,在不同的生命周期,我們可以做一些自動(dòng)化的事情。

舉兩個(gè)簡(jiǎn)單的例子:
? pre-commit的時(shí)候我們可以做 eslint
? post-commit的時(shí)候,我們可以做利用 jenkins 類似的工具做持續(xù)集成

當(dāng)然還有更多的聲明周期,具體可以參考 Git 鉤子

git submodule && git subtree,管理第三方模塊

這兩個(gè)命令通常用來管理公用的第三方模塊。比如一些通用的底層邏輯、中間件、還有一些可能會(huì)頻繁變化的通用業(yè)務(wù)組件。
當(dāng)然,兩者還是有區(qū)別的。
git submodule 主要用來管理一些單向更新的公共模塊或底層邏輯。
git subtree 對(duì)于部分需要雙向更新的可復(fù)用邏輯來說,特別適合管理。比如一些需要復(fù)用的業(yè)務(wù)組件代碼。在我之前的實(shí)踐中,我也曾用subtree來管理構(gòu)建系統(tǒng)邏輯。

git alias,簡(jiǎn)化 Git 命令

我們可以通過配置 git alias 來簡(jiǎn)化需要輸入的 Git 命令。
比如前文的 git subtree 需要輸入很長(zhǎng)的 Git 命令,我們可以配置 .git/config 文件來解決。

// git stpull appfe demo/xxx
// git stpush appfe demo/xxx
[alias]
    stpull = !git subtree pull --prefix=$1 appfe $2 \
        && :
    stpush = !git subtree pull --prefix=$1 appfe $2 \
        && git subtree split --rejoin --prefix=$1 $2 \
        && git subtree push --prefix=$1 appfe $2 \
        && :

總結(jié)說點(diǎn)啥?

該文首先介紹了 Git 常規(guī)操作
? 包括克隆代碼、操作 commit、操作分支等。其實(shí) Git 常規(guī)操作的命令并不多,請(qǐng)看第一部分的簡(jiǎn)單總結(jié)。

其次介紹了 Git 開發(fā)流程
? 該部分主要介紹了兩種主流的開發(fā)模式:比較輕量的 基于功能分支的開發(fā)流程 和適合復(fù)雜項(xiàng)目的 GitFlow 開發(fā)流程 ,兩種模式各有使用的場(chǎng)景,對(duì)于常規(guī)使用,前者就已經(jīng)足夠了。

最后介紹了一些 Git 實(shí)用技巧
? 主要包括:reflog 操作,壓縮日志,rebase 的注意事項(xiàng),利用 pull request 做 codeReview,利用 git hook 做一些自動(dòng)化工作等。

最后編輯于
?著作權(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閱讀 230,791評(píng)論 6 545
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,795評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,943評(píng)論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,057評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,773評(píng)論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,106評(píng)論 1 330
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,082評(píng)論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,282評(píng)論 0 291
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,793評(píng)論 1 338
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,507評(píng)論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,741評(píng)論 1 375
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,220評(píng)論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,929評(píng)論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,325評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,661評(píng)論 1 296
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,482評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,702評(píng)論 2 380

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

  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,540評(píng)論 1 26
  • 命運(yùn)的掙扎 評(píng)《沙丘2:沙丘救世主》 你希望擁有神奇的魔力嗎?希望擁有神秘的預(yù)知能力嗎?希望時(shí)刻都能預(yù)知下...
    汶子_楊家小汶子閱讀 227評(píng)論 0 1
  • 文/晴天過后上一章 目錄 雨嫻沿著小路慢慢走著,看著這熟悉的小鄉(xiāng)村,她腦海中浮現(xiàn)出和黎志軒嬉鬧的場(chǎng)景...
    晴天過后閱讀 783評(píng)論 4 24
  • 深圳是個(gè)女孩, 位于東南方的沿海小城, 沒有體驗(yàn)浩瀚的海, 沒有見識(shí)北方的雪, 也沒有領(lǐng)略西部的沙。 深圳是個(gè)女孩...
    Jasmine農(nóng)閱讀 197評(píng)論 0 0
  • 有欲望,真好! 想學(xué)車,想學(xué)財(cái)商,想學(xué)收納,想學(xué)的很多很多!這是不是叫欲望,拿別人的錢生錢,拿別人的故事找共通點(diǎn),...
    透明的灰閱讀 159評(píng)論 0 0