帶你徹底搞懂Git上的遠程分支與變基【云駐計劃】(git 覆蓋遠程分支)
Git分支-遠程分支
遠程引用是對遠程倉庫的引用(指針),包括分支、標簽等等。
遠程分支本質(zhì)上也是一個指針,指向遠程地址
查看遠程引用列表與信息
git ls-remote
上面兩行命令比較少用,更常見的做法是利用遠程跟蹤分支。
遠程跟蹤分支
遠程跟蹤分支是遠程分支狀態(tài)的引用。它們是你無法移動的本地引用。一旦你進行了網(wǎng)絡(luò)通信, Git 就會為你移動它們以精確反映遠程倉庫的狀態(tài)。請將它們看做書簽, 這樣可以提醒你該分支在遠程倉庫中的位置就是你最后一次連接到它們的位置。
它們以
這可能有一點兒難以理解,讓我們來看一個例子。 假設(shè)你的網(wǎng)絡(luò)里有一個在 git.ourcompany.com 的 Git 服務(wù)器。 如果你從這里克隆,Git 的 clone 命令會為你自動將其命名為 origin,拉取它的所有數(shù)據(jù), 創(chuàng)建一個指向它的 master 分支的指針,并且在本地將其命名為 origin/master。 Git 也會給你一個與 origin 的 master 分支在指向同一個地方的本地 master 分支,這樣你就有工作的基礎(chǔ)。
筆記:從遠程克隆下來的倉庫有一個叫origin/master的遠程跟蹤分支 和 一個本地的master分支
筆記:“origin” 并無特殊含義遠程倉庫名字 “origin” 與分支名字 “master” 一樣,在 Git 中并沒有任何特別的含義一樣。 同時 “master” 是當你運行 git init 時默認的起始分支名字,原因僅僅是它的廣泛使用, “origin” 是當你運行 git clone 時默認的遠程倉庫名字。 如果你運行 git clone -o booyah,那么你默認的遠程分支名字將會是 booyah/master。
圖1. 克隆之后的服務(wù)器與本地倉庫 ▲
如果你在本地的 master 分支做了一些工作,在同一段時間內(nèi)有其他人推送提交到 git.ourcompany.com 并且更新了它的 master 分支,這就是說你們的提交歷史已走向不同的方向。 即便這樣,只要你保持不與 origin 服務(wù)器連接(并拉取數(shù)據(jù)),你的 origin/master 指針就不會移動。
圖2. 本地與遠程的工作可以分叉 ▲
如果要與給定的遠程倉庫同步數(shù)據(jù),運行 git fetch
圖3. git fetch 更新你的遠程跟蹤分支 ▲
筆記: 本地的 master 分支 可能 和 遠程跟蹤分支 origin/master 分叉
為了演示有多個遠程倉庫與遠程分支的情況,我們假定你有另一個內(nèi)部 Git 服務(wù)器,僅服務(wù)于你的某個敏捷開發(fā)團隊。 這個服務(wù)器位于 git.team1.ourcompany.com。 你可以運行 git remote add 命令添加一個新的遠程倉庫引用到當前的項目,這個命令我們會在 Git 基礎(chǔ) 中詳細說明。 將這個遠程倉庫命名為 teamone,將其作為完整 URL 的縮寫。
遠程倉庫名本質(zhì)上是遠程URL的縮寫
圖4. 添加另一個遠程倉庫 ▲
現(xiàn)在,可以運行 git fetch teamone 來抓取遠程倉庫 teamone 有而本地沒有的數(shù)據(jù)。 因為那臺服務(wù)器上現(xiàn)有的數(shù)據(jù)是 origin 服務(wù)器上的一個子集, 所以 Git 并不會抓取數(shù)據(jù)而是會設(shè)置遠程跟蹤分支 teamone/master 指向 teamone 的 master 分支。
圖5. 遠程跟蹤分支 teamone/master ▲
推送
當你想要公開分享一個分支時,需要將其推送到有寫入權(quán)限的遠程倉庫上。 本地的分支并不會自動與遠程倉庫同步——你必須顯式地推送想要分享的分支。 這樣,你就可以把不愿意分享的內(nèi)容放到私人分支上,而將需要和別人協(xié)作的內(nèi)容推送到公開分支。
如果希望和別人一起在名為 serverfix 的分支上工作,你可以像推送第一個分支那樣推送它。 運行 git push
$ git push origin serverfix Counting objects: 24, done. Delta compression using up to 8 threads. Compressing objects: 100% (15/15), done. Writing objects: 100% (24/24), 1.91 KiB | 0 bytes/s, done. Total 24 (delta 2), reused 0 (delta 0) To https://github.com/schacon/simplegit * [new branch] serverfix -> serverfix
這里有些工作被簡化了。 Git 自動將 serverfix 分支名字展開為 refs/heads/serverfix:refs/heads/serverfix, 那意味著,“推送本地的 serverfix 分支來更新遠程倉庫上的 serverfix 分支?!?我們將會詳細學習 Git 內(nèi)部原理 的 refs/heads/ 部分, 但是現(xiàn)在可以先把它放在兒。你也可以運行 git push origin serverfix:serverfix, 它會做同樣的事——也就是說“推送本地的 serverfix 分支,將其作為遠程倉庫的 serverfix 分支” 可以通過這種格式來推送本地分支到一個命名不相同的遠程分支。
如果并不想讓遠程倉庫上的分支叫做 serverfix,可以運行 git push origin serverfix:awesomebranch 來將本地的 serverfix 分支推送到遠程倉庫上的 awesomebranch 分支。
$ git fetch origin remote: Counting objects: 7, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0) Unpacking objects: 100% (3/3), done. From https://github.com/schacon/simplegit * [new branch] serverfix -> origin/serverfix
要特別注意的一點是當抓取到新的遠程跟蹤分支時,本地不會自動生成一份可編輯的副本(拷貝)。 換一句話說,這種情況下,不會有一個新的 serverfix 分支——只有一個不可以修改的 origin/serverfix 指針。
可以運行 git merge origin/serverfix 將這些工作合并到當前所在的分支。 如果想要在自己的 serverfix 分支上工作,可以將其建立在遠程跟蹤分支之上:
$ git checkout -b serverfix origin/serverfix Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix'
這會給你一個用于工作的本地分支,并且起點位于 origin/serverfix。
跟蹤分支
從一個遠程跟蹤分支檢出一個本地分支會自動創(chuàng)建所謂的“跟蹤分支”(它跟蹤的分支叫做“上游分支”)。 跟蹤分支是與遠程分支有直接關(guān)系的本地分支。 如果在一個跟蹤分支上輸入 git pull,Git 能自動地識別去哪個服務(wù)器上抓取、合并到哪個分支。
當克隆一個倉庫時,它通常會自動地創(chuàng)建一個跟蹤 origin/master 的 master 分支。 然而,如果你愿意的話可以設(shè)置其他的跟蹤分支,或是一個在其他遠程倉庫上的跟蹤分支,又或者不跟蹤 master 分支。 最簡單的實例就是像之前看到的那樣,運行 git checkout -b
$ git checkout --track origin/serverfix Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix'
由于這個操作太常用了,該捷徑本身還有一個捷徑。 如果你嘗試檢出的分支 (a) 不存在且 (b) 剛好只有一個名字與之匹配的遠程分支,那么 Git 就會為你創(chuàng)建一個跟蹤分支:
$ git checkout serverfix Branch serverfix set up to track remote branch serverfix from origin. Switched to a new branch 'serverfix'
如果想要將本地分支與遠程分支設(shè)置為不同的名字,你可以輕松地使用上一個命令增加一個不同名字的本地分支:
$ git checkout -b sf origin/serverfix Branch sf set up to track remote branch serverfix from origin. Switched to a new branch 'sf'
現(xiàn)在,本地分支 sf 會自動從 origin/serverfix 拉取。
設(shè)置已有的本地分支跟蹤一個剛剛拉取下來的遠程分支,或者想要修改正在跟蹤的上游分支, 你可以在任意時間使用 -u 或 --set-upstream-to 選項運行 git branch 來顯式地設(shè)置。
$ git branch -u origin/serverfix Branch serverfix set up to track remote branch serverfix from origin.
查看跟蹤分支
如果想要查看設(shè)置的所有跟蹤分支,可以使用 git branch 的 -vv 選項。 這會將所有的本地分支列出來并且包含更多的信息,如每一個分支正在跟蹤哪個遠程分支與本地分支是否是領(lǐng)先、落后或是都有。
$ git branch -vv iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets master 1ae2a45 [origin/master] deploying index fix * serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it testing 5ea463a trying something new
這里可以看到 iss53 分支正在跟蹤 origin/iss53 并且 “ahead” 是 2,意味著本地有兩個提交還沒有推送到服務(wù)器上。 也能看到 master 分支正在跟蹤 origin/master 分支并且是最新的。 接下來可以看到 serverfix 分支正在跟蹤 teamone 服務(wù)器上的 server-fix-good 分支并且領(lǐng)先 3 落后 1, 意味著服務(wù)器上有一次提交還沒有合并入同時本地有三次提交還沒有推送。 最后看到 testing 分支并沒有跟蹤任何遠程分支。
需要重點注意的一點是這些數(shù)字的值來自于你從每個服務(wù)器上最后一次抓取的數(shù)據(jù)。 這個命令并沒有連接服務(wù)器,它只會告訴你關(guān)于本地緩存的服務(wù)器數(shù)據(jù)。 如果想要統(tǒng)計最新的領(lǐng)先與落后數(shù)字,需要在運行此命令前抓取所有的遠程倉庫。 可以像這樣做:
$ git fetch --all; git branch -vv
拉取
當 git fetch 命令從服務(wù)器上抓取本地沒有的數(shù)據(jù)時,它并不會修改工作目錄中的內(nèi)容。 它只會獲取數(shù)據(jù)然后讓你自己合并。 然而,有一個命令叫作 git pull 在大多數(shù)情況下它的含義是一個 git fetch 緊接著一個 git merge 命令。 如果有一個像之前章節(jié)中演示的設(shè)置好的跟蹤分支,不管它是顯式地設(shè)置還是通過 clone 或 checkout 命令為你創(chuàng)建的,git pull 都會查找當前分支所跟蹤的服務(wù)器與分支, 從服務(wù)器上抓取數(shù)據(jù)然后嘗試合并入那個遠程分支。
由于 git pull 的魔法經(jīng)常令人困惑所以通常單獨顯式地使用 fetch 與 merge 命令會更好一些。
刪除遠程分支
$ git push origin --delete serverfix To https://github.com/schacon/simplegit - [deleted] serverfix
基本上這個命令做的只是從服務(wù)器上移除這個指針。 Git 服務(wù)器通常會保留數(shù)據(jù)一段時間直到垃圾回收運行,所以如果不小心刪除掉了,通常是很容易恢復的。
Git分支-變基
在 Git 中整合來自不同分支的修改主要有兩種方法:merge 以及 rebase。 在本節(jié)中我們將學習什么是“變基”,怎樣使用“變基”,并將展示該操作的驚艷之處,以及指出在何種情況下你應(yīng)避免使用它。
變基的基本操作
請回顧之前在 分支的合并 中的一個例子,你會看到開發(fā)任務(wù)分叉到兩個不同分支,又各自提交了更新。
圖0. 分叉的提交歷史 ▲
之前介紹過,整合分支最容易的方法是 merge 命令。 它會把兩個分支的最新快照(C3 和 C4)以及二者最近的共同祖先(C2)進行三方合并,合并的結(jié)果是生成一個新的快照(并提交)。
圖1. 通過合并操作來整合分叉的歷史 ▲
概念
變基就是:將某一分支上的所有修改復制到另一分支上
除了merge,還有一種方法:你可以提取在 C4 中引入的補丁和修改,然后在 C3 的基礎(chǔ)上應(yīng)用一次。 在 Git 中,這種操作就叫做 變基(rebase)。 你可以使用 rebase 命令將提交到某一分支上的所有修改都移到另一分支上,就好像“重新播放”一樣。
在這個例子中,你可以檢出 experiment 分支,然后將它變基到 master 分支上:
$ git checkout experiment $ git rebase master # 將experiment上的修改變基到master分支上(將experiment的提交移動到master上。) First, rewinding head to replay your work on top of it... Applying: added staged command
它的原理是首先找到這兩個分支(即當前分支 experiment、變基操作的目標基底分支 master) 的最近共同祖先 C2,然后對比當前分支相對于該祖先的歷次提交,提取相應(yīng)的修改并存為臨時文件, 然后將當前分支指向目標基底 C3, 最后以此將之前另存為臨時文件的修改依序應(yīng)用。 (譯注:寫明了 commit id,以便理解,下同)
原理
找到當前分支和目標分支的最近共同祖先
對比當前分支相對于該共同祖先的歷次提交
提取相應(yīng)的修改并存為臨時文件
將當前分支指向目標分支
將之前臨時文件的修改依序應(yīng)用
圖2.將 C4 中的修改變基到 C3 上 ▲
現(xiàn)在回到 master 分支,進行一次快進合并。
$ git checkout master $ git merge experiment
圖3.master 分支的快進合并 ▲
步驟
先檢出源分支,將源分支的修改變基到目標分支。切回目標分支,進行一次快進合并
# 示意: git checkout <源分支> git (源分支的修改)rebase(到) <目標分支> git checkout <目標分支> git merge <源分支>
此時,C4' 指向的快照就和 the merge example 中 C5 指向的快照一模一樣了。 這兩種整合方法的最終結(jié)果沒有任何區(qū)別,但是 變基使得提交歷史更加整潔。 你在查看一個經(jīng)過變基的分支的歷史記錄時會發(fā)現(xiàn),盡管實際的開發(fā)工作是并行的, 但它們看上去就像是串行的一樣,提交歷史是一條直線沒有分叉。
一般我們這樣做的目的是為了確保在向遠程分支推送時能保持提交歷史的整潔——例如向某個其他人維護的項目貢獻代碼時。 在這種情況下,你首先在自己的分支里進行開發(fā),當開發(fā)完成時你需要先將你的代碼變基到 origin/master 上,然后再向主項目提交修改。 這樣的話,該項目的維護者就不再需要進行整合工作,只需要快進合并便可。
請注意,無論是通過變基,還是通過三方合并,整合的最終結(jié)果所指向的快照始終是一樣的,只不過提交歷史不同罷了。 變基是將一系列提交按照原有次序依次應(yīng)用到另一分支上,而合并是把最終結(jié)果合在一起。
優(yōu)點
變基的優(yōu)點: 使提交記錄更加整潔。
更有趣的變基例子
在對兩個分支進行變基時,所生成的“重放”并不一定要在目標分支上應(yīng)用,你也可以指定另外的一個分支進行應(yīng)用。 就像 從一個主題分支里再分出一個主題分支的提交歷史 中的例子那樣。 你創(chuàng)建了一個主題分支 server,為服務(wù)端添加了一些功能,提交了 C3 和 C4。 然后從 C3 上創(chuàng)建了主題分支 client,為客戶端添加了一些功能,提交了 C8 和 C9。 最后,你回到 server 分支,又提交了 C10。
更有趣的變基例子
在對兩個分支進行變基時,所生成的“重放”并不一定要在目標分支上應(yīng)用,你也可以指定另外的一個分支進行應(yīng)用。 就像 從一個主題分支里再分出一個主題分支的提交歷史 中的例子那樣。 你創(chuàng)建了一個主題分支 server,為服務(wù)端添加了一些功能,提交了 C3 和 C4。 然后從 C3 上創(chuàng)建了主題分支 client,為客戶端添加了一些功能,提交了 C8 和 C9。 最后,你回到 server 分支,又提交了 C10。
圖4.從一個主題分支里再分出一個主題分支的提交歷史 ▲
假設(shè)你希望將 client 中的修改合并到主分支并發(fā)布,但暫時并不想合并 server 中的修改, 因為它們還需要經(jīng)過更全面的測試。這時,你就可以使用 git rebase 命令的 --onto 選項, 選中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9),將它們在 master 分支上重放:
$ git rebase --onto master server client
以上命令的意思是:“取出 client 分支,找出它從 server 分支分歧之后的補丁, 然后把這些補丁在 master 分支上重放一遍,讓 client 看起來像直接基于 master 修改一樣”。這理解起來有一點復雜,不過效果非???。
--onto選項
選中C分支中的但不在B分支里的修改,應(yīng)用到A分支。
圖5.截取主題分支上的另一個主題分支,然后變基到其他分支 ▲
現(xiàn)在可以快進合并 master 分支了。(如圖 快進合并 master 分支,使之包含來自 client 分支的修改):
$ git checkout master $ git merge client
圖6.快進合并 `master` 分支,使之包含來自 `client` 分支的修改 ▲
省去先切換到源分支的步驟
git rebase <目標(當前)分支> <源分支> # 將源分支變基到目標分支。執(zhí)行此命令后會自動切換到源分支 git checkout <目標分支> git merge <源分支>
注意:使用這個方法要確保源分支上的代碼是最新的。
接下來你決定將 server 分支中的修改也整合進來。 使用 git rebase
$ git rebase master server
如圖 將 server 中的修改變基到 master 上 所示,server 中的代碼被“續(xù)”到了 master 后面。
圖7.將 `server` 中的修改變基到 `master` 上 ▲
然后就可以快進合并主分支 master 了:
$ git checkout master $ git merge server
至此,client 和 server 分支中的修改都已經(jīng)整合到主分支里了, 你可以刪除這兩個分支,最終提交歷史會變成圖 最終的提交歷史 中的樣子:
$ git branch -d client $ git branch -d server
圖8. 最終的提交歷史 ▲
變基的風險
金科玉律
呃,奇妙的變基也并非完美無缺,要用它得遵守一條準則:
如果提交存在于你的倉庫之外,而別人可能基于這些提交進行開發(fā),那么不要執(zhí)行變基。
如果你遵循這條金科玉律,就不會出差錯。 否則,人民群眾會仇恨你,你的朋友和家人也會嘲笑你,唾棄你。
::: tip
例如:幾個人同時在一個主題分支上進行開發(fā)和提交時,你不要中途執(zhí)行變基,只有在大家都完成工作之后才可以執(zhí)行變基。
:::
變基的實質(zhì)
變基操作的實質(zhì)是丟棄一些現(xiàn)有的提交,然后相應(yīng)地新建一些內(nèi)容一樣但實際上不同的提交。 如果你已經(jīng)將提交推送至某個倉庫,而其他人也已經(jīng)從該倉庫拉取提交并進行了后續(xù)工作,此時,如果你用 git rebase 命令重新整理了提交并再次推送,你的同伴因此將不得不再次將他們手頭的工作與你的提交進行整合,如果接下來你還要拉取并整合他們修改過的提交,事情就會變得一團糟。
讓我們來看一個在公開的倉庫上執(zhí)行變基操作所帶來的問題。 假設(shè)你從一個中央服務(wù)器克隆然后在它的基礎(chǔ)上進行了一些開發(fā)。 你的提交歷史如圖所示:
圖9. 克隆一個倉庫,然后在它的基礎(chǔ)上進行了一些開發(fā) ▲
然后,某人又向中央服務(wù)器提交了一些修改,其中還包括一次合并。 你抓取了這些在遠程分支上的修改,并將其合并到你本地的開發(fā)分支,然后你的提交歷史就會變成這樣:
圖10. 抓取別人的提交,合并到自己的開發(fā)分支 ▲
接下來,這個人又決定把合并操作回滾,改用變基;繼而又用 git push --force 命令覆蓋了服務(wù)器上的提交歷史。 之后你從服務(wù)器抓取更新,會發(fā)現(xiàn)多出來一些新的提交。
圖11. 有人推送了經(jīng)過變基的提交,并丟棄了你的本地開發(fā)所基于的一些提交 ▲
結(jié)果就是你們兩人的處境都十分尷尬。 如果你執(zhí)行 git pull 命令,你將合并來自兩條提交歷史的內(nèi)容,生成一個新的合并提交,最終倉庫會如圖所示:
圖12. 你將相同的內(nèi)容又合并了一次,生成了一個新的提交 ▲
用變基解決變基
如果你 真的 遭遇了類似的處境,Git 還有一些高級魔法可以幫到你。 如果團隊中的某人強制推送并覆蓋了一些你所基于的提交,你需要做的就是檢查你做了哪些修改,以及他們覆蓋了哪些修改。
實際上,Git 除了對整個提交計算 SHA-1 校驗和以外,也對本次提交所引入的修改計算了校驗和——即 “patch-id”。
如果你拉取被覆蓋過的更新并將你手頭的工作基于此進行變基的話,一般情況下 Git 都能成功分辨出哪些是你的修改,并把它們應(yīng)用到新分支上。
舉個例子,如果遇到前面提到的 有人推送了經(jīng)過變基的提交,并丟棄了你的本地開發(fā)所基于的一些提交 那種情境,如果我們不是執(zhí)行合并,而是執(zhí)行 git rebase teamone/master, Git 將會:
檢查哪些提交是我們的分支上獨有的(C2,C3,C4,C6,C7)
檢查其中哪些提交不是合并操作的結(jié)果(C2,C3,C4)
檢查哪些提交在對方覆蓋更新時并沒有被納入目標分支(只有 C2 和 C3,因為 C4 其實就是 C4')
把查到的這些提交應(yīng)用在 teamone/master 上面
從而我們將得到與 你將相同的內(nèi)容又合并了一次,生成了一個新的提交 中不同的結(jié)果,如圖 在一個被變基然后強制推送的分支上再次執(zhí)行變基 所示。
圖13. 在一個被變基然后強制推送的分支上再次執(zhí)行變基 ▲
要想上述方案有效,還需要對方在變基時確保 C4' 和 C4 是幾乎一樣的。 否則變基操作將無法識別,并新建另一個類似 C4 的補?。ǘ@個補丁很可能無法整潔的整合入歷史,因為補丁中的修改已經(jīng)存在于某個地方了)。
在本例中另一種簡單的方法是使用 git pull --rebase 命令而不是直接 git pull。 又或者你可以自己手動完成這個過程,先 git fetch,再 git rebase teamone/master。
如果你習慣使用 git pull ,同時又希望默認使用選項 --rebase,你可以執(zhí)行這條語句 git config --global pull.rebase true 來更改 pull.rebase 的默認配置。
如果你只對不會離開你電腦的提交執(zhí)行變基,那就不會有事。 如果你對已經(jīng)推送過的提交執(zhí)行變基,但別人沒有基于它的提交,那么也不會有事。 如果你對已經(jīng)推送至共用倉庫的提交上執(zhí)行變基命令,并因此丟失了一些別人的開發(fā)所基于的提交, 那你就有大麻煩了,你的同事也會因此鄙視你。
如果你或你的同事在某些情形下決意要這么做,請一定要通知每個人執(zhí)行 git pull --rebase 命令,這樣盡管不能避免傷痛,但能有所緩解。
變基 vs. 合并
至此,你已在實戰(zhàn)中學習了變基和合并的用法,你一定會想問,到底哪種方式更好。 在回答這個問題之前,讓我們退后一步,想討論一下提交歷史到底意味著什么。
有一種觀點認為,倉庫的提交歷史即是 記錄實際發(fā)生過什么。 它是針對歷史的文檔,本身就有價值,不能亂改。 從這個角度看來,改變提交歷史是一種褻瀆,你使用 謊言 掩蓋了實際發(fā)生過的事情。 如果由合并產(chǎn)生的提交歷史是一團糟怎么辦? 既然事實就是如此,那么這些痕跡就應(yīng)該被保留下來,讓后人能夠查閱。
另一種觀點則正好相反,他們認為提交歷史是 項目過程中發(fā)生的事。 沒人會出版一本書的第一版草稿,軟件維護手冊也是需要反復修訂才能方便使用。 持這一觀點的人會使用 rebase 及 filter-branch 等工具來編寫故事,怎么方便后來的讀者就怎么寫。
現(xiàn)在,讓我們回到之前的問題上來,到底合并還是變基好?希望你能明白,這并沒有一個簡單的答案。 Git 是一個非常強大的工具,它允許你對提交歷史做許多事情,但每個團隊、每個項目對此的需求并不相同。 既然你已經(jīng)分別學習了兩者的用法,相信你能夠根據(jù)實際情況作出明智的選擇。
總的原則是,只對尚未推送或分享給別人的本地修改執(zhí)行變基操作清理歷史, 從不對已推送至別處的提交執(zhí)行變基操作,這樣,你才能享受到兩種方式帶來的便利。
Git GitHub 代碼托管 CodeHub 代碼檢查 CodeCheck 彈性云服務(wù)器 ECS
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。