iT邦幫忙

2023 iThome 鐵人賽

DAY 13
0
自我挑戰組

用ChatGPT詠唱來完成工作與點亮前後端技能樹系列 第 13

【Day13】ChatGPT請教教我:Git版控!(上)

  • 分享至 

  • xImage
  •  

Git 是踏入程式開發這塊領域之後,該要認識的一個很重要的工具與系統
也許在找工作時,就可以看到在能力需求的項目中,很常見會提到
「熟悉Git操作」、「悉知Git Flow開發流程」等等字眼
又或者說進入公司、進入一個團隊之後,就會使用到git,主管會要求學習使用git

所以Git到底是什麼呢?到底為什麼如此重要?
作用和目的又是為了解決什麼問題

我們來試著問看看ChatGPT

另外本章節會需要使用到終端機

Git 基本介紹

https://ithelp.ithome.com.tw/upload/images/20230924/20135750yvRii0Q2BC.png

Git 是一個版本控制系統,它被用來追蹤和管理軟體開發過程中的變更。它的作用和目的如下:

  1. 版本控制:Git 允許你追蹤你專案中的所有文件的變更,並保留這些變更的歷史記錄。這使得你可以隨時回溯到先前的版本,並比較不同版本之間的差異。
  2. 協作:Git 使得多個開發者可以在同一個專案上協同工作。每個開發者可以在自己的本地環境中進行修改,然後將這些變更推送到共用的倉庫中。
  3. 分支管理:Git 允許你創建不同的分支,每個分支可以獨立進行開發,這樣可以讓你在不影響主要開發流程的情況下進行實驗、修復錯誤等工作。
  4. 保護代碼品質:通過Git,你可以在合併變更之前進行審查,這有助於確保新增的代碼符合團隊的品質標準。

總的來說,Git 是一個強大的工具,它可以幫助團隊有效地合作、管理代碼並保證代碼的品質。對於前端工程師來說,掌握Git是非常重要的,因為它在軟體開發過程中扮演著關鍵的角色。

講了很多的好處,也出現了很多的關鍵字
像是「版本控制」、「分支管理」、「協作」等等

讓ChatGPT近一步說明使用的情境
https://ithelp.ithome.com.tw/upload/images/20230924/20135750ysT1uywQ2H.png

當然,讓我以一個真實情境來解釋Git的重要性與必要性:

假設你是一名初學的前端工程師,正在參與一個小型團隊開發一個網站專案。你們的專案包括了多個頁面、圖片、樣式表等資源。

在開發的初期階段,每個人都在各自的電腦上進行著不同的工作,例如設計介面、撰寫程式碼等。隨著時間推移,大家在各自的本地環境中進行了許多變更。

這時候,如果沒有Git,可能會出現以下問題:

  1. 版本混亂:因為每個人在各自的電腦上進行了修改,如果沒有一個統一的版本控制系統,很難確定哪個版本是最新的,這可能導致混亂和錯誤。
  2. 無法協作:假如你和另一名團隊成員在相同的文件中進行了修改,但你們並不知道彼此的變更,這可能會導致衝突和遺失重要的變更。
  3. 不容易回溯:如果沒有版本控制,當發現了一個嚴重的錯誤時,很難快速地回溯到先前的穩定版本來修復問題。

這時候,Git的重要性就凸顯出來了:

  1. 版本控制:使用Git,你可以輕鬆地追蹤所有文件的變更,並且可以隨時回溯到先前的版本。
  2. 協作:你可以在自己的本地環境中進行開發,然後通過Git將變更推送到共用的倉庫,這樣其他成員就可以看到你的變更,避免了衝突。
  3. 保護代碼品質:通過Git的分支管理,你可以在進行複雜的修改或實驗時,不影響主要的開發流程,這有助於保證代碼的品質。

總的來說,Git是一個幫助團隊有效合作、管理代碼的重要工具,特別是在多人協作的專案中,它的作用不可忽視。

這讓我直接回想起來,曾經在大學的時候,要和同學分組一起寫程式

一開始我們各自分工,然後再手動把兩份程式碼組合起來
如果是不同的檔案還勉強可處理
如果撰寫的部分是放在同一個檔案內,那就會變成很複雜麻煩的大工程

