<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                既然是相互協作,在貢獻代碼的同時,也免不了要維護管理自己的項目。像是怎么處理別人用 format-patch 生成的補丁,或是集成遠端倉庫上某個分支上的變化等等。但無論是管理代碼倉庫,還是幫忙審核收到的補丁,都需要同貢獻者約定某種長期可持續的工作方式。 ## 使用特性分支進行工作 如果想要集成新的代碼進來,最好局限在特性分支上做。臨時的特性分支可以讓你隨意嘗試,進退自如。比如碰上無法正常工作的補丁,可以先擱在那邊,直到有時間仔細核查修復為止。創建的分支可以用相關的主題關鍵字命名,比如 ruby_client 或者其它類似的描述性詞語,以幫助將來回憶。Git 項目本身還時常把分支名稱分置于不同命名空間下,比如 sc/ruby_client 就說明這是 sc 這個人貢獻的。 現在從當前主干分支為基礎,新建臨時分支: `$ git branch sc/ruby_client master` 另外,如果你希望立即轉到分支上去工作,可以用 checkout -b: `$ git checkout -b sc/ruby_client master` 好了,現在已經準備妥當,可以試著將別人貢獻的代碼合并進來了。之后評估一下有沒有問題,最后再決定是不是真的要并入主干。 采納來自郵件的補丁 如果收到一個通過電郵發來的補丁,你應該先把它應用到特性分支上進行評估。有兩種應用補丁的方法:git apply 或者 git am。 使用 apply 命令應用補丁 如果收到的補丁文件是用 git diff 或由其它 Unix 的 diff 命令生成,就該用 git apply 命令來應用補丁。假設補丁文件存在 /tmp/patch-ruby-client.patch,可以這樣運行: `$ git apply /tmp/patch-ruby-client.patch` 這會修改當前工作目錄下的文件,效果基本與運行 patch -p1 打補丁一樣,但它更為嚴格,且不會出現混亂。如果是 git diff 格式描述的補丁,此命令還會相應地添加,刪除,重命名文件。當然,普通的 patch 命令是不會這么做的。另外請注意,git apply 是一個事務性操作的命令,也就是說,要么所有補丁都打上去,要么全部放棄。所以不會出現 patch 命令那樣,一部分文件打上了補丁而另一部分卻沒有,這樣一種不上不下的修訂狀態。所以總的來說,git apply 要比 patch 嚴謹許多。因為僅僅是更新當前的文件,所以此命令不會自動生成提交對象,你得手工緩存相應文件的更新狀態并執行提交命令。 在實際打補丁之前,可以先用 `git apply --chec`k 查看補丁是否能夠干凈順利地應用到當前分支中: ~~~ $ git apply --check 0001-seeing-if-this-helps-the-gem.patch error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply ~~~ 如果沒有任何輸出,表示我們可以順利采納該補丁。如果有問題,除了報告錯誤信息之外,該命令還會返回一個非零的狀態,所以在 shell 腳本里可用于檢測狀態。 ## 使用 am 命令應用補丁 如果貢獻者也用 Git,且擅于制作 format-patch 補丁,那你的合并工作將會非常輕松。因為這些補丁中除了文件內容差異外,還包含了作者信息和提交消息。所以請鼓勵貢獻者用 format-patch 生成補丁。對于傳統的 diff 命令生成的補丁,則只能用 git apply 處理。 對于 format-patch 制作的新式補丁,應當使用 git am 命令。從技術上來說,git am 能夠讀取 mbox 格式的文件。這是種簡單的純文本文件,可以包含多封電郵,格式上用 From 加空格以及隨便什么輔助信息所組成的行作為分隔行,以區分每封郵件,就像這樣: ~~~ From 330090432754092d704da8e76ca5c05c198e71a8 Mon Sep 17 00:00:00 2001 From: Jessica Smith <jessica@example.com> Date: Sun, 6 Apr 2008 10:17:23 -0700 Subject: [PATCH 1/2] add limit to log function Limit log functionality to the first 20 ~~~ 這是 format-patch 命令輸出的開頭幾行,也是一個有效的 mbox 文件格式。如果有人用 git send-email 給你發了一個補丁,你可以將此郵件下載到本地,然后運行 git am 命令來應用這個補丁。如果你的郵件客戶端能將多封電郵導出為 mbox 格式的文件,就可以用 git am 一次性應用所有導出的補丁。 如果貢獻者將 format-patch 生成的補丁文件上傳到類似 Request Ticket 一樣的任務處理系統,那么可以先下載到本地,繼而使用 git am 應用該補丁: ~~~ $ git am 0001-limit-log-function.patch Applying: add limit to log function ~~~ 你會看到它被干凈地應用到本地分支,并自動創建了新的提交對象。作者信息取自郵件頭 From 和 Date,提交消息則取自 Subject 以及正文中補丁之前的內容。來看具體實例,采納之前展示的那個 mbox 電郵補丁后,最新的提交對象為: ~~~ $ git log --pretty=fuller -1 commit 6c5e70b984a60b3cecd395edd5b48a7575bf58e0 Author: Jessica Smith <jessica@example.com> AuthorDate: Sun Apr 6 10:17:23 2008 -0700 Commit: Scott Chacon <schacon@gmail.com> CommitDate: Thu Apr 9 09:19:06 2009 -0700 add limit to log function Limit log functionality to the first 20 ~~~ Commit 部分顯示的是采納補丁的人,以及采納的時間。而 Author 部分則顯示的是原作者,以及創建補丁的時間。 有時,我們也會遇到打不上補丁的情況。這多半是因為主干分支和補丁的基礎分支相差太遠,但也可能是因為某些依賴補丁還未應用。這種情況下,git am 會報錯并詢問該怎么做: ~~~ $ git am 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply Patch failed at 0001. When you have resolved this problem run "git am --resolved". If you would prefer to skip this patch, instead run "git am --skip". To restore the original branch and stop patching run "git am --abort". ~~~ Git 會在有沖突的文件里加入沖突解決標記,這同合并或衍合操作一樣。解決的辦法也一樣,先編輯文件消除沖突,然后暫存文件,最后運行 git am --resolved 提交修正結果: ~~~ $ (fix the file) $ git add ticgit.gemspec $ git am --resolved Applying: seeing if this helps the gem ~~~ 如果想讓 Git 更智能地處理沖突,可以用 -3 選項進行三方合并。如果當前分支未包含該補丁的基礎代碼或其祖先,那么三方合并就會失敗,所以該選項默認為關閉狀態。一般來說,如果該補丁是基于某個公開的提交制作而成的話,你總是可以通過同步來獲取這個共同祖先,所以用三方合并選項可以解決很多麻煩: ~~~ $ git am -3 0001-seeing-if-this-helps-the-gem.patch Applying: seeing if this helps the gem error: patch failed: ticgit.gemspec:1 error: ticgit.gemspec: patch does not apply Using index info to reconstruct a base tree... Falling back to patching base and 3-way merge... No changes -- Patch already applied. ~~~ 像上面的例子,對于打過的補丁我又再打一遍,自然會產生沖突,但因為加上了 -3 選項,所以它很聰明地告訴我,無需更新,原有的補丁已經應用。 對于一次應用多個補丁時所用的 mbox 格式文件,可以用 am 命令的交互模式選項 -i,這樣就會在打每個補丁前停住,詢問該如何操作: ~~~ $ git am -3 -i mbox Commit Body is: -------------------------- seeing if this helps the gem -------------------------- Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all ~~~ 在多個補丁要打的情況下,這是個非常好的辦法,一方面可以預覽下補丁內容,同時也可以有選擇性的接納或跳過某些補丁。 打完所有補丁后,如果測試下來新特性可以正常工作,那就可以安心地將當前特性分支合并到長期分支中去了。 ## 檢出遠程分支 如果貢獻者有自己的 Git 倉庫,并將修改推送到此倉庫中,那么當你拿到倉庫的訪問地址和對應分支的名稱后,就可以加為遠程分支,然后在本地進行合并。 比如,Jessica 發來一封郵件,說在她代碼庫中的 ruby-client 分支上已經實現了某個非常棒的新功能,希望我們能幫忙測試一下。我們可以先把她的倉庫加為遠程倉庫,然后抓取數據,完了再將她所說的分支檢出到本地來測試: ~~~ $ git remote add jessica git://github.com/jessica/myproject.git $ git fetch jessica $ git checkout -b rubyclient jessica/ruby-client ~~~ 若是不久她又發來郵件,說還有個很棒的功能實現在另一分支上,那我們只需重新抓取下最新數據,然后檢出那個分支到本地就可以了,無需重復設置遠程倉庫。 這種做法便于同別人保持長期的合作關系。但前提是要求貢獻者有自己的服務器,而我們也需要為每個人建一個遠程分支。有些貢獻者提交代碼補丁并不是很頻繁,所以通過郵件接收補丁效率會更高。同時我們自己也不會希望建上百來個分支,卻只從每個分支取一兩個補丁。但若是用腳本程序來管理,或直接使用代碼倉庫托管服務,就可以簡化此過程。當然,選擇何種方式取決于你和貢獻者的喜好。 使用遠程分支的另外一個好處是能夠得到提交歷史。不管代碼合并是不是會有問題,至少我們知道該分支的歷史分叉點,所以默認會從共同祖先開始自動進行三方合并,無需 -3 選項,也不用像打補丁那樣祈禱存在共同的基準點。 如果只是臨時合作,只需用 git pull 命令抓取遠程倉庫上的數據,合并到本地臨時分支就可以了。一次性的抓取動作自然不會把該倉庫地址加為遠程倉庫。 ~~~ $ git pull git://github.com/onetimeguy/project.git From git://github.com/onetimeguy/project * branch HEAD -> FETCH_HEAD Merge made by recursive. ~~~ ## 決斷代碼取舍 現在特性分支上已合并好了貢獻者的代碼,是時候決斷取舍了。本節將回顧一些之前學過的命令,以看清將要合并到主干的是哪些代碼,從而理解它們到底做了些什么,是否真的要并入。 一般我們會先看下,特性分支上都有哪些新增的提交。比如在 contrib 特性分支上打了兩個補丁,僅查看這兩個補丁的提交信息,可以用 --not 選項指定要屏蔽的分支 master,這樣就會剔除重復的提交歷史: ~~~ $ git log contrib --not master commit 5b6235bd297351589efc4d73316f0a68d484f118 Author: Scott Chacon <schacon@gmail.com> Date: Fri Oct 24 09:53:59 2008 -0700 seeing if this helps the gem commit 7482e0d16d04bea79d0dba8988cc78df655f16a0 Author: Scott Chacon <schacon@gmail.com> Date: Mon Oct 22 19:38:36 2008 -0700 updated the gemspec to hopefully work better ~~~ 還可以查看每次提交的具體修改。請牢記,在 git log 后加 -p 選項將展示每次提交的內容差異。 如果想看當前分支同其他分支合并時的完整內容差異,有個小竅門: `$ git diff master` 雖然能得到差異內容,但請記住,結果有可能和我們的預期不同。一旦主干 master 在特性分支創建之后有所修改,那么通過 diff 命令來比較的,是最新主干上的提交快照。顯然,這不是我們所要的。比方在 master 分支中某個文件里添了一行,然后運行上面的命令,簡單的比較最新快照所得到的結論只能是,特性分支中刪除了這一行。 這個很好理解:如果 master 是特性分支的直接祖先,不會產生任何問題;如果它們的提交歷史在不同的分叉上,那么產生的內容差異,看起來就像是增加了特性分支上的新代碼,同時刪除了 master 分支上的新代碼。 實際上我們真正想要看的,是新加入到特性分支的代碼,也就是合并時會并入主干的代碼。所以,準確地講,我們應該比較特性分支和它同 master 分支的共同祖先之間的差異。 我們可以手工定位它們的共同祖先,然后與之比較: ~~~ $ git merge-base contrib master 36c7dba2c95e6bbb78dfa822519ecfec6e1ca649 $ git diff 36c7db ~~~ 但這么做很麻煩,所以 Git 提供了便捷的 ... 語法。對于 diff 命令,可以把 ... 加在原始分支(擁有共同祖先)和當前分支之間: `$ git diff master...contrib` 現在看到的,就是實際將要引入的新代碼。這是一個非常有用的命令,應該牢記。 ## 代碼集成 一旦特性分支準備停當,接下來的問題就是如何集成到更靠近主線的分支中。此外還要考慮維護項目的總體步驟是什么。雖然有很多選擇,不過我們這里只介紹其中一部分。 ## 合并流程 一般最簡單的情形,是在 master 分支中維護穩定代碼,然后在特性分支上開發新功能,或是審核測試別人貢獻的代碼,接著將它并入主干,最后刪除這個特性分支,如此反復。來看示例,假設當前代碼庫中有兩個分支,分別為 ruby_client 和 php_client,如圖 5-19 所示。然后先把 ruby_client 合并進主干,再合并 php_client,最后的提交歷史如圖 5-20 所示。 ![2015-05-19/555aeb601aa9e](https://box.kancloud.cn/2015-05-19_555aeb601aa9e.png) 圖 5-19. 多個特性分支 ![2015-05-19/555aeb7dde33e](https://box.kancloud.cn/2015-05-19_555aeb7dde33e.png) 圖 5-20. 合并特性分支之后 這是最簡單的流程,所以在處理大一些的項目時可能會有問題。 對于大型項目,至少需要維護兩個長期分支 master 和 develop。新代碼(圖 5-21 中的 ruby_client)將首先并入 develop 分支(圖 5-22 中的 C8),經過一個階段,確認 develop 中的代碼已穩定到可發行時,再將 master 分支快進到穩定點(圖 5-23 中的 C8)。而平時這兩個分支都會被推送到公開的代碼庫。 圖 5-21. 特性分支合并前 ![2015-05-19/555aebcb4db70](https://box.kancloud.cn/2015-05-19_555aebcb4db70.png) 圖 5-22. 特性分支合并后 ![2015-05-19/555aed4b2883a](https://box.kancloud.cn/2015-05-19_555aed4b2883a.png) 圖 5-23. 特性分支發布后 這樣,在人們克隆倉庫時就有兩種選擇:既可檢出最新穩定版本,確保正常使用;也能檢出開發版本,試用最前沿的新特性。 你也可以擴展這個概念,先將所有新代碼合并到臨時特性分支,等到該分支穩定下來并通過測試后,再并入 develop 分支。然后,讓時間檢驗一切,如果這些代碼確實可以正常工作相當長一段時間,那就有理由相信它已經足夠穩定,可以放心并入主干分支發布。 ## 大項目的合并流程 Git 項目本身有四個長期分支:用于發布的 master 分支、用于合并基本穩定特性的 next 分支、用于合并仍需改進特性的 pu 分支(pu 是 proposed updates 的縮寫),以及用于除錯維護的 maint 分支(maint 取自 maintenance)。維護者可以按照之前介紹的方法,將貢獻者的代碼引入為不同的特性分支(如圖 5-24 所示),然后測試評估,看哪些特性能穩定工作,哪些還需改進。穩定的特性可以并入 next 分支,然后再推送到公共倉庫,以供其他人試用。 ![2015-05-19/555aed6d3119f](https://box.kancloud.cn/2015-05-19_555aed6d3119f.png) 圖 5-24. 管理復雜的并行貢獻 仍需改進的特性可以先并入 pu 分支。直到它們完全穩定后再并入 master。同時一并檢查下 next 分支,將足夠穩定的特性也并入 master。所以一般來說,master 始終是在快進,next 偶爾做下衍合,而 pu 則是頻繁衍合,如圖 5-25 所示: ![2015-05-19/555aedada2a91](https://box.kancloud.cn/2015-05-19_555aedada2a91.png) 圖 5-25. 將特性并入長期分支 并入 master 后的特性分支,已經無需保留分支索引,放心刪除好了。Git 項目還有一個 maint 分支,它是以最近一次發行版為基礎分化而來的,用于維護除錯補丁。所以克隆 Git 項目倉庫后會得到這四個分支,通過檢出不同分支可以了解各自進展,或是試用前沿特性,或是貢獻代碼。而維護者則通過管理這些分支,逐步有序地并入第三方貢獻。 ## 衍合與挑揀(cherry-pick)的流程 一些維護者更喜歡衍合或者挑揀貢獻者的代碼,而不是簡單的合并,因為這樣能夠保持線性的提交歷史。如果你完成了一個特性的開發,并決定將它引入到主干代碼中,你可以轉到那個特性分支然后執行衍合命令,好在你的主干分支上(也可能是develop分支之類的)重新提交這些修改。如果這些代碼工作得很好,你就可以快進master分支,得到一個線性的提交歷史。 另一個引入代碼的方法是挑揀。挑揀類似于針對某次特定提交的衍合。它首先提取某次提交的補丁,然后試著應用在當前分支上。如果某個特性分支上有多個commits,但你只想引入其中之一就可以使用這種方法。也可能僅僅是因為你喜歡用挑揀,討厭衍合。假設你有一個類似圖 5-26 的工程。 ![2015-05-19/555aedbe58365](https://box.kancloud.cn/2015-05-19_555aedbe58365.png) 圖 5-26. 挑揀(cherry-pick)之前的歷史 如果你希望拉取e43a6到你的主干分支,可以這樣: ~~~ $ git cherry-pick e43a6fd3e94888d76779ad79fb568ed180e5fcdf Finished one cherry-pick. [master]: created a0a41a9: "More friendly message when locking the index fails." 3 files changed, 17 insertions(+), 3 deletions(-) ~~~ 這將會引入e43a6的代碼,但是會得到不同的SHA-1值,因為應用日期不同。現在你的歷史看起來像圖 5-27. ![2015-05-19/555aedcfd1b3f](https://box.kancloud.cn/2015-05-19_555aedcfd1b3f.png) 圖 5-27. 挑揀(cherry-pick)之后的歷史 現在,你可以刪除這個特性分支并丟棄你不想引入的那些commit。 ## 給發行版簽名 你可以刪除上次發布的版本并重新打標簽,也可以像第二章所說的那樣建立一個新的標簽。如果你決定以維護者的身份給發行版簽名,應該這樣做: ~~~ $ git tag -s v1.5 -m 'my signed 1.5 tag' You need a passphrase to unlock the secret key for user: "Scott Chacon <schacon@gmail.com>" 1024-bit DSA key, ID F721C45A, created 2009-02-09 ~~~ 完成簽名之后,如何分發PGP公鑰(public key)是個問題。(譯者注:分發公鑰是為了驗證標簽)。還好,Git的設計者想到了解決辦法:可以把key(即公鑰)作為blob變量寫入Git庫,然后把它的內容直接寫在標簽里。gpg --list-keys命令可以顯示出你所擁有的key: ~~~ $ gpg --list-keys /Users/schacon/.gnupg/pubring.gpg --------------------------------- pub 1024D/F721C45A 2009-02-09 [expires: 2010-02-09] uid Scott Chacon <schacon@gmail.com> sub 2048g/45D02282 2009-02-09 [expires: 2010-02-09] ~~~ 然后,導出key的內容并經由管道符傳遞給git hash-object,之后鑰匙會以blob類型寫入Git中,最后返回這個blob量的SHA-1值: ~~~ $ gpg -a --export F721C45A | git hash-object -w --stdin 659ef797d181633c87ec71ac3f9ba29fe5775b92 ~~~ 現在你的Git已經包含了這個key的內容了,可以通過不同的SHA-1值指定不同的key來創建標簽。 `$ git tag -a maintainer-pgp-pub 659ef797d181633c87ec71ac3f9ba29fe5775b92` 在運行git push --tags命令之后,maintainer-pgp-pub標簽就會公布給所有人。如果有人想要校驗標簽,他可以使用如下命令導入你的key: `$ git show maintainer-pgp-pub | gpg --import` 人們可以用這個key校驗你簽名的所有標簽。另外,你也可以在標簽信息里寫入一個操作向導,用戶只需要運行git show <tag>查看標簽信息,然后按照你的向導就能完成校驗。 ## 生成內部版本號 因為Git不會為每次提交自動附加類似'v123'的遞增序列,所以如果你想要得到一個便于理解的提交號可以運行git describe命令。Git將會返回一個字符串,由三部分組成:最近一次標定的版本號,加上自那次標定之后的提交次數,再加上一段所描述的提交的SHA-1值: ~~~ $ git describe master v1.6.2-rc1-20-g8c5b85c ~~~ 這個字符串可以作為快照的名字,方便人們理解。如果你的Git是你自己下載源碼然后編譯安裝的,你會發現git --version命令的輸出和這個字符串差不多。如果在一個剛剛打完標簽的提交上運行describe命令,只會得到這次標定的版本號,而沒有后面兩項信息。 git describe命令只適用于有標注的標簽(通過-a或者-s選項創建的標簽),所以發行版的標簽都應該是帶有標注的,以保證git describe能夠正確的執行。你也可以把這個字符串作為checkout或者show命令的目標,因為他們最終都依賴于一個簡短的SHA-1值,當然如果這個SHA-1值失效他們也跟著失效。最近Linux內核為了保證SHA-1值的唯一性,將位數由8位擴展到10位,這就導致擴展之前的git describe輸出完全失效了。 ## 準備發布 現在可以發布一個新的版本了。首先要將代碼的壓縮包歸檔,方便那些可憐的還沒有使用Git的人們。可以使用git archive: ~~~ $ git archive master --prefix='project/' | gzip > `git describe master`.tar.gz $ ls *.tar.gz v1.6.2-rc1-20-g8c5b85c.tar.gz ~~~ 這個壓縮包解壓出來的是一個文件夾,里面是你項目的最新代碼快照。你也可以用類似的方法建立一個zip壓縮包,在git archive加上--format=zip選項: `$ git archive master --prefix='project/' --format=zip > `git describe master`.zip` 現在你有了一個tar.gz壓縮包和一個zip壓縮包,可以把他們上傳到你網站上或者用e-mail發給別人。 ## 制作簡報 是時候通知郵件列表里的朋友們來檢驗你的成果了。使用git shortlog命令可以方便快捷的制作一份修改日志(changelog),告訴大家上次發布之后又增加了哪些特性和修復了哪些bug。實際上這個命令能夠統計給定范圍內的所有提交;假如你上一次發布的版本是v1.0.1,下面的命令將給出自從上次發布之后的所有提交的簡介: ~~~ $ git shortlog --no-merges master --not v1.0.1 Chris Wanstrath (8): Add support for annotated tags to Grit::Tag Add packed-refs annotated tag support. Add Grit::Commit#to_patch Update version and History.txt Remove stray `puts` Make ls_tree ignore nils Tom Preston-Werner (4): fix dates in history dynamic version method Version bump to 1.0.2 Regenerated gemspec for version 1.0.2 ~~~ 這就是自從v1.0.1版本以來的所有提交的簡介,內容按照作者分組,以便你能快速的發e-mail給他們。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看