GitFlow+Gitlab工作流及Git規(guī)范

Git 規(guī)范

所有使用了本規(guī)范的項目厉膀,必須嚴(yán)格規(guī)范操作溶耘,否則不予以合并代碼、提測服鹅、打包上線等后續(xù)操作凳兵。

基本要求

  • 所有commit必須有注釋,內(nèi)容必須按照注釋格式嚴(yán)格執(zhí)行企软!
  • 合理控制提交內(nèi)容的顆粒度庐扫,一次commit含一個獨立功能點。嚴(yán)禁一次提交涵蓋多個功能項仗哨。
  • 正確為每個項目設(shè)置Git提交用到的user.name和user.email信息形庭,以公司郵箱為準(zhǔn),不可隨意設(shè)置以影響無法正確識別厌漂。 查看當(dāng)前項目配置信息的命令:git config -l

版本號(tag)

  • 版本號(tag)命名規(guī)則:主版本號.次版本號.修訂號萨醒,如2.1.13。(遵循GitHub語義化版本命名規(guī)范)
  • 版本號僅標(biāo)記于master分支苇倡,用于標(biāo)識某個可發(fā)布/回滾的版本代碼
  • 對master標(biāo)記tag意味著該tag能發(fā)布到生產(chǎn)環(huán)境
  • 對master分支代碼的每一次更新(合并)必須標(biāo)記版本號
  • 僅項目管理員有權(quán)限對master進行合并和標(biāo)記版本號

項目權(quán)限

Git權(quán)限分管理員富纸、開發(fā)者、瀏覽者三種類型旨椒,可以在Gitlab上設(shè)置每個項目的項目權(quán)限

gitlab_role.png
  • 瀏覽者(Guest)只能瀏覽代碼晓褪,無push、pull request等所有寫權(quán)限
  • 開發(fā)者(Developer)擁有瀏覽综慎、push非主分支辞州、提交pull request工單權(quán)限
  • 管理員(Master)擁有建立和管理Git項目、合并分支和代碼寥粹、給master打tag版本號等權(quán)限

分支使用

  • 每個Git項目固定含有上述所有分支類型。主分支master和develop是保護分支埃元,只能進行合并請求涝涤,均不可直接提交代碼。
  • 功能需求或常規(guī)Bug修復(fù)岛杀,請從develop拉取feature分支阔拳;線上緊急問題修復(fù),請從master拉取hotfix分支。

代碼提交

  • 一個提交就代表解決一個問題
  • 大問題適當(dāng)?shù)胤纸鉃槎鄠€小問題糊肠,以便每次小型提交都更易于理解

代碼合并

將開發(fā)完畢的分支辨宠,拉取develop最新代碼,merge并解決沖突后货裹,之后在對應(yīng)的feature分支創(chuàng)建并提交到develop分支嗤形,并自動觸發(fā)merge request請求,然后進行code review弧圆,確認(rèn)無誤后再合并赋兵。

注意:

  • 每個merge request不要包含不相關(guān)的功能
  • merge request提交后需要及時跟蹤動態(tài),包括通過搔预、打回等
  • 該功能進入提測流程后霹期,需刪除之前的功能分支

注釋格式

每次提交,Commit message 都包括三個部分:Header拯田,Body 和 Footer历造。

code_comment.png

其中,Header 是必需的船庇,BodyFooter 可以省略吭产。不管是哪一個部分,任何一行都不得超過72個字符溢十。這是為了避免自動換行影響美觀垮刹。

Header

Header部分只有一行,包括三個字段:type(必需)张弛、scope(可選)和subject(必需)荒典。

  • type用于說明 commit 的類別,只允許使用下面7個標(biāo)識吞鸭。
  • feat:新功能(feature)
  • fix:修補bug

  • docs:文檔(documentation)

  • style: 格式(不影響代碼運行的變動)

  • refactor:重構(gòu)(即不是新增功能寺董,也不是修改bug的代碼變動)

  • test:增加測試

  • chore:構(gòu)建過程或輔助工具的變動

  • scope用于說明 commit 影響的范圍,比如數(shù)據(jù)層刻剥、控制層遮咖、視圖層等等,視項目不同而不同造虏。

  • subject是 commit 目的的簡短描述御吞,不超過50個字符。

以動詞開頭漓藕,使用第一人稱現(xiàn)在時陶珠,比如change拳氢,而不是changed或changes
第一個字母小寫
結(jié)尾不加句號(.)

Body

Body 部分是對本次 commit 的詳細(xì)描述储耐,可以分成多行, 有兩個注意點:

  • 使用第一人稱現(xiàn)在時,比如使用change而不是changed或changes;

  • 應(yīng)該說明代碼變動的動機犯助,以及與以前行為的對比;