即使使用了一個類似google文件的工具——HackMD ,可以在網頁上一起編輯一份檔案
但很容易延遲,也會不小心誤動到對方的內容,或是互相覆蓋對方先前修改過的內容

要追加功能或修改程式碼時,
電腦桌面開始貼滿了各種 project-1 、project-0922-2、project-new之類的相似又不同的檔案
要找出這些檔案的不同之處又是另外一個痛點

上述ChatGPT提到如果沒有Git的問題:混亂。
真的再也貼切不過了,就是混亂。亂成一團。

也許不是每個人都跟我一樣幹過這麼白癡的事情
但顯然的,沒有一個工具來協助,要進行團隊合作開發是個非常困難而且容易吵架的事情

上面也只講述了可以改善這類的問題,但還沒有講述要怎麼使用Git
Git到底是使用了什麼樣的方式或概念,可以促使團隊協作呢
https://ithelp.ithome.com.tw/upload/images/20230924/20135750QU6s1aZaUq.png

當然,我會提供一個簡單易懂的Git教學,以及相關的概念、安裝與使用方法。

Git 的基本概念:

1. 倉庫(Repository):

Git 中的倉庫是你的專案所在的目錄,它包含了所有的文件以及相關的版本控制資訊。

2. 提交(Commit):

提交代表了一個版本的快照,它包含了你在專案中所做的一系列變更。

3. 分支(Branch):

分支是基於某個特定提交的一個獨立開發線,可以在不影響主要開發線的情況下進行實驗、開發新功能等。

4. 推送(Push):

當你完成了一些工作,想要將這些變更分享給其他團隊成員時,你可以將它們推送到共用的倉庫中。

5. 拉取(Pull):

當其他團隊成員推送了新的變更,你可以通過拉取(pull)來更新你的本地倉庫,以保持最新的狀態。

Git 的安裝與使用教學:

1. 安裝 Git:

請參考Git 官方網站下載與安裝適用於你的作業系統的 Git 版本。

2. 創建倉庫:

在你的專案目錄中,開啟終端機並執行以下指令以初始化一個 Git 倉庫:

git init

3. 新增與提交變更:

在你對專案做了一些變更後,可以使用以下指令將這些變更提交到本地倉庫:

git add .  # 將所有變更添加到暫存區
git commit -m "提交訊息"  # 提交變更,訊息描述你的變更內容

4. 創建分支:

如果你想要在一個獨立的分支中進行開發,可以使用以下指令:

git branch 新分支名稱  # 創建新分支
git checkout 新分支名稱  # 切換到新分支

5. 推送與拉取:

當你完成了一些工作並準備與團隊分享時,可以使用以下指令:

git push origin 分支名稱  # 推送變更到遠端倉庫

當其他成員推送了變更,你可以使用以下指令來拉取最新的變更:

git pull origin 分支名稱  # 拉取最新變更

這是一個簡單的 Git 使用教學,希望能幫助你開始使用Git進行版本控制和團隊合作。如果你需要更進一步的說明或範例,請隨時告訴我!

上述提供了一個基礎設定、如何起始的教學
提到了不少新名詞

我覺得ChatGPT蠻貼心的是,雖然是請他以中文回覆
但遇到專有名詞的時候,仍然有附上英文的原文單字,方便拿這些關鍵字去深入了解
也避免再找尋文獻或資料時,不知道名詞與原本單字的對應

上面提到了「倉庫」,請他針對倉庫是什麼來做說明

Git 倉庫(Repository)

https://ithelp.ithome.com.tw/upload/images/20230924/20135750qNWwderO7A.png

當然,我來針對倉庫進一步解釋,並搭配圖片說明。

Git 倉庫(Repository)的深入解釋:

Git 倉庫是一個非常重要的概念,它是儲存你專案所有版本資訊的地方。可以將它想像成一個保存所有專案變更歷史的數據庫。

1. 本地倉庫(Local Repository):

本地倉庫位於你的本地電腦上。當你在專案目錄中執行 git init 指令後,這個目錄就成為了一個本地倉庫。本地倉庫包含了以下三個重要的區域:

  • 工作目錄(Working Directory):這是你正在工作的實際目錄,它包含了所有的專案文件。
  • 暫存區(Staging Area):也被稱為索引(Index),這是一個暫存變更的地方,在你確定要提交這些變更之前,你可以在這裡對它們進行檢查和編輯。
  • 本地庫(Local Repository):這是包含所有提交歷史的地方,每次你進行提交(commit)時,都會在這裡保存一個新的版本。

