1 · W02 版本控制

W02 版本控制

w02-01-cover.png
  • 存檔、同步、紀錄版本
  • 這是一個讓我們安心,也讓我們合作的工具
2 · 再次確認:你有分組嗎?

再次確認:你有分組嗎?

打開 Gitea,你應該看到兩個版本庫:

w02-02-repos.png
  • notes:全班共用
  • 你們組的版本庫

只看到 notes 的舉手。

版本庫(repository),簡稱 repo:放一個專案所有檔案和歷史的地方。

3 · 投影片在哪裡

投影片在哪裡

w02-03-slides-qr.png

shu-dma-mult285.pages.dev 每週的投影片都會公開,課後可以回來看。

4 · 心態調整

心態調整

w02-04-mistake.png

上週大家已經體驗到了一些挫折

  • 沒有不會出錯的系統
  • 不管是寫程式還是工作流程,很少一次就對
4b · 重要的是這三件事

重要的是這三件事

w02-04b-three.png
  • 及早發現
  • 找到原因
  • 解決它

卡住了不要自己悶著,勇敢問。

5 · 從需求出發:一個專案裡有什麼

從需求出發:一個專案裡有什麼

一個複雜的專案會包含:

w02-05-files.png
  • 很多不同類型的檔案:程式、圖、音效、模型、文件
  • 很多決策:為什麼這樣做、後來為什麼改
  • 很多人:每個人同時在改不同的地方
  • 很多版本:昨天的、上週能動的、要交出去的那一版
5b · 所以團隊需要三件事

所以團隊需要三件事

w02-05b-needs.png
  • 資料要存得住
  • 組員都拿得到檔案
  • 大家都知道哪一份才是對的

第三件最常出事:檔案都在,但沒人確定該用哪一個。

6 · 平常我們怎麼做

平常我們怎麼做

w02-06-scatter.png
  • 開一個資料夾,然後越開越多
  • 資料散在每個人的電腦裡
  • 各種好用的網路工具:
    • 發想:Canva
    • 文字:Google Docs/HackMD
    • 資料:Google Sheets
6b · 每種內容,各自的軟體

每種內容,各自的軟體

每種內容有自己的製作軟體,各自輸出檔案:

w02-06b-tools.png
  • 畫圖:Photoshop、Krita
  • 建模:Blender
  • 音效:Audacity
  • 程式:VS Code

輸出的檔案最後都要回到同一個專案裡。 工具都很好,但東西會散在各處。

7 · 一個遊戲專案裡有什麼

一個遊戲專案裡有什麼

  • 程式碼
  • 各式各樣的素材(assets):圖、音效、模型、動畫
  • 團隊的工作紀錄
  • 團隊決定好的事
w02-07-gameproj.png

最後一項最容易消失:「那時候說好的是哪個版本?」

8 · 單一事實來源(Source of Truth)

單一事實來源(Source of Truth)

一個專案資料夾,就是全組唯一的正本。

w02-08-sot.png
  • 一個大家可以一起工作的地方
  • 正確性優先
  • 不用那麼即時

需要即時討論?用通訊軟體就好。

9 · 還需要:記錄每一次改變

還需要:記錄每一次改變

w02-09-ledger.png

在發想和製作的過程中:

  • 記下我們做過的所有改變
  • 隨時都能恢復
  • 隨時都能回到某個版本
10 · 這就是版本控制

這就是版本控制

w02-10-vcs.png

版本控制能幫我們:

  1. 儲存空間:一個全組都拿得到的地方
  2. 記錄變化:誰、什麼時候、改了什麼、為什麼
11 · 為什麼需要版本控制

為什麼需要版本控制

你一定遇過:

w02-11-pain.png
  • 改壞了想回到昨天的版本 → 回不去
  • 兩個人改同一個檔案 → 一個人的工作不見了
  • 「這段是誰做的、為什麼這樣做」→ 沒人記得

版本控制解決這三件事。而且它可以當作個人貢獻的評分依據。

12 · Gitea 是什麼?GitHub 是什麼?

Gitea 是什麼?GitHub 是什麼?

是什麼 網址
Git 版本控制的本體 git-scm.com
GitHub 放 Git 專案的網站,全世界最多人用 github.com
Gitea 同樣的東西,自己架的版本,只有修課的人看得到 anxiously-unrecipient-aurora.ngrok-free.dev
w02-12-servers.png

GitHub 上還有非常多好用的工具和開源專案。 善用工具,不要只局限於老師教的幾種。

13 · 像蓋房子:一層一層往上

