---
# System prepended metadata

title: Git & GitHub的簡短教學

---

# Git介紹與操作教學

## **Git 安裝教學**
搜尋git安裝
![image](https://hackmd.io/_uploads/SyvR3UXMC.png)

點選windows安裝
![image](https://hackmd.io/_uploads/HkP86I7M0.png)


## **Git 基礎指令**
此處使用 VScode 操作，請先建立一空資料夾並以VScode開啟
新增一 movie.txt 檔，點選 Terminal -> New Terminal，即可在終端機上使用 git 語法

![image](https://hackmd.io/_uploads/SkNnC87MC.png)

```
git init
```
將當下環境變成一個新的 Git 版控
```
git status
```
確認版控狀態

![image](https://hackmd.io/_uploads/S1SIbDmz0.png)

>紅字代表 movie.txt此檔案尚未上傳至Git或變更尚未上傳

```
git add 文件名稱
```
打一段文字當作新變更

![image](https://hackmd.io/_uploads/H1sK7D7fC.png)

將當下檔案加進 Git 準備存檔階段

![image](https://hackmd.io/_uploads/S1lqZwQzC.png)

>add 檔案後 model.txt狀態變綠色了!
```
git commit -m "存檔名稱"
```
![image](https://hackmd.io/_uploads/Hyu6bvQz0.png)

將當下存檔，存檔名稱可讓之後我們判斷是哪個存檔
>
>==注意:git add只是將檔案提交到準備存檔的階段，實際存檔還是要用git commit==

```
git branch
```
查看分支
```
git log
```
查看存檔紀錄

![image](https://hackmd.io/_uploads/Hy6gMP7GA.png)

```
git restore 檔案名稱
```
在VScode中會將以修改會將新增或修改過後但尚未存入 Git 的程式碼開頭顯示綠色，而若想回復存檔(這裡的存檔指的是存至 Git，而不是將 VScode 之存檔)前之狀態，則使用 git restore

![image](https://hackmd.io/_uploads/r1fq90dZA.png)
```
git add .
```
因為在同一時間下可能修改了資料夾裡的許多檔案，而使用git add "檔案名稱"會耗費過多時間在提交，故使用git add . 可將目前路徑下所有檔案提交到 Git，




```
git reset 存檔紀錄碼
```
Git 是利用 commit ....來讀取記錄檔，故要讀取時reset後方加入git log可查詢到的commit後長串字碼

![image](https://hackmd.io/_uploads/Hyy-9w7MR.png)

讀取first save，會發現第2行開頭變為綠色，是因為第2行開始是second save之範圍，而現在git log查詢發現位於first save，目前可從first save之位置繼續更改，且其後都是尚未存檔的

```
git reflog
```
查看以往變更的位置與紀錄

![image](https://hackmd.io/_uploads/SkPJB_Xf0.png)


## **分支Branch**
何謂<font color="#f00">分支</font>，在一個開發團隊中有一條主線 (時間線) 作為主要開發，而各成員可以在主線上另開許多分支 branch 做為測試各功能用途，而當此分支出現錯誤並不影響主線流程，或者分支測試完畢可與主線合併，如圖 Master 為主線，而Bugfix為新開之分支。
![image](https://hackmd.io/_uploads/ByoKTQtWR.png)
>[!Note]
>注意通常開發過程中不會直接對主分支進行修改，而是新開子分支修改後推上 git，再發 Merge request 讓 devops 成員或主管審核合併。

### 建立branch
```
git branch 支線名稱 #建立新支線
git branch #查看目前分支狀況
git checkout 分支名稱 #切換到想要的分支上
```
>綠色表示目前所在之分支，master為主線
>![image](https://hackmd.io/_uploads/BJ90RPQzR.png)

此時先將支線轉換至second_branch，新增一新文檔soccer.txt，並在movie2.txt打新的內容，用git add .將所有變動加入Git，接著存檔為add soccer and new，用git log查看發現第二個存檔被存至支線second_branch

![image](https://hackmd.io/_uploads/HJA1WOXGC.png)



### 刪除branch
```
git branch -D 分支名稱
```
>==注意:要刪除某分支，當前位置不能在該分支上，需先切換到其餘分支==
### 合併branch

```
git merge 支線名稱 #當支線修改或新增完畢後，即可與主線合併
git merge second_branch
```

上述 second_branch 內容以修改完畢，就可以將支線合併到主線上，使用 git merge second_branch，合併完成後即可刪除支線

# GitHub操作教學
首先登入 GitHub，創建一 repository，點選 New repository

![image](https://hackmd.io/_uploads/rkFZ5dmG0.png)

選取 owner 及設定 repository name，往下選取公開或私人後創建 repository

![image](https://hackmd.io/_uploads/SkFYcuQzR.png)

***
## 上傳本地檔案至GitHub
創建完畢後會看到以下畫面，而複製最下方的程式碼可以協助你在vscode的終端機上將資料夾的檔案上傳至 GitHub 的此 repo

![image](https://hackmd.io/_uploads/BJewwFQGA.png)

在VScode執行以上指令後即將檔案上傳至GitHub，重整網頁便可發現所有檔案皆已顯示

![image](https://hackmd.io/_uploads/Hyeu_cNMA.png)
 ***
## 從GitHub上下載檔案

1.在repository裡點選code -> ssh -> 複製repo的路徑
![image](https://hackmd.io/_uploads/H1w9KqVfR.png)

2.在 VScode 終端機上執行 git clone 指令，加上上一部複製的路徑，結尾加上資料夾名稱，如此便會在原路徑上新增一資料夾並將GitHub上檔案下載至本地端

![image](https://hackmd.io/_uploads/HkEY5q4f0.png)
***
## Pull
當我們與他人共同開發程式時，若有新版本的修改更新可使用 Pull request 將最新檔案拉到本地開發環境，使本地可以與 GitHub repo 上同步

1.現在使用 Add file 創建一新檔案 new_file.txt 當作GitHub repo 上的更新(即共同開發者新上傳或修改過後的檔案)

![image](https://hackmd.io/_uploads/SkOb09EGA.png)

2.在開發端使用 
```
git pull
```
![image](https://hackmd.io/_uploads/BkL00q4zR.png)

使用者端已與 GitHub 上同步
***
## Push
可以將 GitHub repo 檔案拉下來，同樣能將修改過後的資料推送至雲端同步，這時需使用git push指令

1.首先將上一步新增的 `new_file.txt` 檔案增加一些文字，並執行 `git add .`與 `git commit` 指令做新存檔

![image](https://hackmd.io/_uploads/ByLbesEz0.png)

查看版控狀態發現 git 告訴我們有一項新存檔可以推送至 gitHub

2.在VScode終端機上執行git push指令
![image](https://hackmd.io/_uploads/r1CYZoVz0.png)
重整 gitHub 網頁後發現新存檔都已推送至雲端
***

<font color="#0072E3">**如何同步分支到Github上**</font>

1.首先在 VScode 創造一新分支 new_branch，並在新分支上修改一些檔案後存檔

![image](https://hackmd.io/_uploads/H16UBsEG0.png)

![image](https://hackmd.io/_uploads/BJg3SiVfC.png)

存檔名叫做"新分支的存檔"，已存入新分支中，此時使用以下指令將新的分支推送到雲端上

```
git push -u origin 分支名稱
```
![image](https://hackmd.io/_uploads/HyxYUoVM0.png)
在GitHub上就可以看到新分支已被推送上去

***
# Merge Conflict 合併衝突
合併衝突是指多人同時修改同一行 code 時，就會有衝突情況，在推送至 GitHub 上時會不知道應該採用哪個人所修改的檔案作為最新版本
![image](https://hackmd.io/_uploads/rJ1c5oEG0.png)


>假設今天有兩位服裝設計師為你打造符合你的特質的打扮，兩人共同協作，但在過程中，對於其中一件配件兩人彼此看法不同，例如帽子，但是你只有一個頭，這時候我們可以決定其中一個來做最後的選擇，<font color="#f00">但在某些情況下也可以選擇接受兩個更改</font>。
>同理，在一個專案中，如果有多人合作，萬一改到相同的樣式設定，或者改到同一行 html 結構，那麼在合併分支時，Git 就會很貼心的提醒你，現在有地方發生衝突，只要我們查看後決定要留下哪一個 code ，之後再繼續提交就解決囉！

```
git config pull.rebase false
```
當遇到合併衝突時可先使用以上指令，後再使用 `git pull` 在本地端檢視兩者的變更，視窗便會顯示雙方所有的變更，讓使用者可以自行選擇要保留哪個，選擇完畢後再 `git push` 將結果推至雲端，即可完成同步


## 分支管理
上述有提及到一些分支的概念，現在整理一些常用的操作指令給大家。

---
當我們要開始一天的開發流程時，我們要先檢查目前在哪個分支，防止你在做測試功能時動到主分支，要記住主分支 (**main** 或 **master**) 上的程式一定要是能運行且最乾淨的，因此在你的功能開發到一個段落前都需要在其他 Branch 進行。

1. **分支查看**
用 `git branch` 查看目前在哪個分支 (這裡用 preparing 當作你的範例分支名)
    * *preparing  沒問題，直接開始。
    * *main 需要切換！
        * 如果分支已存在：`git checkout preparing`
        * 如果分支不存在 (開新的且直接切換到那)：`git checkout -b preparing`，注意開分支前一定要在基準的那個分支先 push。

2. **同步分支資訊**
當你的同事開啟了其他分支，但你的本地端並沒有同步。
使用 `git fetch origin`。
    ```git=
    # 更新地端的遠端索引（同步所有分支資訊，但不會改動你目前的程式碼）
    git fetch origin 

    # 切換
    git checkout <想要去的 branch-name>

    # 讓程式碼也同步
    git pull origin <想要去的 branch-name>
    ```

3. **Merge main**
開發流程應該保持分支獨立，大家在自己的 Feature branch 專心開發就好，不需要去動到別人的 Code。

    另外，main 應該被視為最新的版本進度，每天第一件事，先將遠端 main 進度同步回本地的 main，再把 main Merge 進自己的分支，如果別人的分支功能需要你修改一些程式來配合，正確做法應該是請他先發 MR 併入主線，讓你透過 main 來同步，而不是你需要隨時關注他的分支。
    ```git=
    # 1. 先確保本地 main 是最新的
    git checkout main
    git pull origin main

    # 2. 切換回你的開發分支
    git checkout preparing

    # 3. 把最新的 main 合進來
    git merge main
    ```

2. **Preparing commit**
當你今天開發完 preparing 的功能後，需要先 commit 後提交。
    * 第一次上傳新分支 (綁定關係)：`git push -u origin preparing`
        * `-u`：告訴 Git 本地的 preparing 對應到遠端的 origin/preparing，在初始上傳時要設定。
    * 第二次以後 (日常上傳)：`git push`
只要當前分支已綁定過，Git 就知道要推去哪，但要注意上傳前要確認目前是在 preparing 分支。

5. **版本回溯**
如果你先在本地開了一個新分支修改，又想回頭看先前的分支內容，記得先在你的新分支 commit 一次，否則你的那些修改都會被帶回舊分支。

3. **刪除分支**
    ```git=
    // 删除本地分支
    git branch -d localBranchName

    // 删除遠端分支
    git push origin --delete remoteBranchName
    ```


| 動作 | 是否需通知 DevOps/主管 | 說明 |
| :--- | :--- | :--- |
| `checkout -b` | 不用 | 這是個人開發空間，讓你開發新功能或修改。 |
| `git push` (到子分支) | 不用 | 只是備份到雲端，除非是要合併到 main 了 |
| **發起 Merge Request (MR)** | **要通知** | 代表「我做完了，請審核合併到 main」，系統會自動寄信通知。 |

>[!Note]補充
>* **本地專案連線遠端 (Remote)**
時機：當本地已有程式碼，要連上 GitLab 空專案時。 
指令：`git remote add origin <GitLab URL>`
(必須在專案根目錄執行)
>* **讓推上去的操作名字是你**
>要在本地專案位置執行以下操作，才能讓推上去的名字是你本人，這樣在團隊裡才能辨識。
>`git config --local user.name "name"`
`git config --local user.email "email"` 



**教學到此啦!!!!!**	🥳🥳






