2. 遠端倉庫(Remote Repository):

遠端倉庫是位於遠程伺服器上的儲存庫,它可以在團隊成員之間共享。通過推送(push)和拉取(pull)操作,你可以將本地倉庫的變更同步到遠端倉庫中,以及從遠端倉庫中取得最新的變更。

圖示說明:

下面是一個示意圖,說明了本地倉庫和遠端倉庫之間的關係:

  +----------------------+       +----------------------+
  |   工作目錄 (Working   |       |   遠端倉庫 (Remote     |
  |    Directory)        | <===> |    Repository)       |
  |                      |       |                      |
  +----------------------+       +----------------------+
             |                                  ^
             |                                  |
             v                                  |
  +----------------------+       +----------------------+
  |   暫存區 (Staging     |       |                      |
  |       Area)          |       |   本地倉庫 (Local     |
  |                      |       |   Repository)        |
  +----------------------+       |                      |
                                 +----------------------+

這張圖顯示了工作目錄、暫存區和本地倉庫之間的關係,以及本地倉庫和遠端倉庫之間的連接。

  • 工作目錄包含你正在工作的實際文件。
  • 暫存區是一個中介區域,用於準備提交的變更。
  • 本地倉庫保存了所有的提交歷史。
  • 遠端倉庫位於遠程伺服器上,可以供多個團隊成員共享。

這種組織方式使得團隊成員可以有效地協作、追蹤變更,並保留所有版本的歷史記錄。希望這個圖示能幫助你更好地理解Git倉庫的概念。

好的XD 他的「產圖」能力還有待加強,看了示意圖後反而不明所以
希望他變出能夠更助於理解的示意圖,還有點困難

但他又提到了一個新的關鍵字:遠端倉庫
https://ithelp.ithome.com.tw/upload/images/20230924/20135750OwdaB4r90b.png

遠端倉庫(Remote Repository)是位於遠程伺服器上的一個儲存庫,它用於保存專案的版本控制資訊,並提供了團隊成員之間共享專案的平台。

遠端倉庫的作用如下:

  1. 共享和備份:遠端倉庫允許多個開發者將他們的工作同步到同一個中央位置。這樣可以保證所有的開發者都在使用相同的基礎代碼,並且可以作為一個備份的地方。
  2. 協作:開發者可以通過推送(push)和拉取(pull)操作來分享彼此的變更。這使得團隊成員可以在專案中有效地協作。
  3. 版本控制:遠端倉庫保存了所有的提交歷史,這使得你可以隨時回溯到先前的版本。
  4. 持續集成(CI)和部署(CD):許多CI/CD系統(例如Jenkins、Travis CI等)可以直接與遠端倉庫整合,使得自動化測試、建置和部署變得更容易。

遠端倉庫通常被託管在網路上的 Git 服務提供商(例如GitHub、GitLab、Bitbucket等)上。這些平台提供了一個方便的方式來創建、管理和分享你的遠端倉庫。

總的來說,遠端倉庫是一個重要的概念,它為團隊合作和版本控制提供了便捷的解決方案,特別是在多人協作的專案中。

所以,我們常常聽到的GitHub、GitLab,或是Bitbucket,他們都是一個「平台」

一開始可能會搞混 Git 和GitHub
Git是一個軟體,而GitHub 只是其中一種遠端倉庫

了解倉庫之後,來認識另一個關鍵字:分支(Branch)

分支(Branch)

https://ithelp.ithome.com.tw/upload/images/20230924/20135750EQY6PGXRsV.png

好的,我來解釋分支的概念和作用,並搭配圖片說明。

分支(Branch)的概念與作用:

在Git中,分支是一個非常重要的概念,它允許開發者在不影響主要開發流程的情況下,獨立進行開發、實驗新功能或修復問題。

概念:

  • 主分支(Main Branch):通常稱為master分支,它是一個專案的主要開發線,包含了穩定的代碼。
  • 分支(Branch):分支是基於某個特定提交(commit)的一個獨立開發線。你可以在分支上進行編輯、新增功能或修復錯誤,而不會影響主分支。
  • 合併(Merge):當一個分支的工作完成且測試通過,你可以將它合併回主分支,這樣主分支就包含了新的變更。