像蓋房子:一層一層往上

  • 每做完一件事,就往上蓋一層
  • 新的一層蓋在上一層的基礎上,不是憑空出現
  • 每一層都有自己的編號(ID),指名道姓找得到
  • Git 記的是每一層跟上一層的差異:這層改了什麼
  • 所以想看以前的樣子,往下數幾層就回得去
w02-13-house.png

打開 Gitea 看看你們自己蓋的房子。

13b · 上週的衝突,是正常的

上週的衝突,是正常的

上週大家在網頁上簽到時,撞到了 Git 的衝突。

w02-13b-mismatch.png
  • 兩個人從同一層往上蓋
  • 各蓋各的,變成兩棟不一樣的房子
  • 要合起來,得先決定:上面那層照誰的做

衝突不是錯誤,是 Git 在問你。

14 · 提交(commit)是什麼

提交(commit)是什麼

一次提交=一個存檔點。 每個提交都帶著:

w02-14-commit.png
  • 日期
  • ID(一串亂碼,每個提交獨一無二)
  • 作者
  • 說明(comment)

上週在網頁上簽到,就是一次線上提交。

15 · 提交會疊成一棵樹

提交會疊成一棵樹

  • 每次提交都接在上一次後面
  • 目前大家的提交都蓋在主線上,叫主分支(main)
w02-15-stack.png
●─●─●─●  main
16 · 分支:多元宇宙

分支:多元宇宙

Git 可以開分支。

w02-16-multiverse.png
  • 就像多元宇宙:每條分支是一個不同的現實
  • 我們一次只能體驗一個現實
  • 所以每個宇宙都要有名字,才能在宇宙之間穿越
16b · 分支長什麼樣

分支長什麼樣

w02-16b-twigs.png
        ●─●  feature
       /
●─●─●─●─●  main

從某一層岔出去往上蓋,就是一條新的分支。

17 · 分支其實是一個標籤

分支其實是一個標籤

  • 分支=一個標籤,指著某根樹枝的末端
  • 在樹枝之間跳來跳去叫 checkout
  • 跳過去,你看到的檔案就會變成那根樹枝上的樣子
w02-17-tag.png

在 Gitea 的分支選單裡,打勾的那個就是你現在站的分支。

18 · 雲端與本地端

雲端與本地端

到這裡為止,我們看的都是 Gitea 上的東西——那是雲端。

w02-18-cloudlocal.png
  • 雲端(remote):Gitea 上的那一份,全組共用
  • 本地端(local):你電腦裡的那一份

接下來這半堂課,全部都在講本地端。

18b · 為什麼要下載到自己電腦

為什麼要下載到自己電腦

w02-18b-software.png
  • 網頁只適合改幾行字
  • 真正要新增、修改內容,得在自己電腦上做
  • 各種素材有各自的專業軟體(Photoshop、Blender、Godot…)
19 · 雲端和本地端的關係

雲端和本地端的關係

  • 雲端有一棵樹,本地端也有一棵樹
  • 版本控制做的事:讓兩棵樹同步
w02-19-sync.png
雲端  ●─●─●
       ⇅  同步
本地  ●─●─●
20 · 需要軟體來幫忙

需要軟體來幫忙

w02-20-cliVsGui.png
  • Git 原本是用命令列操作
  • 能做的事很多,但有點複雜
  • 所以我們用圖形介面軟體來幫忙
21 · 本地端的版本控制軟體:Fork

本地端的版本控制軟體:Fork

w02-21-gui.png
  • 下載:https://git-fork.com/
  • 用滑鼠就能看歷史、提交、同步
  • 它做的每件事,底下都是 Git 指令
22 · 設定帳號

設定帳號

Fork → File → Preferences → Git:

w02-22-idcard.png
  • User Name=學號
  • Email=學號@mail.shu.edu.tw

要跟 Gitea 帳號一樣,貢獻才算得到你頭上。

23 · 把專案複製到本地端:Clone

把專案複製到本地端:Clone

w02-23-clone.png

Clone:把雲端的整棵樹複製到本地端。

  1. 在 Gitea 的 repo 頁複製網址
  2. Fork → File → Clone,貼上網址
  3. 選一個放專案的資料夾
24 · HEAD:你現在站在哪裡

HEAD:你現在站在哪裡

w02-24-head.png
  • HEAD=你現在所在的位置
  • 資料夾裡看到的檔案,就是 HEAD 指著的那個版本
25 · 在本地端編輯檔案

在本地端編輯檔案

用你習慣的編輯器打開專案資料夾:

w02-25-editor.png
  • VS Code
  • Obsidian

改完存檔,回到 Fork,會看到哪些檔案變了。

26 · 從本地端提交:兩個步驟

