# 親愛的，我把 GitHub 拿來收作業了!

> 使用 GitHub 收作業的優點包括不再擔心郵件遺失、透明公開的作業管理、記錄提交歷史、便於程式碼審查，同時學生還能學到Git和 Markdown 等技能。缺點是需要老師和學生花時間學習 GitHub，但這種方式有助於提高效率和公平性。

Published: 2017-12-12
URL: https://kaochenlong.com/use-github-for-homework

---

時間過得很快，一轉眼今年秋天在[台北商業大學](http://www.ntub.edu.tw/bin/home.php)開設的 Ruby on Rails 學程已經是第四年了。

不管是什麼技能，想要學會不太可能就只靠每週三小時的三學分課程就學得會，一定需要平日的練習或是實作專案才能有所成效。由於是學校的正式課程，需要有打分數的標準，於是除了期中、期末考外，所以每週會規定同學們要繳交作業。

在以往大多會使用 Email 或是開學校的 FTP 請同學自己上傳檔案，但 Email 有些不確定性(被歸進垃圾郵件或是寄往莫明的黑洞完全消失)，而 FTP 雖然簡單，但我希望同學們還可以在學校再學到一些其它畢業之後還能用到的技能，於是我便選擇使用 Git/GitHub 來收同學們的作業。

Git 不是新技術，使用 GitHub 收作業也不是什麼新潮的做法，國外早就有學校是這樣做的，本文不是要介紹如何使用 Git 指令或教大家如何使用 GitHub，僅分享我自己這幾年來在學校授課時實際使用 GitHub 收作業的一些心得。

&lt;!--more--&gt;

## 優缺點？

使用 GitHub 來收作業有什麼優點跟缺點呢？先說優點：

### 優點

#### 1. 不用擔心收不到

「老師，我昨天有把作業寄出去了，請問有收到嗎？」由於 Email 有時會有些不確定性，偶爾會因為附件檔案太大被退件，或是被歸到垃圾信件，又或是莫名的消失在網路世界中，像這樣的對話我相信大家不會太陌生。（而且是不是真的有寄出有時候也是個問號）

由於同學們是使用 Git 把作業推上 GitHub 並以發送 Pull Request(以下簡稱 PR) 的方式繳交作業，就不用太擔心這個問題，同學們也不需要一直來問老師是不是有收到作業。

#### 2. 不用特別花時間整理

如果是使用 Email 方式繳交，平常工作上的信件已經夠多了，還得從眾多信件中整理出同學們各式各樣標題的作業繳交信件，還不一定找得到。從信件中整理出同學們的作業會是很花時間的工作，生命就該浪費在美好的事物上才是！

#### 3. 透明公開

作業繳交的時間很明確，一切公開透明，作業有沒有交、是不是在期限前繳交、寫得好不好，全部一目了然，不會因為跟老師比較熟或是跟老師有一腿（咦？）所以分數比較高。

![Personal Folder](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWDg9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--bb55b180da631dee736eb5320cf0045840f58e3e/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/score.png)

#### 4. 有完整的紀錄

因為 Git 有 log 可以看，所以可以知道同學們是在什麼時間點完成作業的。有時我還會在作業裡指定每個 Commit 要做什麼事：

![Commit](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWUE9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--82fb3ce6649f644e0cb4096bc75957741ae64a83/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/commits-on-steps.png)

這不只是希望同學們練習控制 Commit 的顆粒度，而且如果是參考同學的作業能參考到這麼精準，至少也有練到 Git 的基本功了。

#### 5. 方便 Code Review

GitHub 網站提供的功能，可以很容易的在同學繳交的作業上加建議：

![GitHub Comment](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWUU9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--ddf474f7d34c46e0caea7d732b22e82ac4537b10/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/comment-on-github.png)

有時候我會反過來，我寫一段 Code，請同學們閱讀後幫我加上註解或說明。之後也打算試著讓同學之間互相進行 Code Review，像這樣
不同程度之間的互相 Review，常可收到不錯的成效。

#### 6. 順便學會新技能

Git 目前是業界版本控制工具的首選，就算原本課程的本體學得不怎麼樣也沒關係，至少可以提早在學校就讓同學學會這項技能也不是壞事。

#### 7. 順便學會怎麼使用 Markdown

[Markdown](https://en.wikipedia.org/wiki/Markdown) 是一款可以用來產生 HTML 文件的輕量級標記語言，容易寫、容易學，因為 GitHub 也支援 Markdown 顯示，所以我也會順便要求同學們使用 Markdown 來撰寫作業，同時順便多學一項技能也不錯。

#### 8. 老師不總是對的

我常會跟同學們說，不要台上老師講什麼你們就聽進去，對很多事情都要抱著懷疑的態度，所以也曾發生作者或期中考的題目寫錯，或是教材有錯別字，同學就直接幫忙發 PR 修正（鼓掌）。

### 缺點

缺點其實不太多，我想到的就只有以下兩個：

1. 老師得先花一點時間學會如何使用 Git &amp; GitHub。
2. 接著老師得花一點時間教同學們如何使用 Git &amp; GitHub。

## 怎麼開始？

首先，我會先在 GitHub 上開一個公開的 Repository，接著會請每位同學在上面建立自己的個人學號目錄（或是我幫同學們建立也可以），像這樣：

![Personal Folder](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWUk9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--1c3d0c97d436a9272d06e7558e10ca2fa8d08d22/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/create_personal_folder.png)

接著，請同學們在自己的學號目錄裡放一個叫做 `README.md` 的檔案。由於在 GitHub 上 `README.md` 檔案會被當做是該目錄的預設展示頁面，所以第一堂課我會請他們編輯這個檔案，做個簡單的自我介紹。

### 怎麼收作業？

基本上就是使用 GitHub 上的 Pull Request（PR）方式來收作業。如果對 PR 流程不熟，我在[這裡](https://gitbook.tw/chapters/github/pull-request)有錄了一段影片供大家參考。

除了第一堂課的自我介紹外，接下來每週的作業，我會開一個分支：

![homework branch](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWU09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--833f8885020a3357b86df865e39d46440de2a1af/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/homework-branch.png)

然後請同學完成作業後，發送 PR 到該分支。在每週改完作業後，因為 PR 收下來的東西有點亂，所以我會使用 rebase 方式整理分支並合併到 master 分支：

![rebase homework branch](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWVE9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--dcff9bf9d8c5666806ddada4f386e2ad63c8a814/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/rebase-homework-branch.png)

如果對 rebase 不熟悉，我在[這裡](https://gitbook.tw/chapters/branch/merge-with-rebase)有放一段 rebase 的教學影片。

除此之外，還可搭配 GitHub 上的 issue 功能進行討論。

### 期中、期末考

期中、期末考一樣我也是使用類似方式進行，我會在考試前幾分鐘把題目推上某個分支，請大家完成後再發 PR 回來。

也許你會好奇，PR 都是公開的話，同學們作弊怎麼辦？因為題目是在考前才推上去，而且其實可以在每個人的學號目錄裡放不一樣的題目，還是可以做到一點防止作弊的效果。但對我來說，我的在意的不是同學們的分數，而是同學們有沒有真的學會。

## 打槍？

若有以下情況，PR 會被退回：

### 作業不是放在個人目錄裡，或 PR 未在指定的 Branch 裡

這沒辦法，沒有把作業放在對的位置，一定是打槍的。

### GitHub 帳號尚未設定個人照片(Avatar)

這點算是我個人比較龜毛的偏好。沒設定大頭貼照片，表示你可能不怎麼重視這個帳號（同學們，你們的 FB、LINE、IG 都會一直換大頭照了，為什麼這個不行？）。如果你自己都不重視的話，我應該也沒道理重視。

我們家面試新人的時候，如果履歷上附的 GitHub 是個使用預設圖片的帳號，基本上大概也不會太期待了。

### 單次 PR 的 Commit 次數過多

同學們一開始還不習慣 Commit 的手感，有可能一次 Commit 一大堆檔案，或是每次 Commit 只有一點點的修改，這些都會被我退回去整理後再重新發 PR，期望大家可以透過這個訓練提早養成正確的 Commit 習慣。

### 測試沒過

有些作業我會請同學們寫一段程式並串接上 CI(Continuous Integration) 來跑自動化測試：

![CI](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWVU9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--c411ba3d0c141f8857d010aafd34952b91a0bd6c/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/github-ci.png)

如果在 PR 後面出現紅色叉叉表示那個測試是有問題的，連看都不需要看就可直接關掉，有綠色勾勾才需要開始看。我使用的是 [Travis CI](https://travis-ci.org/)，透過它的設定檔可以設定只針對特定的分支或是 PR 來進行測試：

![Travis CI](/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBWVk9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--05d9b72642210a432d5a4fb866572fe1bd4a3adc/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJXa0NBQVE9IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--578d6799c87a604ca574298502ba874c9075e929/travis-ci.png)

當同學們發送 PR 的同時便會啟動 CI 流程，如果 CI 沒跑過同學們會自己收到通知。

### Commit 或 PR 的訊息無意義

Commit 訊息很重要嗎？ 對，很重要！很重要！很重要！（所以要說三次）

它最主要的目的就是告訴你自己以及其它人「這次的修改做了什麼」，所以不管是用中文或英文，如果訊息沒什麼意義的話我也會退回去修正重送。

### PR 內含有未處理之 conflict。

這就不用說了，有衝突，當然是解掉之後再重送啦！

### 超過繳交期限，或是同一次 PR 裡有前次作業。

我這人比較難相處，不太喜歡超過期限的作業或是補交作業，所以有這個情況我也會把作業退回去。

## 常見問題

### 成效如何？

這我不好說，但就算課程本身學得不怎麼樣，至少還學到 Git 跟 GitHub 怎麼用，也算是有學到一技之長。

### 不怕學生抄嗎？

要抄就抄啊！大家都當過學生，我知道作業一定會抄來抄去，所以我會在開學第一週就跟同學們說：

&gt; 我給大家的作業都不算太難，目的是希望大家回去後再多花一點時間練習，所以請盡量試著自己寫寫看。用抄的其實還是看得出來的，我大學時候也不喜歡寫作業所以我不會怪大家。重點是，各位的人生是你們自己的，想要變什麼樣的人，就要在年輕的時候做什麼樣的努力。

但印象中還是有回同學抄了某位同學的作業，最後我是給「比較晚 Commit」的那位同學的那次作業零分，因為如果作業借同學抄還比別人晚交就是你的錯了。

## 想試試看嗎？我很樂意跟大家分享

各位學校的教授、老師們想試試看嗎？我知道老師們大多很忙，如果您是現職學校教職員，貴校只要集滿五名以上教職員，台北市/新北市我可免費前往貴校與老師們分享；若是外縣市的話只要幫我處理車資就行了 :)