作用:

  • 同時進行多個任務:你可以同時在不同的分支上進行不同的任務,例如開發新功能、修復問題等,而不會相互干擾。
  • 實驗和測試:你可以在一個獨立的分支上進行實驗,嘗試新的想法,而不必擔心影響到主要開發流程。
  • 版本控制:每個分支都包含了一個特定的版本歷史,這使得你可以隨時回溯到先前的狀態。

圖示說明:

以下是一個示意圖,說明了分支的概念:

   +------------------------+   +------------------------+
   |   主分支 (master)       |   |   新功能分支 (feature)   |
   |                        |   |                        |
   |   Commit 1             |   |   Commit 1             |
   |   Commit 2             |   |   Commit 2             |
   |   Commit 3             |   |   Commit 3             |
   +------------------------+   |   Commit 4             |
                                +------------------------+

這張圖示了一個主分支和一個新功能分支。主分支包含了三個提交(Commit 1、Commit 2、Commit 3),而新功能分支在此基礎上進行了額外的開發(Commit 4)。這樣,主分支和新功能分支的工作是獨立的,互不影響。

總的來說,分支是一個強大的工具,它允許你在專案開發過程中保持組織、靈活性和版本控制。特別是在多人協作的專案中,合理使用分支可以提高開發效率和代碼品質。

仍然嘗試讓他用文字來繪製示意圖
大概可以感覺到(?)不同分支的檔案內容可以獨立開來
後續再藉由「合併分支」這個動作將所有的內容整併

因此我們來繼續追問有關合併分支的問題