從本地端提交:兩個步驟

  1. Stage(暫存):挑出這次要提交哪些改動
  2. Commit(提交):寫說明,存成一個存檔點
w02-26-stage.png
改檔案  ⇄  Stage  →  Commit
   ↓      Unstage
Discard(這次改壞了,不要了)
26b · 反悔的兩種按法

反悔的兩種按法

  • Unstage:這個檔案這次不要一起提交,放回去就好,內容不會變
  • Discard:把還沒提交的修改丟掉,檔案回到上一個提交的樣子
w02-26b-undo.png

⚠️ Discard 丟掉就回不來,因為它還沒被記錄過。Unstage 則完全無害。

27 · 提交之後發生什麼

提交之後發生什麼

w02-27-grew.png
  • 樹枝往上長一節
  • HEAD 跟著移動到最新的提交
  • ⚠️ 這時候提交還在你的電腦裡,雲端還沒有
28 · 提交的注意事項

提交的注意事項

  • 一次提交只做一件事
  • 說明不要亂寫:用一句話講這次做了什麼,動詞開頭
w02-28-labels.png
好的 壞的
新增組員名單 ❌ update
修正敵人卡在斜坡的問題 ❌ 修正bug
調整第一關的難度 ❌ asdf
29 · 實作(一):第一個提交

實作(一):第一個提交

老師已經在每組的 repo 放了 README.md。 每組派一位同學:

w02-29-clipboard.png
  1. 在 README.md 寫上組員名單
  2. Stage → Commit
  3. 做到這裡就停,其他按鈕先不要碰
30 · 實作(二):第二個提交

實作(二):第二個提交

每組第二位同學:

w02-30-clipboard2.png
  1. 在 README.md 填上平台(例如 PC、手機、網頁)
  2. Stage → Commit
  3. 一樣做完就停

現在兩個人的電腦裡各有一個新提交,Gitea 上還是舊的。

31 · Push:同步到雲端

Push:同步到雲端

Push:把剛剛的提交送到雲端。

w02-31-push.png
  • 雲端的樹也往上長一節
  • Fork 裡是同一棵樹、兩個標籤:
    • main = 你本地端的位置
    • origin/main = 雲端的位置
  • push 前兩個標籤不在同一層;push 後疊在一起

第一位同學先 push。 到 Gitea 重新整理,看到了嗎?

32 · 本地端與雲端的衝突

本地端與雲端的衝突

w02-32-mismatch.png

第二位同學 push → 出現警告。 恭喜,這是第二次衝突(第一次在上週)! 這次撞的不是同一行文字,是你的樹和雲端的樹對不起來。

32b · 為什麼會這樣

為什麼會這樣

  • 兩位同學改的是不同地方,commit 都成功
  • 但第一位已經 push 了,origin/main 這個標籤往前移過了
  • 你的提交接在舊的那一層上,接不回現在的 origin/main
w02-32b-offset.png

看 Fork 的提交樹:main 和 origin/main 不但不在同一層,還岔開成兩邊。

33 · 衝突長什麼樣

衝突長什麼樣

w02-33-fork.png
        ●  ← main(你的提交,只在本地)
       /
●─●─●─●  ← origin/main(雲端,多了組員的提交)

兩個標籤各自往上長,樹岔開了。要想辦法把它們接回同一條。

34 · 解決衝突:先看是什麼檔案

解決衝突:先看是什麼檔案

  • 文字檔:有機會自動合併;改到同一行就手動決定留哪個
  • 二進位檔(圖片、模型、場景):沒辦法合併,只能二選一
w02-34-filetypes.png

所以:素材和場景一個人負責一個,不要兩個人同時改。

34b · 動手之前:先 Fetch

動手之前:先 Fetch

Fetch = 去雲端問一下:你那邊現在長怎樣?

w02-34b-fetch.png
  • 只是把雲端的最新狀態抓下來,不會動到你的檔案
  • 抓完 origin/main 這個標籤才會移到正確的位置
  • 看得到真正的分叉,才選得出要用哪個方法

沒 fetch 之前,你看到的雲端是舊的。

35 · 方法一:不要了(Reset --hard)

方法一:不要了(Reset --hard)

你手邊改的東西(已提交)不重要、或本來就想重做:

w02-35-discard.png
  • 直接丟掉自己的提交與修改
  • 把雲端那份原封不動拉下來
  • 從乾淨的狀態重新開始

⚠️ 丟掉就回不來了。 只有在「這些改動我不要」時才用。

35b · Reset --hard 在 Fork 裡怎麼按

Reset --hard 在 Fork 裡怎麼按