Footer

Footer 部分只用于兩種情況:

  • 如果當(dāng)前代碼與上一個版本不兼容,則 Footer 部分以BREAKING CHANGE開頭暑脆,后面是對變動的描述渠啤、以及變動理由和遷移方法;

  • 如果當(dāng)前 commit 針對某個issue,那么可以在 Footer 部分關(guān)閉這個 issue (Closes #123, #245, #992), GitHub這個功能很好用添吗;

Revert

還有一種特殊情況沥曹,如果當(dāng)前 commit 用于撤銷以前的 commit,則必須以revert:開頭根资,后面跟著被撤銷 Commit 的 Header架专。

為什么要約定注釋格式? 1. 加快 Reviewing Code 的過程 2. 幫助我們寫好 release note 3. 5年后幫你快速想起來某個分支玄帕,tag 或者 commit 增加了什么功能部脚,改變了哪些代碼 4. 讓其他的開發(fā)者在運行 git blame 的時候想跪謝 5. 其他小伙伴不會出現(xiàn)想抽你的沖動 6. 總之,一個好的提交信息裤纹,會幫助你提高項目的整體質(zhì)量

Git Flow

簡介

Git Flow是構(gòu)建在Git之上的一個組織軟件開發(fā)活動的模型委刘,是在Git之上構(gòu)建的一項軟件開發(fā)最佳實踐。Git Flow是一套使用Git進行源代碼管理時的一套行為規(guī)范和簡化部分Git操作的工具鹰椒。

gitflow_main.png

工作流中涉及到的角色介紹:

  • 功能開發(fā)者:模塊中功能的開發(fā)人員锡移;
  • 開發(fā)管理員:由項目模塊開發(fā)的小組長(team leader)擔(dān)當(dāng);
  • 測試管理員:由測試團隊指定人員擔(dān)當(dāng)漆际;
  • 發(fā)布管理員:由生產(chǎn)環(huán)境發(fā)布團隊指定人員擔(dān)當(dāng)淆珊;

分支說明

名稱 說明 命名規(guī)范 命名示例 合并目標(biāo) 合并操作
master 線上穩(wěn)定版本 master master -- --
release 待發(fā)布分支,下個版本需上線的版本 release/xxx release/v1.0.0 master merge request
develop 當(dāng)前正在開發(fā)的分支 develop develop master merge request
feature 功能分支奸汇,每個功能需分別建立自己的子分支 feature/版本號-功能名 feature/v1.0.0-Login develop merge request
hotfix 緊急修復(fù)分支 hotfix/xxx hotfix/v1.0.1 master/develop merge request

分支約定

Git Flow有主分支和輔助分支兩類分支施符。其中主分支用于組織與軟件開發(fā)、部署相關(guān)的活動擂找;輔助分支組織為了解決特定的問題而進行的各種開發(fā)活動戳吝。

主分支

git_master.png

主分支是所有開發(fā)活動的核心分支。所有的開發(fā)活動產(chǎn)生的輸出物最終都會反映到主分支的代碼中贯涎。主分支分為master分支和develop分支听哭。

master 分支
  • master分支存放的是隨時可供在生產(chǎn)環(huán)境中部署的穩(wěn)定版本代碼
  • master分支保存官方發(fā)布版本歷史,release tag標(biāo)識不同的發(fā)布版本
  • 一個項目只能有一個master分支
  • 僅在發(fā)布新的可供部署的代碼時才更新master分支上的代碼
  • 每次更新master塘雳,都需對master添加指定格式的tag陆盘,用于發(fā)布或回滾
  • master分支是保護分支,不可直接push到遠(yuǎn)程倉master分支
  • master分支代碼只能被release分支或hotfix分支合并
develop 分支
  • develop分支是保存當(dāng)前最新開發(fā)成果的分支
  • 一個項目只能有一個develop分支
  • develop分支衍生出各個feature分支
  • develop分支是保護分支败明,不可直接push到遠(yuǎn)程倉庫develop分支
  • develop分支不能與master分支直接交互

每次將develop分支上的代碼合并回master分支時礁遣,我們都可以認(rèn)為一個新的可供在生產(chǎn)環(huán)境中部署的版本就產(chǎn)生了〖缛校基于此,理論上說,每當(dāng)有代碼提交到master分支時盈包,我們可以使用Git Hook觸發(fā)軟件自動測試以及生產(chǎn)環(huán)境代碼的自動更新工作沸呐。這些自動化操作將有利于減少新代碼發(fā)布之后的一些事務(wù)性工作。

只有開發(fā)管理員有合并的權(quán)限

輔助分支

git_assist.png

輔助分支是用于組織解決特定問題的各種軟件開發(fā)活動的分支呢燥。輔助分支主要用于組織軟件新功能的并行開發(fā)崭添、簡化新功能開發(fā)代碼的跟蹤、輔助完成版本發(fā)布工作以及對生產(chǎn)代碼的缺陷進行緊急修復(fù)工作叛氨。這些分支與主分支不同呼渣,通常只會在有限的時間范圍內(nèi)存在。跟“歷史性”分支相反寞埠,這三類分支都是短期分支屁置,針對他們的工作內(nèi)容完成后,一般都要進行刪除仁连。

工作內(nèi)容完成的標(biāo)識有兩個:開發(fā)完成蓝角、合并完成,缺一不可饭冬。

輔助分支包括:

  • 用于開發(fā)新功能時所使用的feature分支
  • 用于輔助版本發(fā)布的release分支
  • 用于修正生產(chǎn)代碼中的缺陷的hotfix分支

以上這些分支都有固定的使用目的和分支操作限制使鹅。從單純技術(shù)的角度說,這些分支與Git其他分支并沒有什么區(qū)別昌抠,但通過命名患朱,我們定義了使用這些分支的方法。

feature 分支

使用規(guī)范:

  • 分支的命名格式必須是版本號-功能名炊苫,例如v1.0.0-login
  • develop分支的功能分支
  • feature分支使用develop分支作為它們的父類分支
  • 以功能為單位從develop拉一個feature分支
  • 每個feature分支顆粒要盡量小裁厅,以利于快速迭代和避免沖突
  • 當(dāng)其中一個feature分支完成后,它會合并回develop分支
  • 當(dāng)一個功能因為各種原因不開發(fā)了或者放棄了劝评,這個分支直接廢棄姐直,不影響develop分支
  • feature分支代碼可以保存在開發(fā)者自己的代碼庫中而不強制提交到主代碼庫里
  • 由每組開發(fā)管理員負(fù)責(zé)把所有feature分支開發(fā)完成的代碼合并到develop分支
  • feature分支只與develop分支交互,不能與master分支直接交互

如有幾個同事同時開發(fā)蒋畜,需要分割成幾個小功能声畏,每個人都需要從develop中拉出一個feature分支,但是每個feature顆粒要盡量小姻成,因為它需要我們能盡早merge回develop分支插龄,否則沖突解決起來就沒完沒了。同時科展,當(dāng)一個功能因為各種原因不開發(fā)了或者放棄了均牢,這個分支直接廢棄,不影響develop分支才睹。

release 分支

使用規(guī)范:

  • 命名規(guī)則:release/*徘跪,“*”以本次發(fā)布的版本號為標(biāo)識
  • release分支主要用來為發(fā)布新版的測試甘邀、修復(fù)做準(zhǔn)備
  • 當(dāng)需要為發(fā)布新版做準(zhǔn)備時,從develop衍生出一個release分支
  • release分支可以從develop分支上指定commit派生出
  • release分支測試通過后垮庐,合并到master分支并且給master標(biāo)記一個版本號
  • release分支一旦建立就將獨立松邪,不可再從其他分支pull代碼
  • 必須合并回develop分支和master分支

release分支是為發(fā)布新的產(chǎn)品版本而設(shè)計的。在這個分支上的代碼允許做小的缺陷修正哨查、準(zhǔn)備發(fā)布版本所需的各項說明信息(版本號逗抑、發(fā)布時間、編譯時間等)寒亥。通過在release分支上進行這些工作可以讓develop分支空閑出來以接受新的feature分支上的代碼提交邮府,進入新的軟件開發(fā)迭代周期。

當(dāng)develop分支上的代碼已經(jīng)包含了所有即將發(fā)布的版本中所計劃包含的軟件功能溉奕,并且已通過所有測試時褂傀,我們就可以考慮準(zhǔn)備創(chuàng)建release分支了。而所有在當(dāng)前即將發(fā)布的版本之外的業(yè)務(wù)需求一定要確保不能混到release分支之內(nèi)(避免由此引入一些不可控的系統(tǒng)缺陷)腐宋。

成功的派生了release分支紊服,并被賦予版本號之后,develop分支就可以為“下一個版本”服務(wù)了胸竞。所謂的“下一個版本”是在當(dāng)前即將發(fā)布的版本之后發(fā)布的版本欺嗤。版本號的命名可以依據(jù)項目定義的版本號命名規(guī)則進行。

hotfix 分支

使用規(guī)范:

  • 命名規(guī)則:hotfix/*卫枝,“*”以本次發(fā)布的版本號為標(biāo)識
  • hotfix分支用來快速給已發(fā)布產(chǎn)品修復(fù)bug或微調(diào)功能
  • 只能從master分支指定tag版本衍生出來
  • 一旦完成修復(fù)bug煎饼,必須合并回master分支和develop分支
  • master被合并后,應(yīng)該被標(biāo)記一個新的版本號
  • hotfix分支一旦建立就將獨立校赤,不可再從其他分支pull代碼

除了是計劃外創(chuàng)建的以外吆玖,hotfix分支與release分支十分相似:都可以產(chǎn)生一個新的可供在生產(chǎn)環(huán)境部署的軟件版本。

當(dāng)生產(chǎn)環(huán)境中的軟件遇到了異常情況或者發(fā)現(xiàn)了嚴(yán)重到必須立即修復(fù)的軟件缺陷的時候马篮,就需要從master分支上指定的TAG版本派生hotfix分支來組織代碼的緊急修復(fù)工作沾乘。

這樣做的顯而易見的好處是不會打斷正在進行的develop分支的開發(fā)工作,能夠讓團隊中負(fù)責(zé)新功能開發(fā)的人與負(fù)責(zé)代碼緊急修復(fù)的人并行的開展工作浑测。

版本管理

我們使用 Git Flow 來進行版本管理控制翅阵,它相對于 GitHub Flow 更適合在產(chǎn)品開發(fā)中快速迭代,這種代碼管理模式應(yīng)該已經(jīng)廣泛使用了迁央。

另外掷匠,我們鼓勵使用 Git 客戶端 SourceTree,它集成了 Git Flow 的一些基本操作岖圈。如果嚴(yán)格遵循 Git Flow 的流程進行版本管理控制讹语,那么我們只用管開始和結(jié)束一個 Feature/Release/Hotfix,基本上是不用手動 merge 分支的蜂科。

gitflow_branch.jpg

新功能開發(fā)流程

  1. 從 develop 分支創(chuàng)建 feature 分支顽决;
  2. 開發(fā)調(diào)試完將 feature 分支提交到遠(yuǎn)程版本庫短条;
  3. 提交 pull request 請求合并到 develop 分支;
  4. 相關(guān)負(fù)責(zé)人 code review 后如果同意合并后才菠,刪除遠(yuǎn)程 feature 分支慌烧,如果不同意,重新修改后再上傳 feature 分支請求 pull request鸠儿。

Pull Request

Pull Request是當(dāng)功能開發(fā)者完成一個新功能后向項目維護者發(fā)送合并請求通知的機制。它的使用過程如下:

pull_request.png
  1. 功能開發(fā)者可以通過Gitlab頁面發(fā)送pull request
  2. 開發(fā)管理員自己或組織其他的團隊成員審查厕氨、討論和修改代碼
  3. 開發(fā)管理員合并新增功能分支到develop分支进每,然后關(guān)閉pull request,并且可以選擇刪除新增分支

工作流程

1?? 由開發(fā)管理員負(fù)責(zé)在Gitlab上創(chuàng)建空白的倉庫命斧,并clone到本地田晚,在sourcetree的git flow菜單中選擇初始化倉庫,并push到遠(yuǎn)端国葬。

init_repo.png

2?? 在Gitlab上設(shè)置保護分支贤徒,把master、develop分支保護起來汇四,只有指定人可push接奈。

3?? 功能開發(fā)者clone代碼到本地,先在sourcetree的git flow菜單中選擇初始化倉庫通孽。

init_repo.png

4?? 然后再開始新建功能分支序宦,進行開發(fā)工作。

new_feature.png

5?? 新功能開發(fā)全部完成或部分完成后背苦,功能開發(fā)者把最新代碼push到遠(yuǎn)端同樣的新功能分支里互捌,并在Gitflow發(fā)起pull request給開發(fā)管理員

6?? 開發(fā)管理員review代碼,選擇合并代碼到develop行剂,并可選擇刪除已經(jīng)合并的新功能分支

7?? 當(dāng)開發(fā)管理員處理完合并請求后秕噪,開發(fā)者,切換到develop分支,直接刪除自己的本地分支及遠(yuǎn)程分支厚宰,不要點擊完成(Finish Feature)腌巾,此時開發(fā)者pull遠(yuǎn)端develop分支最新代碼即可,可忽視本地的push提醒固阁。

delete_feature1.png

delete_feature2.png

8?? release壤躲、hotfix分支和feature分支操作類似。

9?? 不可點擊完成新功能备燃、完成發(fā)布版本碉克、完成修復(fù)補丁,因為這樣會導(dǎo)致自動合并代碼到master或develop分支

finish_feature_no.png

SourceTree mac版本下載地址

SourceTree_2.3.1.zip

鏈接:https://pan.baidu.com/s/1XHFvLh5MueebYjjGrEVcdQ 密碼:opjd

SourceTree win版本下載地址

SourceTree2480.zip

鏈接:https://pan.baidu.com/s/1z6UC7LrzJLNn9yeQnxoWyg 密碼:7uac

windows下使用sourcetree需要安裝一下軟件并齐,請在安裝sourcetree前安裝好:

Git-2.17.0-64-bit.exe

鏈接:https://pan.baidu.com/s/1q0WQw03U9oCmhN5Fii7PNQ 密碼:ab2n

mercurial-4.4.1-x64.msi

鏈接:https://pan.baidu.com/s/1PBIRFFMPsIe3MoV_42dDzg 密碼:nvkx

安裝SourceTree打開后會提示你Atlassian需要注冊漏麦,這家軟件公司在澳大利亞客税,所以注冊時需要翻墻,才能注冊成功撕贞,這里提供一個跳過注冊的方法

  1. 找到目錄:C:\Users\用戶\AppData\Local\Atlassian\SourceTree
  2. 新建accounts.json文件里面輸入下面代碼塊內(nèi)容后更耻,重新打開,就不會提示注冊了捏膨!
[  
  {  
    "$id": "1",  
    "$type": "SourceTree.Api.Host.Identity.Model.IdentityAccount, SourceTree.Api.Host.Identity",  
    "Authenticate": true,  
    "HostInstance": {  
      "$id": "2",  
      "$type": "SourceTree.Host.Atlassianaccount.AtlassianAccountInstance, SourceTree.Host.AtlassianAccount",  
      "Host": {  
        "$id": "3",  
        "$type": "SourceTree.Host.Atlassianaccount.AtlassianAccountHost, SourceTree.Host.AtlassianAccount",  
        "Id": "atlassian account"  
      },  
      "BaseUrl": "https://id.atlassian.com/"  
    },  
    "Credentials": {  
      "$id": "4",  
      "$type": "SourceTree.Model.BasicAuthCredentials, SourceTree.Api.Account",  
      "Username": "",  
      "Email": null  
    },  
    "IsDefault": false  
  }  
]

推薦工具

  • Git Flow 擴展 Git Flow模型提出者nvie寫的Git命令集擴展秧均,提供了極出色的命令幫助以及輸出提示。支持OSX号涯,Linux和Windows平臺目胡。參考:git-flow 備忘清單

參考資料

Git 工作流與規(guī)范
Commit message 和 Change log 編寫指南

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市链快,隨后出現(xiàn)的幾起案子誉己,更是在濱河造成了極大的恐慌,老刑警劉巖域蜗,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件巨双,死亡現(xiàn)場離奇詭異,居然都是意外死亡霉祸,警方通過查閱死者的電腦和手機筑累,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來脉执,“玉大人疼阔,你說我怎么就攤上這事“胍模” “怎么了婆廊?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長巫橄。 經(jīng)常有香客問我淘邻,道長,這世上最難降的妖魔是什么湘换? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任宾舅,我火速辦了婚禮,結(jié)果婚禮上彩倚,老公的妹妹穿的比我還像新娘筹我。我一直安慰自己,他們只是感情好帆离,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布蔬蕊。 她就那樣靜靜地躺著,像睡著了一般哥谷。 火紅的嫁衣襯著肌膚如雪岸夯。 梳的紋絲不亂的頭發(fā)上麻献,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天,我揣著相機與錄音猜扮,去河邊找鬼勉吻。 笑死,一個胖子當(dāng)著我的面吹牛旅赢,可吹牛的內(nèi)容都是我干的齿桃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼煮盼,長吁一口氣:“原來是場噩夢啊……” “哼源譬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起孕似,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎刮刑,沒想到半個月后喉祭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡雷绢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年泛烙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片翘紊。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蔽氨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帆疟,到底是詐尸還是另有隱情鹉究,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布踪宠,位于F島的核電站自赔,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏柳琢。R本人自食惡果不足惜绍妨,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柬脸。 院中可真熱鬧他去,春花似錦、人聲如沸倒堕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涩馆。三九已至行施,卻和暖如春允坚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蛾号。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工稠项, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人鲜结。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓展运,卻偏偏與公主長得像,于是被迫代替她去往敵國和親精刷。 傳聞我的和親對象是個殘疾皇子拗胜,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353