# 專題 - 課輔 [TOC] ## 時間 - 每個禮拜六 19:00~21:00 ## 學生專案 - https://github.com/Sylvia2002/scholarship ## 資料庫 ### 概論 - DBMS (Database Management System) - 管理資料庫的資訊系統 - ex. MySQL, MSSQL - database 相較 file system 的優點 - 降低 data 與 app 的相依性 - 統一存取 data 的標準 - 3-tier architecture - each layer - database layer - business logic layer - UI layer - ex. web-based app - 優 - 減輕單台 server 負擔 - 架構分工明確,易於開發和維護 - 缺 - layer 間需額外傳輸成本 - Data Model - data 存於 database 的規範 - relational data model - 表格式的方式存 data - table 由 row, column 組成 - 效率差 - 要 join table,需 O(n*m) - object-oriented data model - column 存 object 而不是 value - hierarchical data model - 階層式,類似 tree 的方式存 data - 父、子紀錄以 link 連接 - ![image](https://hackmd.io/_uploads/HyZ37rYWR.png) - https://www.geeksforgeeks.org/difference-between-hierarchical-and-network-data-model/ - Key 1. Primary Key - 具備唯一性(一個 table 只有一個 column 為 PK) - 可用於唯一識別一個 record 2. Foreign Key - 會對應到一個 table 的 PK 3. Candiate Key 4. Super Key - Integrity Rules 1. entity : record 需有 PK 2. referential : FK 對應的 PK 需存在 3. domain : value type 需符合對應的 column,且為 atomic value - ER Model - 將實體的關係結構的表示 - component - entity - 長方形 - attribute - 橢圓形 - key - 橢圓形加底線 - relationship - 菱形 - 種類 - 一對一 - 一對多 - 多對多 - ER Diagram - ex. - ![image](https://hackmd.io/_uploads/rynwfBCGC.png) - ref : https://miro.com/diagramming/how-to-draw-an-er-diagram/ - Normalization - 優點 - 可以降低重複儲存 - 避免 新增、修改、刪除 的異常 - 缺點 - 降低查詢的效率(因 join) 1. 1NF - 定義 - 去除多值,所有欄位為 atomic - 每個 record 有 pk - ex. - ![image](https://hackmd.io/_uploads/r13z8vmfA.png) - 有 新增、刪除、修改 異常 - 練習 - stu(snum, name, tel) 2. 2NF - 定義 - 符合 1NF - 去除對 pk 的部分相依 - ex. - ![image](https://hackmd.io/_uploads/SJRgEvXz0.png) - 仍有 新增、修改、刪除 異常 - 練習 - room(course_name, teacher_name, time, teacher_birth) - room(course_name, teacher_name, time) - teacher(teacher_name, teacher_birth) 3. 3NF - 定義 - 符合 1NF & 2NF - 去除非 key 的遞移相依 - ex. - ![image](https://hackmd.io/_uploads/ByjZEPXMR.png) - 練習 - room(course_name, teacher_name, time, teacher_birth, teacher_age) - room(course_name, teacher_name, time) - teacher(teacher_name, teacher_birth) - birth(teacher_birth,teacher_age) - 練習 - 訂單內容 ![image](https://hackmd.io/_uploads/ryTDF_mfC.png) - customer(cid, name) - product(pid, name, price) - order(oid, cid, pid, date time, num) - schema - 依照不同情境,建立資料庫的綱要 - 一對一 - ex. 一個男生只能娶一個女生(兩個 table,男生、女生) 1. 建新的 table : (男生 ID, 女生 ID) 2. 在男生 table 欄位新增 女生 ID 欄位 - 一對多 - ex. 一個老師可以教很多堂課(兩個 table,老師、課程) 1. 建新的 table : (老師 ID, 課程 ID) - 多對多 - ex. 學生選課 1. 建新的 table : (學生 ID, 課程 ID) - 練習 1. ![image](https://hackmd.io/_uploads/HkXgO85Z0.png) ![image](https://hackmd.io/_uploads/BkO1_LcbR.png) :::spoiler 參考解法 relation ![image](https://hackmd.io/_uploads/BkK9crF-A.png) ER Model ![image](https://hackmd.io/_uploads/HJAyvwcWR.png) ::: 2. ![S__5668871](https://hackmd.io/_uploads/BJyOBSAzR.jpg) :::spoiler 參考解法 ![image](https://hackmd.io/_uploads/rkOI1fIQ0.png) ::: ### 語法 - 教學 - https://hackmd.io/@-WjEAPGMTkmWoSDEHpaZuQ/BJaBURrlo/%2FdQr7hSfYS7aSLChtHNEfBw - DDL (Data Definition Language) - 建立、調整 DB、table - 語法 - CREATE : 建立 - ALTER : 更新 - DROP : 刪除 - constraint definition - 當某一 row 的某一 column 被 reference 成其他 table 的 FK,須確保 referential integrity,故可以設定 column 的 constraint definition - ON UPDATE, ON DELETE - NO ACTION : 不能更新該欄或刪除該列。MySQL 的預設 - ex. - Member(MID, name) - (1, "tommy") - (2, "good") - Song(SID, name) - (1, "小星星") - Order(MID, SID) - (1,1) - CASCADE : 連帶刪除或更新受影響的 FK - SET NULL : 將受影響的 column 設為 NULL - SET DEFAULT : 將受影響的 column 設為預設值 - ex. ```sql= CREATE TABLE Student ( s_id int(10), name varchar(10), t_id int(10), PRIMARY KEY (s_id), FOREIGN KEY (t_id) REFERENCES Teacher(t_id) ON DELETE CASCADE ON UPDATE NO ACTION ); ``` - DQL (Data Query Language) - 查詢 data - 語法 - SELECT - operator - WHERE : 過濾篩選條件 - 可以用 =, LIKE 篩選 - LIKE : `%` 代表 0~N 個字元。1 個 `_` 代表 1 個字元 - 可以用 AND, OR 連接 - DISTINCT : 過濾重複欄位的 record - GROUP BY - 依欄位將 record 做分群 - SELECT 的欄位一定會出現於此,但反之不然 - HAVING : 依據 GROUP BY 分群後,再過濾條件 - ORDER BY - 依欄位值大小做排序 - ASC : 遞增,預設 - DESC : 遞減 - AVG - 取平均 - SUM - 加總 - COUNT - 計算 record 數量 - MAX - 找出該欄位最大值 - MIN - 找出該欄位最小值 - join - 同時需要兩個以上的 table 的 data,故須將多個 table 做集合,過濾條件以 `on` 表示 - inner join - 只有條件符合才顯示 - ![](https://hackmd.io/_uploads/Hy_YB3R1p.png) - ex. - `select Customers.CustomerID, Orders.OrderID from Orders inner join Customers on Customers.CustomerID = Orders.CustomerID;` - outer join - left join - 以左邊為主,會顯示條件符合 + 剩下的左邊的資料 - ex. `Orders` 196 筆 + 剩下的 `Employees` 1 筆(該 `EmployeeID` 沒有在 `Orders` 裡) - `SELECT Employees.EmployeeID, Orders.OrderID FROM Employees left join Orders on Employees.EmployeeID = Orders.EmployeeID order by Employees.EmployeeID desc;` - ![](https://hackmd.io/_uploads/HJH9u2R1a.png) - mulitple left join - ![](https://hackmd.io/_uploads/rJG8HWngp.png) - ref : https://stackoverflow.com/questions/4950296/how-to-use-multiple-left-joins-in-sql - right join - 改成以右邊為主 - full join - 顯示條件符合 + 剩下的右邊、左邊 的資料 - cross join - 列出兩個 table 的所有 records 排列組合 - ex. a table 有 5 筆 records,b table 8 筆:會有 40 筆 records - ref - https://ithelp.ithome.com.tw/articles/10215741 - DML (Data Manipulation Language) - 操作 data - 語法 - INSERT : 新增一筆 record - DELETE : 刪除 record - UPDATE : 更新 record - 練習 1. 找出所有商品的商品名稱 :::spoiler 參考解法 SELECT ProductName FROM Products; ::: 3. 找出所有商品的名稱及其供應商的名稱 :::spoiler 參考解法 SELECT P.ProductName, S.SupplierName FROM Products P, Suppliers S WHERE P.SupplierID = S.SupplierID; ::: 2. 找出商品的平均單價超過 30 的供應商名稱 :::spoiler 參考解法 SELECT S.SupplierName, AVG(Price) FROM Products P, Suppliers S WHERE P.SupplierID = S.SupplierID GROUP BY P.SupplierID, S.SupplierName HAVING AVG(Price) > 30; ::: ### 線上測試環境 - https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_top&ss=-1 ### 畫圖工具 - draw.io - ![image](https://hackmd.io/_uploads/Hyvwkc8WA.png) ## 網頁開發 ### 教學 - https://ycchen.im.ncnu.edu.tw/www2011/ - html - frontend js - css - php ### 概論 - 介紹 - 使用者端送 request (其中可能包含一些資訊) 給 web server,web server response data (ex. html) 給 使用者端,再由 browser (ex. chrome) render 在頁面上 - 架構 - 主要由前後端組成 - 前端 - 主要負責頁面的渲染 - 由 HTML, CSS, JS 組成 - 後端 - 主要負責資料的處理 - 可用 php, nodejs, java web ... - 開發架構 - MVC - Model View Controller - ![](https://hackmd.io/_uploads/SkXQKNFk6.png) - 前後端分離架構 - 將前後端拆分成不同系統,前端(ex. ReactJS)只負責畫面顯示 - 分工更清楚、彈性更高 ### HTML - 介紹 - 有多種 element,讓 browser 去解析 - 語法 - 宣告是 html 的文件,讓 browser 知道如何解析,因可能是 xml 或其他種文件 - `<!DOCTYPE html>` - element 宣告 - `<element attribute = "" style = "">content</element>` - `attribute` : 此 element 可設定的屬性 - `style` : 此 element 的排版 - 註解 - `<!-- 我是註解 -->` - 常用 element - `html` - `title` : 頁面標題 - `head` - `h1` - `<meta charset="utf-8">` - `body` - `div` : block element,會占用一整個區塊的大小 - `span` : inline element,僅占用內容的大小 - `br` : 換行 - `table` : 表格 - `a` : 超連結 - `script` : js script - `link` : 引入外部連結的資料(ex. css) - ex. ```html <!DOCTYPE html> <html> <title>Main Page</title> <head> <meta charset="utf-8"> <h1>This is main page.</h1> </head> <body> <div>Contents</div> <div>i am good.</div> <!-- <span>Contents</span> <span>i am good</span> --> </body> </html> ``` ### CSS - 介紹 - 將 html 內容做排版 - box model 1. `margin` - element <b>之間</b> 的距離,隔開相鄰的 element 多少 - ![](https://hackmd.io/_uploads/S1WgPIHMp.png) - ![](https://hackmd.io/_uploads/rkq7DISMp.png) 2. `padding` - element <b>內部</b> 內容(可能是其他 element)的距離,把 element 往裡面擠多少,同時會把外面的 element 撐大 ```html= <html> <style> #test2 { color : hsl(120, 100%, 25%); padding: 100px 50px 50px 500px; // 上右下左 } </style> <body> <div id = "test2"> <div id = "test3">test3</div> </div> </body> ``` - ![](https://hackmd.io/_uploads/r1bv3ydkT.png) 3. `border` - 邊線本身的設定 - bootstrap ### JS - ECMAScrpit - ![image](https://hackmd.io/_uploads/r1X-sNYbA.png) - https://ithelp.ithome.com.tw/articles/10206587 - javascript = dynamic + 超級 week type - strong vs weak type - weak type lanaguage - 會自動轉換 type - ex. js ```js= let a = 1; let b = "1"; console.log(a+b); // 11 ``` - ex. c/c++ : int 會被轉換成 boolean - strong type language - 不會自動轉換 type - ex. java, c# - dynamic vs static type - static - 需先宣告 vairable type - dynamic - 不須,交給編譯器判斷 - ![](https://hackmd.io/_uploads/SyDKOP_yp.png) - js 的 `+` 有 2 個意思:數學、字串 - 當兩方其中有一方是字串,js 就會設定此 `+` 是字串相加 ```js= 111 + 222 + "333" + 111 + 222; // 333333111222 ``` - 但 php 會分開來 : `+` = 數學, `.` = 字串 ```php= <?php $v1 = 111; $v2 = 222; $x = $v1 + $v2; // 333 $x = $v1 . $v2; // "111222" ?> ``` - js 中,幾乎所有東西都可以相加 - ![](https://hackmd.io/_uploads/S1q_hw_1a.png) - 但 php 雖然是弱型別,但還是有限制 - ![](https://hackmd.io/_uploads/ByCq2vdJ6.png) - 解法 - `typescript` : 可讓 code 的型別更嚴謹(雖然不嚴謹還是可以被編譯成 .js),更易讀、維護 - function 加入回傳 type - function 限制傳入參數 type - 有 `private`, `public`, `protected` - scope - 作用域 1. function scope : variable 只在 function 裡有用 2. global scope - 在 html 是 window object - ![](https://hackmd.io/_uploads/ry0vE_uJp.png) `window.aaa; // 5` - 可以在 function 內宣告全域 : 不宣告(`var`, `let`, `const`)變數就給值 ```js= function test() { aaa = 5; } test(); console.log(aaa); ``` - 在 nodejs 是 global object 3. block scope - 只作用在大括號之中 - ![](https://hackmd.io/_uploads/BJyiIOu1a.png) - var vs let vs const - var 缺點 1. 同 scope 內可以重複宣告 - 且不會初始化原本的值 - ![](https://hackmd.io/_uploads/B1FN8uuJ6.png) - 可能會不小心改到之前有宣告過的同名的變數 2. 不支援 constant variable(不能被改的) 3. 不支援 block scope - ![](https://hackmd.io/_uploads/SJbGDdOk6.png) - 因為 var 是 function scope - ![](https://hackmd.io/_uploads/H1_2ncxzp.png) 4. 會產生 global variable - ![](https://hackmd.io/_uploads/rJBy3dOJT.png) - let 優點 1. 同個 scope 內不可重複宣告 2. 支援 block scope - ![](https://hackmd.io/_uploads/BJLbx95MT.png) - ![](https://hackmd.io/_uploads/Skovgq9za.png) 4. 不會產生 global variable - ![](https://hackmd.io/_uploads/SJMtjbSgT.png) - 原因 - ![](https://hackmd.io/_uploads/r1lo3_OJp.png) - 這樣的好處是進一步管控了 Global 變數,只能透過 Global Object 去存取,提升程式的嚴謹性和安全性。 - const 優點 - 除了 let 優點再加上 : 定義時必須初始化 (Initialization),且之後不能再更改 - ref - https://something-about-js-book.onejar99.com/day08 - hosting - js 會將 variable, function 的 declare 拉到 scope 最上面 - varaiable ```js= console.log(x); var x = 5; // 會變成 var x; // declare console.log(x); x = 5; // 這邊是 init ``` - function ```js= sayHi(); function sayHi(){ console.log('Hi'); } // 會變成 // 整個 function 都被拉到最上面 function sayHi(){ console.log('Hi'); } sayHi ``` - function in variable - ![](https://hackmd.io/_uploads/B19DJKdyp.png) - 因會變成 - ![](https://hackmd.io/_uploads/HkfFJY_Ja.png) - 只有 `var` 會有 undefined 的效果,`let` 和 `const` 雖然也有 hosting,但不會初始化為 undefiend,所以會顯示 `reference error : is not defined` - function 常用寫法 1. 一般 : 有 hosting ```js= a("test"); function a(name) { console.log(name); // test } ``` 2. anonymous function : 無 hosting ```js= a("test"); // error : a is not a function var a = function (name) { console.log(name); } ``` 3. arrow function - 語法更為簡潔 - ![](https://hackmd.io/_uploads/H1_BQZWga.png) - 主要和傳統 function 差在 `this` - 傳統 function 的 this 是指向呼叫他的 object - ![](https://hackmd.io/_uploads/rJlJl7-Zg6.png) - ref - https://ithelp.ithome.com.tw/articles/10207992 - arrow function 的 this 是指向外圍一層的 function(如果一直往外找沒有的話就會指向 window) - 適合用在 `setTimeout`, `setInterval` - object 寫法 - ![](https://hackmd.io/_uploads/B1vmfbWxa.png) - ![](https://hackmd.io/_uploads/SkAEz--gT.png) - function 寫法 - ![](https://hackmd.io/_uploads/By8C_JUfa.png) - ![](https://hackmd.io/_uploads/HJchOyUGT.png) - 不為此 scope 產生新的 `arguments` - 傳統可用 `arguments`,不用管帶入的參數 - ![](https://hackmd.io/_uploads/ryfmttuJa.png) - 改成這樣 - ![](https://hackmd.io/_uploads/BkfvYtdJT.png) - AJAX - 藉由 browser 的 web api 達成和 js main thread 達成非同步去 call api,動態去更改網頁中部份內容,而不用重新載入 - callback - 一個 function 裡面在 call 別的 function,可確保執行順序,目前這個 function 跑完,才去 callback 下一個 function - 常見於封裝 XMLHttpRequest 的 ajax - ![](https://hackmd.io/_uploads/BJ9QBQHyT.png) - callback hell - 如果要連續呼叫多個有上下關係的 api,就會變成巢狀不易維護和閱讀 - ![](https://hackmd.io/_uploads/r1B48XB1a.png) - promise - 為了解決 callback hell 的問題而產生的 object - ![](https://hackmd.io/_uploads/S1eHqft16.png) - 3 種狀態 - pending : 等待中 - fullfilled : 成功,執行 `then` 裡面的 code - rejected : 失敗,執行 `catch` 裡面的 code - ex. ```js= myName() .then((res) => console.log('成功:'+ res)) .catch((error) => console.log('失敗:' + error)); ``` - 多種寫法 1. `Promise.all` : 一次等待所有 promise 完成才做 `then`,且多隻 api 是同時執行(不是一個執行完換下一個),適合打多隻 api 的,但是若有一隻 error 就不會顯示其他正確的 api 的訊息 - ![](https://hackmd.io/_uploads/BkezO7Bya.png) - `resolve` : 回傳成功的訊息 - `reject` : 回傳錯誤的訊息 - 如果上下 api 沒有關係,可以用此來加快速度 - ![](https://hackmd.io/_uploads/ByunEEryp.png) - 需一個一個等待,較慢 - ![](https://hackmd.io/_uploads/HyVA4ESya.png) - 一起做,較快 2. `Promise.allSettled` : 和 `all` 差別在,會回傳所有 api 的訊息(就算有 error),回傳時會多帶一個 `status` 代表成功 or 失敗 - ![](https://hackmd.io/_uploads/rJqS4NrJT.png) 3. `Promise.race` : 只做先完成的 - ![](https://hackmd.io/_uploads/BktddXB1a.png) - 教學 - https://israynotarray.com/javascript/20211128/2950137358/ - async/await - 解決 promise 還要寫 then, catch,還是有可能變巢狀結構,更易讀 - async - function 加上 async,代表會回傳一個 promise 的 object - sync vs async - sync : 等一行執行完才會到下一行 - ex. nodejs : `fs.readFileSync('./README.md')` - async : 可先去執行別行,等之前的執行完再執行 callback function - ex. `fs.readFile('./README.md',readFileFinished);` - await - await 會等其後的 promise object 結束(resolved or rejected),再繼續執行 - await 需在 async function 內用 - axios vs ajax vs fetch - ajax - 不支援 promise,要用 callback - fetch - 基於 promise,所以可以用 then、async+await,js 原生支援,不須引入 - request body 的 data 需先 json.stringify - axios - 基於 promise,所以可以用 then、async+await - 較 fetch 易用 - 可直接 `axios.post`,fetch 需寫在裡面 - ![](https://hackmd.io/_uploads/rJ3R14Hyp.png) - 不須 stringify,直接送 json - request method - 有分為:get, post, put, delete, update - get - 將傳送的資料轉為 query string 加再 url 後面 - 如果用 get 來更新資料會有點危險,因可能別人隨便傳給你連結就點,結果是亂帶資料的 - 或是不小心點到錯誤網址 - 好處是可以藉由 url 傳參數,使用者也方便知道參數 - post - 將資料放入 request 的 body - Restful API - url 內容的部分的 root = api - ![](https://hackmd.io/_uploads/ByQlqHG-T.png) - 用正確的 method 可以增加 SEO - get - 獲得所有實驗室資料 - `/api/lab` - 獲得單一實驗室資料 - `/api/lab/{lab_id}` - post - 建立新實驗室資料 - `/api/lab` - put - 更新單一實驗室資料 - `/api/lab/{lab_id}` - 更新單一實驗室部分資料 - 更新實驗室負責人資料 - `/api/lab/{lab_id}/manager` - delete - 刪除單一實驗室資料 - `/api/lab/{lab_id}` - ref - https://igouist.github.io/post/2021/05/newbie-2-webapi/ ### NodeJS - 介紹 - nodejs 是一個開源的工具,用於執行 javascript,且提供許多用於網頁後端的套件(ex. http server) - 優點 - 前後端都用 js,比較好整合 - 大量 IO request 的情境下效能佳 - ![](https://hackmd.io/_uploads/BysDbe6la.png) - https://medium.com/@mihaigeorge.c/web-rest-api-benchmark-on-a-real-life-application-ebb743a5d7a3 - npm - nodejs 預設的套件管理系統 - 可用於更容易安裝、管理套件 - 安裝 - https://nodejs.org/en/download - 初始化 nodejs 專案 - `cd` 到專案的資料夾 - 初始化 npm - `npm init` - ExpressJS - 介紹 - 是一個基於 nodejs 的輕量級網頁框架,提供許多後端網頁會用到的套件 - 跟其他有完整 MVC 架構的框架相比,Express 其實鬆散(或者說自由)很多,許多地方並沒有強制規範,都只是按照前人的方法或者是慣例來實踐,十個人可能會有十種不同的寫法。 - 教學 - https://hackmd.io/@Heidi-Liu/note-be201-express-node - 安裝 - `npm install express` - request - 預設只能拿到 get 的 query string,所以要拿到 post 的 request.body,就要用 `body-parser` 來 parse request 的 body - `bodyParser.urlencoded()` 處理 UTF-8 編碼的資料,常見的表單(form)提交 例如:application/x-www-form-urlencoded - `bodyParser.json()` 處理 JSON 格式的資料 例如:application/json - `bodyParser.text()` 處理 type 為 text 的資料 例如:text/html, text/css - `bodyParser.raw()` 處理 type 為 application 的資料 例如:application/pdf, application/zip - ex. ```js= app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) ``` - MVC in express - ![](https://hackmd.io/_uploads/SkXQKNFk6.png) - controller 就是 express router - controller 可以再細分成 routing 和 邏輯處理的 middleware - 所以 `index.js` 引入 `api` 中 routing 檔案只負責路由回傳由 middleware 處理完的資料 - `index.js` - 引入 routing 的檔案 - routing - ![](https://hackmd.io/_uploads/HkAL6MZe6.png) - middleware - ![](https://hackmd.io/_uploads/HJsQaGZx6.png) - 範例 - https://github.com/tommygood/Express_Example - 存取 db - 先將 db schema dump into database - 建立 db user 讓系統可以存取 db - `CREATE USER '{username}'@'{host}' identified by '{password}';` - ex. `CREATE USER 'test'@'%' identified by '123';` - 給權限 - all table - `GRANT ALL PRIVILEGES ON *.* TO '{username}'@'%';` - one table, ex. wp table - `GRANT ALL PRIVILEGES ON wp.* TO '{username}'@'%';` - `flush privileges;` - 建立 pool ```js= const db = require("mariadb"); // 相容於 MySQL // create pool const pool = db.createPool({ connectionLimit : 50, // 這個 pool 占用的連線數量 host : 'localhost', user : 'test', password : '123', database : 'scholarship' }); ``` - 可能遇到的問題 - `too many connections` - 問題描述:因目前資料庫的連線數量超過 `max_connections` 這個最大連線數的變數的大小 - 查看目前資料庫的 `max_connections` - ![image](https://hackmd.io/_uploads/SJlIsO5rC.png) - 查看目前資料庫的總連線數量 - ![image](https://hackmd.io/_uploads/Hy-2sucH0.png) - sol 1. 將目前的連線數量大小調整到足夠 2. 將建立的 pool 的連線數量調小 3. 檢查是否有不小心重複建立多個 pool ## Git ### 介紹 - 用於專案的版控,在多人開發專案時助於提升開發效率,降低溝通成本 - 平台 - ex. github, gitlab - 可以利用 git 將專案的原始碼儲存於平台中 ### 概論 - branch - 一個專案可以有多個 branch,不同 branch 的 code 通常會不同,代表這個 branch 中的專案處在不同的情境 - ex. - ![image](https://hackmd.io/_uploads/rJH1aQ0MR.png) - 有 5 個 commit 的 branch - commit - 一個 branch 可以有多個 commit,當每次新增或更新完內容後,可以提交一次 commit,就可以將這次修改的部分的 code 更新到所處的 branch ### 常用指令 - 複製專案 - `git clone {repo}` - 提交這次新的修改 - `git add .` - 將目前所在的檔案有修正的部分全部新增到暫存區 - `git commit -m "{commit msg}"` - 將暫存區的檔案更新的內容作為一個 commit 提交到 branch - `git push {origin} {branch}` - 將本地的 branch 的新 commit 推到來源端的 branch - 本地更新雲端上的新的 commit 內容 - `git pull {origin} {branch}` ### 教學 - https://learngitbranching.js.org/?locale=zh_TW