---
# System prepended metadata

title: Git and Github
tags: [Note]

---

# Git and Github

## Terms
* Directory -> 資料夾
* Terminal or Command Line -> 終端機
* CLI -> 終端機介面
* cd -> 切換資料夾
* Code Editor -> 程式碼編輯器
* Repository -> 放專案的地方 - 資料庫
* Github -> 在網路上放資料庫的地方

## Git Commands
* clone -> 可以將github上面的專案用clone的方式下載到local的電腦上
* add -> 可以追蹤有哪些檔案被替換掉了
* commit -> 將修改過後的資料存起來到git
* push -> 上傳commit過的東西到github上面
* pull -> 將更改過後的東西下載回local的電腦中

## Flow
* `git clone "git clone https"`
    若是使用ssh，會出現因為沒有辦法驗證身分而沒有辦法clone
* `cd "repository name"`
* `git status`
    可以用這個指令來看說目前git的狀況，若是有修改的檔案，會在 **modified:** 裡面看到。若是新創的檔案，會在 **new file:** 裡面看到，若是沒有commit過的檔案會是紅色的
* `git add .`
    要先告訴github有哪些資料要commit，因此需要做add，後面的 **.** 代表說要將全部的檔案加入commit的列表中，也可以只將想要commit的檔案一個一個加進列表中，做完這一步之後使用`git status`，就會發現原本是紅色的字變成綠色的
:::warning
`git add -A`和`git add --all`是可以強制將全部的檔案都add
:::
* `git commit -m "title" -m "describtion"`
    需要告訴git這次commit的東西是什麼，因此要打上title告訴git可能是修改了什麼，或是創建了什麼，再使用一次 **-m** 就可以加入副標題
:::warning
若是第一次使用github的時候，再commit的時候會不知道使用者是誰，因此會需要兩個指令來告訴git信箱跟名字
`git config --global user.email "Your E-Mail"`
`git config --global user.name "Your Name"`
:::

## Git push
由於要將資料推上github，因此這邊需要ssh的認證，需參考以下連結
[Generating a new SSH key and adding it to the ssh-agent](https://docs.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
* 打開git bash
* `ssh-keygen -t ed25519 -C "your_email@example.com"`
    會出現`> Generating public/private ed25519 key pair.`
* `> Enter a file in which to save the key (/c/Users/you/.ssh/id_ed25519):[Press enter]`
    直接按enter
* `> Enter passphrase (empty for no passphrase): [Type a passphrase]`
    `> Enter same passphrase again: [Type passphrase again]`
    密碼這邊可以不填
* Adding your SSH key to the ssh-agent
* 在git bash輸入以下指令
    ```
    # start the ssh-agent in the background
    $ eval `ssh-agent -s`
    > Agent pid 59566
    ```
* `ssh-add ~/.ssh/id_ed25519`
    將私鑰存到自己的電腦中
* [將ssh加入到github的帳號中](https://docs.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account)
* `git push origin master`
    可以將專案推到github上面
## 新專案
* `git remote add origin [ssh_github_repository]`
* `git remote -v`
    會顯示所有remote的列表
* `git push -u origin master`
    加上 **-u** 可以不用每次都加上origin master

## Branch
* `git branch`
    可以查看分支有哪些
* `git checkout -b feature-readme-instructions`
    **-b**是branch的意思，這一行指令是說要創建一個"feature-readme-instructions"的分支
* `git branch`
    在下一次指令就會看到
    ```
    * feature-readme-instructions
      main
    ```
    星號是代表現在的分支在哪
* `git checkout main`
    將分支切換回main
* `git checkout feature-readme-instructions`
* 這個時候我們修改readme的檔案
* `git status`
    會知道現在修改了readme的檔案
* `git add README.md`
    將readme加入修改的行列
* `git commit -m "update readme"`
    下commit
* `git checkout main`
    切換回main之後會發現新增的東西都不見了
* `git diff feature-readme-instructions`
    這行指令可以知道現在的分支跟所選的分支的差別
* ` git push --set-upstream origin feature-readme-instructions`
    這行是要將目前的東西推上github的時候，因為github沒有這個分支，因此要創建一個新的分支。 **--set-upstream** 跟 **-u** 是一樣的概念，就是之後可以不用在打後面的指令。再來可以利用github的介面來merge新東西。
* `git checkout main`
* `git pull`
    將在網頁上面更新好的東西下載到main裡面
* `git branch -d feature-readme-instructions`
    把新創的分支刪掉 **-d**
* `git push origin --delete feature-readme-instructions`
    git刪除github上分支 

### 這時候提出一個概念，在修改分支的時候，主線也被修改了，要怎麼merge
* `git checkout -b quick-test`
    創建一個quick-test的分支
* `git status`
    修改index.html這個檔案
* `git diff`
    檢查修改了什麼
* `git commit -am "added world"`
    **-am** 這個指令的意思是a是add，m是massage，這個只能應用在修改的檔案中，新增的不能使用
* `git checkout main`
* `git checkout quick-test`
    切換到main之後，如果修改了東西，要先commit才能夠再切換分支，要不然東西會被蓋掉
* `git commit -am "added there"`
* `git checkout quick-test`
* `git diff main`
* `git merge main`
    這個時候會發現文字編輯器裡面會顯示說是否要保留新東西，還是要留舊東西，這裡可以把預設的東西刪掉，自己修改需要的東西
* `git commit -am "updated with master"`
    將新東西commit起來

## 取消或是還原git
* `git reset`
    可以將目前已經add的東西取消
* `git reset HEAD~1`
    可以將已經commit的東西取消
* `git log`
    可以看到git的紀錄
* `git reset --hard [commit]`
    加上`--hard`是強制還原到某一個版本，並且取消掉目前版本的東西
    [commit]的東西是要從`git log`裡面來找
* `git push -f`
    由於還原舊版本在推上去的時候會有通知說不能推舊的版本，所以要強制推上去
    
###### tags: `Note`