合併分支 (Merge

https://ithelp.ithome.com.tw/upload/images/20230924/201357507zmF4t39d4.png

將分支的變更合併回主分支是一個常見的操作,它可以保證新功能或修復的變更被整合到主要的開發流程中。下面我會提供一個實際情境的範例來說明如何進行合併,並附上相關的程式碼示範。

實際情境說明:

假設你正在開發一個簡單的網頁應用程式,目前有一個主分支(master)用於保存穩定的代碼。你需要新增一個功能,讓使用者可以點擊按鈕後顯示一個提示訊息。

步驟:

  1. 創建新功能分支

    首先,在你的專案目錄中使用以下指令創建一個新的分支,並切換到這個分支:

    git branch feature-button
    git checkout feature-button
    
    

    這樣你就創建了一個名為 feature-button 的新分支,用於開發這個新功能。

  2. 開發新功能

    feature-button 分支上進行開發,新增一個按鈕,並添加顯示提示訊息的功能。以下是一個簡單的HTML和JavaScript範例:

    <!-- index.html -->
    <button id="showMessage">顯示訊息</button>
    <div id="message"></div>
    
    <script>
      document.getElementById('showMessage').addEventListener('click', function() {
        document.getElementById('message').textContent = '這是一個提示訊息';
      });
    </script>
    
    
  3. 提交變更

    將你的變更提交到 feature-button 分支:

    git add .
    git commit -m "新增按鈕功能和提示訊息"
    
    
  4. 切換回主分支

    在開發完成後,切換回主分支:

    git checkout master
    
    
  5. 合併分支

    接下來,將 feature-button 分支的變更合併回主分支:

    git merge feature-button
    
    

    這個指令將會把 feature-button 分支上的變更合併到 master 分支。

  6. 解決衝突(如果有的話)

    如果在合併的過程中發生了衝突,需要解決這些衝突。這通常涉及到手動編輯檔案以保留想要的變更。

  7. 提交合併

    解決完衝突後,使用以下指令進行提交:

    git commit -m "合併 feature-button 分支"
    
    

示範程式碼範例:

這是一個簡單的示範程式碼範例,用於在點擊按鈕時顯示提示訊息:

<!-- index.html -->
<button id="showMessage">顯示訊息</button>
<div id="message"></div>

<script>
  document.getElementById('showMessage').addEventListener('click', function() {
    document.getElementById('message').textContent = '這是一個提示訊息';
  });
</script>

這段程式碼包含了一個按鈕和一個空的 <div> 元素,當按鈕被點擊時,它會將提示訊息顯示在 <div> 中。

以上步驟和範例程式碼示範了如何將分支的變更合併回主分支。這樣你就可以保證新功能或修復的變更被整合到主要的開發流程中。如果有任何疑問或需要進一步說明,請隨時告訴我!

也就是說,只要沒有發生「合併衝突」
就可以順順地照著步驟並倚賴 git commit -m 這個指令來將程式碼的更變做整合

那麼「合併衝突」又是什麼呢

合併衝突

https://ithelp.ithome.com.tw/upload/images/20230924/20135750YVxsQBWsYU.png

合併衝突發生在兩個不同分支中的相同部分有了不一致的變更,這時Git無法自動確定應該保留哪個版本的變更。這是一個常見的情況,通常發生在以下情況下:

  1. 兩個分支都修改了同一個檔案的同一個部分:例如,在主分支和功能分支上都修改了相同的函數或代碼段。
  2. 其中一個分支刪除了檔案,而另一個分支修改了該檔案:這種情況下,Git不知道應該保留哪一個版本。
  3. 合併分支和目標分支在某個提交之後有不同的歷史:當兩個分支的歷史分歧,Git需要用戶來解決這個問題。

示例情境:

在我之前的例子中,假設你在 feature-button 分支上修改了一個檔案,並且在主分支上也對同一個檔案進行了修改。這可能會導致合併衝突。

讓我們假設在 feature-button 分支上的程式碼如下(修改了 index.html 文件):

<!-- feature-button 分支的 index.html -->
<button id="showMessage">顯示訊息</button>
<div id="message">這是新功能分支的內容</div>

而在 master 分支上的程式碼如下(也修改了 index.html 文件):

<!-- master 分支的 index.html -->
<button id="showMessage">顯示訊息</button>
<div id="message">這是主分支的內容</div>

這兩個分支修改了同一個檔案的相同部分,而且內容不一致。當你嘗試將 feature-button 分支合併到 master 分支時,Git 會檢測到衝突,並停止合併。

解決衝突:

要解決合併衝突,你需要手動編輯檔案,以選擇要保留的變更。在我們的情境中,你可以按照以下步驟解決衝突:

  1. 打開 index.html 檔案。

  2. 你會看到Git在衝突的部分添加了特殊標記,類似於這樣:

    <<<<<<< HEAD
    <div id="message">這是主分支的內容</div>
    =======
    <div id="message">這是新功能分支的內容</div>
    >>>>>>> feature-button
    
    
    • <<<<<<< HEAD======= 之間的部分是 master 分支的內容。
    • =======>>>>>>> feature-button 之間的部分是 feature-button 分支的內容。
  3. 現在你需要選擇要保留的內容。例如,你可以選擇保留 feature-button 分支的內容,或者保留 master 分支的內容。如果需要,你也可以手動編輯,創建一個新的內容。

  4. 一旦你確定了要保留的內容,刪除特殊標記和不需要的部分,使檔案看起來正確無誤。

  5. 儲存檔案。

  6. 使用以下指令進行提交,以解決合併衝突:

    git add index.html  # 將解決衝突的檔案標記為已解決
    git commit -m "解決合併衝突"
    
    

這樣,你就成功解決了合併衝突並完成了合併。現在,master 分支包含了兩個分支的變更,並且衝突已經得到解決。

總的來說,合併衝突是當兩個分支的變更不一致時的常見情況,需要手動解決。這個過程中,你需要選擇要保留的變更,並確保檔案的內容正確。

接下來順便介紹一個有可能會使用到的功能
既然可以提交(Commit),那麼就有機會需要「反悔」

反悔提交 resetrevert

https://ithelp.ithome.com.tw/upload/images/20230924/20135750fdkumbsLkO.png

如果你需要反悔已經提交(commit)的變更,可以使用 git resetgit revert 來實現。這兩者的主要區別在於:

  • git reset 會將 HEAD 移動到特定的提交,並取消之後的提交歷史。
  • git revert 創建一個新的提交,以取消之前的提交,但保留之前的歷史記錄。

以下是使用這兩者的方法:

使用 git reset

如果你希望完全取消一個或多個提交,可以使用 git reset

# 使用 git log 找到你想要反悔的提交的 commit hash
git log

# 將 HEAD 移動到你想要回退的提交之前
git reset <commit hash>

# 將這些變更保留在工作目錄,但未被提交
git add .

請注意,git reset 可能會導致丟失部分提交的歷史記錄,請小心使用。

使用 git revert

如果你想要保留之前的提交歷史記錄,並創建一個新的提交來取消之前的提交,可以使用 git revert

# 使用 git log 找到你想要反悔的提交的 commit hash
git log

# 創建一個新的提交來取消之前的提交
git revert <commit hash>

這樣,Git 會創建一個新的提交,包含了取消之前提交的變更。

請注意,使用 git revert 可以保留所有提交的歷史記錄,但會創建新的提交來取消之前的提交。

總的來說,git resetgit revert 提供了不同的方式來反悔提交,你可以根據自己的需求選擇適合的方法。並且,在執行任何反悔操作之前,請確保你理解這些指令的影響,並備份重要的變更以防萬一。

上述學了這麼多指令
但是輸入指令來操作,那入門門檻還是高了那麼一些…些些啊

所以來詢問有沒有比較簡單的方式
https://ithelp.ithome.com.tw/upload/images/20230924/20135750ySEWeTLG1X.png

Git 的操作可以有一些複雜性,但有一些工具和方式可以讓你更容易地進行 Git 操作,特別是對於初學者來說。以下是一些能夠讓 Git 更容易操作的方式:

  1. 使用圖形用戶界面(GUI)工具

    Git 提供了許多圖形用戶界面(GUI)工具,這些工具可以幫助你在不使用命令行的情況下進行 Git 操作。一些受歡迎的 Git GUI 工具包括 GitHub Desktop、SourceTree 和 GitKraken。這些工具通常提供直觀的界面,使得提交、推送、拉取等操作變得更容易。

  2. 使用Git指令行工具的簡化版本

    有一些Git指令行工具,如Oh My Zsh(用於Zsh shell)和Oh My Git,它們可以簡化並美化Git命令,並提供更多的提示和信息,使得操作更容易理解和執行。

  3. 學習Git的基本操作

    學習Git的基本操作是最重要的,這包括 git clone(複製遠端倉庫)、git add(將變更添加到暫存區)、git commit(提交變更)、git push(推送到遠端倉庫)和git pull(拉取最新變更)等基本指令。瞭解這些基本操作將幫助你在Git中更自在地移動。

  4. 參考Git文件和教程

    Git 的官方文件和許多線上教程提供了詳細的指導和示範。你可以參考這些資源,以理解Git的運作方式並學習如何解決常見的問題。

  5. 練習和實際應用

    最好的學習方式是實際應用。建立自己的Git倉庫,將其用於項目,並不斷練習Git操作。透過實際的經驗,你將更容易理解和應用Git。

無論你選擇哪種方式,Git 學習需要時間和實踐。隨著經驗的積累,你將變得更加熟練,能夠更輕鬆地處理Git操作。

第一點提到的圖形化介面真的是讓入門難度降低了許多
操作以及檢視歷史Commit都相當的直覺

不過SourceTree偶爾在一些初次Clone專案的時候
會卡在一個要輸入yes或no的地方,然後SourceTree就會整個卡住
變成沒有學一點點點基本指令,仍然是會碰到問題

結語

這個章節我個人覺得讓ChatGPT來介紹有一點勉強
雖然說若要請ChatGPT提供做法或是指令、範例都算是能得到不錯的結果

但如果希望他搭配圖示說明,就顯得有些難度
解說的圖示又不像是那些撰寫部落格的配圖,可以直接請他去 imgur.com 或是 Unsplash找圖
初次學習來說,若能搭配說明圖可能會更好理解
也不用閱讀那麼多的文字

git版本控制也是一門很深的學問
初學的時候只要掌握基本語法就能應付大多情況的使用
但若要精深,也可以非常的精深

有關Git Hub 的使用與 Git Flow的介紹留到下一篇

塞一篇實在是太長啦

我是學了版控才已知用火的前端工程師一宵三筵,我們明天見!


上一篇
【Day12】ChatGPT請教教我:Command Line - 基礎CMD指令、Terminal指令
下一篇
【Day14】ChatGPT請教教我:GitHub!Git Flow!團隊協作!(下)
系列文
用ChatGPT詠唱來完成工作與點亮前後端技能樹56
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言