# 簡易git使用教學
## 環境
- OS: Windows 10
- git環境: Git Bash
- git伺服器: GitHub
* 以下文章皆使用`Git Bash`及`GitHub`進行操作。
## Git Bash
* 在使用git之前,我們必須先準備好git的環境。
* 本人是使用陽春、最基本的[Git Bash](https://git-scm.com/downloads)。完全沒有GUI,純CMD的介面。
* 好處是使用起來比較乾淨,理論上git有提供的功能都可以做到。
* 壞處是使用起來比較麻煩,GUI(如SourceTree)可能只要按一顆鍵就完成的事情,你要打三行指令。同時沒有圖像化界面來檢視你的專案開發狀況。
* 總之,我只會用Git Bash。
## GitHub
* 再來,你要有一個git用的伺服端,用於存放你的專案。你可以想成你需要一個雲端空間去存檔案,只是他同時提供了git相關的功能,像是版本控制。
* 本人我使用的空間,也是一般最常用的[GitHub](https://github.com/)。
* 申請完帳號之後,右上角的New repository就是開一個新的空間去存一個專案的概念。
* 
## 本機?伺服?
* 本機端指的就是你電腦正在開發的專案版本,而伺服端就是目前在Git上的版本。
* 本機端可以有很多個、代表有很多個人在開發同一個專案,但他們都應該上傳到同一個伺服端。
## 新建專案
* 先在GitHub上面新增一個資料庫。
* 
* 然後在你電腦想放檔案的地方建一個新的資料夾,並右鍵執行Git Bash。
* 
* 先回到GitHub,找到你剛剛新增的資料庫,裡面有個**Clone or download**,將裡面的URL複製起來。
* 
* 再回到Git Bash,輸入`git clone [剛剛的Url]`。
* 
* 注意一下,Git Bash的複製貼上快捷鍵可能不一樣。
* 按下Enter之後,等它跑出`done`,應該就可以在資料夾看到你Clone下來的專案了。
* 
* 到此為止,你已經完成新建一個專案了。接著你只要在新跑出來的資料夾裡面,開始你的作業即可。
* 
### 如果我已經有專案檔或code,而不是從頭開始,我要怎麼辦?
* 你一樣先在GitHub上建立一個新的資料庫,一樣在電腦裡Clone。
* 出來新資料夾之後,在把你原有的檔案複製到資料夾內即可。
* 記得要進行下面的更新,GitHub才會有東西喔。
## 更新專案
* 今天我已經修改的我的文件(範例為main.cpp,你可以是任何檔案,包含專案檔),但是我看GitHub上面並沒有改變阿?
* 
* 那是當然,因為你需要進行`Push`。也就是將你的檔案推上Git。
* 要進行`Push`,先找到你的資料夾,一樣右鍵開啟Git Bash。
* 
* 確認路徑是你放檔案的地方,結尾應該要有分支名稱(新建的話就是master)。
* 確認無誤後,輸入以下三行:
* 
```git
git add .
git commit -m [你修改了什麼]
git push
```
* 這時候已經完成`Push`。到GitHub去看也確實更新上去了。
* 
### add, commit and push?
* 這三行到底分別是幹嘛?
* 你可以想像今天伺服端和本機端是兩塊大陸,你想要把檔案從本地端更新至伺服端,必須開船過去。
* add指令是將檔案加入到一個清單,清單決定那些檔案要放到船上。
* add . 代表所有有更動的檔案都加上去。
* commit則是真的把檔案搬到船上。
* push是船真的開出去,將檔案真正運到伺服端。
## 分支——多線開發
* Branch是一個重要的技巧,不僅在多人開發中會使用,即使單人開發也強烈建議使用Branch。
* 今天你如果只是像上面教的,有修改就push,這樣你和使用Google Driver好像也沒什麼差別。
* 分支的概念是push的時候,不要都push到同一個地方,而是對不同功能的開發push到各自的分支。
### 範例一:假設多人共同合作開發一款遊戲:
* 寫敵人的就都push到上面的分支。
* 寫地圖的就都push到中間的分支。
* 寫道具的就都push到下面的分支。
* 最後再把大家的code merge起來。
* 
* 好處:我寫敵人的時候,可能中間要push好幾次檔案,如果都push在同一個分支,我push一次就得整合一次大家的code;改成多個branches,變成大家都開發完畢之後,merge最後一次就好了。
### 範例二:同一個事情我有兩種演算法:
* 今天一個function我有兩種想法,但我不知道哪一種比較好。
* 我可以先寫第一種,寫完之後push到branch 1。
* 接著寫第二種,push到branch 2。
* 實測完哪一種比較好之後,再決定master要merge哪一邊的code。
* 好處:我不必把兩種演算法擠在一起測試,也不必為了做第二種演算法先把第一種刪掉。且不論我最後選了哪個,兩種演算法都有好好記錄起來。
### 使用branch
* 要新建一個Branch很簡單,一樣打開Git Bash之後,輸入以下指令:
* 
```git
git checkout -b "分支的名字"
```
* 這樣就成功新建並切換到一個新的分支了,接著我將我的檔案做一點修改,然後push上去測試看看。
* 你可能會發現push不上去,那是因為你剛剛新創了一個branch,要先把branch推上去才行。
* 
* 因此我們將指令`git push`改為`git push --set-upstream origin newBranch`。
* 
* 這時候就順利完成了,去GitHub看也有看到新的分支。
* 
## 回到上一個版本
* git中有許多版本控制的功能,在這邊來教一個最基本的功能:**回到最新提交的版本**。
* 今天假設我修改了我的code,然後發現整個專案炸裂,而且我不知道該從何下手去修正它:
* 
* 這個時候打開你的`Git Bash`,輸入`git reset --hard HEAD`。
* 
* 再回去看你的檔案,會發現它已經回到你最新一次commit的結果了。
* 
### 關於版控,更多內容
* 那如果今天你一不小心,已經將爆炸的版本push上去了,那要怎麼辦呢?
* 上述的`HEAD`是一個指向最新版本的指標,因此你可以用指令`git reset --hard HEAD~n`(`n`為數字),來回到上`n`次的版本。
* 如果你不知道哪個版本是哪個,可以用`git log`來看你所有提交歷史:
* 
* 之前的範例提交太少次了,隨便找了一個專案來當作範例。
* 你可以發現,除了時間可以當作你判斷檔案的依據之外,就只能看你commit的時候下的註解,因此平時最好不要偷懶亂打,要根據修改的內容去撰寫。
* 如果想要回到指定的版本,那就使用`git reset --hard [版本ID]`即可。
* 版本ID可以不用打完整,你輸入前面幾個字元,他會自己去幫你match到一樣的版本。
## 常用指令列表
* 簡易的教學大概到這邊,更多功能(Merge, pull, diff, status)可以再去Google,有些其實蠻基本的我也沒寫到。
* 簡單統整一下這篇有的指令:
| 指令 | 功能 |
| -------- | -------- |
| clone | 複製資料到本機端 |
| add | 將檔案加入清單 |
| commit | 提交檔案 |
| push | 將修改推到伺服端 |
| pull | 將本機更新到最新版本 |
| checkout | 切換分支 |
## 其他資源
* [連猴子都能懂得Git入門指南](https://backlog.com/git-tutorial/tw/)
* 我就是看這個學的,只要將數據庫換成GitHub就很好上手了。
## Info
* [我的網頁 - Zerone](https://zero871015.github.io/)
* 一更 [name=Zero871015][time=Thu, Jun 6, 2019 1:24 AM]
* 二更 [name=Zero871015][time=Mon, Jun 24, 2019 8:30 PM]
* 三更 [name=Zero871015][time=Thu, Nov 5, 2020 7:17 PM]
###### tags: `git`