w02-35b-menu.png
  1. 先 Fetch,讓 origin/main 是最新的
  2. 在提交樹上找到 origin/main 那一層
  3. 右鍵 → Reset 'main' to Here
  4. 模式選 Hard
36 · 方法二:Rebase(接枝)

方法二:Rebase(接枝)

改的東西要留著:

w02-36-graft.png
  • 像花藝的接枝:把你的提交剪下來,接到雲端最新那一層上面
  • 樹會保持一直線,比較好讀
●─●─●─●─●  你的提交接到最新的後面
36b · Rebase 在 Fork 裡怎麼按

Rebase 在 Fork 裡怎麼按

  1. 先 Fetch
  2. 確認你站在 main(左邊清單粗體的那個)
  3. 在 origin/main 上按右鍵 → Rebase 'main' onto origin/main
  4. 有衝突 → Fork 跳出合併工具,解完按 Continue
w02-36b-menu.png

做完:main 接到 origin/main 上面,樹變成一直線,可以 push 了。

37 · 方法三:Merge(合併)

方法三:Merge(合併)

w02-37-merge.png
  • 把兩根樹枝合在一起,多一個「合併提交」
  • 改到不同地方:自動合好
  • 改到同一行:Git 標出來問你
37a · 改到同一行,Git 會問你

改到同一行,Git 會問你

<<<<<<< HEAD
你的版本
=======
組員的版本
>>>>>>>

決定留哪個(或兩個都留)→ 刪掉標記 → commit → push

w02-37a-sameline.png
37b · Merge 在 Fork 裡怎麼按

Merge 在 Fork 裡怎麼按

w02-37b-menu.png

先站到要保留的那個分支上,再把另一邊的改動合進來。

  • 你現在在 main → 對 origin/main 按右鍵 → Merge into main
  • 合進來的是改動,不是整棵樹搬家
37c · 方法四:取消重來(Reset,改動留著)

方法四:取消重來(Reset,改動留著)

w02-37c-tray.png
  • 用 Reset 撤銷自己的提交,但改動還留在檔案裡
  • 先把雲端最新的拉下來
  • 重新 commit,再 push

改動不多的時候,這個最簡單。

38 · 接下來:討論你們的專案

接下來:討論你們的專案

w02-38-ideas.png

每組開始討論這學期想做什麼遊戲:

  • 寫進 README.md,老師有提供模板
  • 每個人用自己的帳號登入
  • 試著編輯 README.md 的不同段落,各自 commit、push
39 · 簽到

簽到

w02-39-signin.png

今天沒有提交和 push 過的人:

  • 在 docs/attendance/w02.md 簽名,commit、push
40 · 下週預告

下週預告

w02-40-calendar.png

W03 · 9/30 · AI 輔助開發

  • 今天的 repo 下週繼續用
41 · 分支

分支

前面都在 main 上一起做。分支是「另外開一條路」。

w02-41-tree.png
  • 想試一個做法,又不想弄壞現在能動的版本
  • 兩個人要改同一個東西,先各走各的,之後再合

分支很便宜:開一條、丟掉一條,都只是動一個標籤。

42 · 開一條分支(Create Branch)

開一條分支(Create Branch)

在 Fork 裡:

w02-42-branch.png
  1. 在提交樹上,找到要從哪一層岔出去(通常是 main 的最上面)
  2. 右鍵 → Create Branch…
  3. 取個名字,例如 try-jump
  4. 勾「Check out after create」=開完直接站過去

開完只是多一個標籤,檔案不會變。

43 · 站過去(Checkout)

站過去(Checkout)

Checkout = 換一條路站。

w02-43-checkout.png
  • 左邊清單雙擊那個分支名,就站過去了
  • 檔案跟著變成那條路上的樣子
  • 粗體的那個就是你現在站的分支

⚠️ 站過去之前,手邊的修改先 commit 或 discard,不然會擋著。

44 · 丟掉一條分支(Delete Branch)

丟掉一條分支(Delete Branch)

這條路試完了、或不要了:

w02-44-delete.png
  1. 先站到別條分支(不能站在自己身上刪自己)
  2. 在要刪的分支上右鍵 → Delete…
  • 刪的是標籤,提交還在,只是沒有名字指著它了
  • 雲端那條要另外刪(Fork 會問要不要一起刪遠端)
45 · 分支要不要用在這門課

分支要不要用在這門課

w02-45-simple.png
  • 今天開始:全組在 main 上一起做就好
  • 之後專案變大、兩個人要同時改同一個場景,再開分支
  • 那時候會一起講 Pull Request 和 review

不要為了用而用。 三個人的小專案,分支常常只是增加麻煩。