--- tags: sysprog --- # Git 教學和 GitHub 設定指引 ## Git 教學影片 (中文) 1. [安裝與設定](https://youtu.be/LZ4oOzZwgrk) 2. [add 和 commit](https://youtu.be/ePaU_kS3rUs) 3. [指定 commit](https://youtu.be/SV7xK_6-Wcg) 4. [patch add 和 amend](https://youtu.be/3oIU7fG2UT0) 5. [branch 和 merge](https://youtu.be/qUfT-4bNtwY) 6. [rebase](https://youtu.be/0nwqar3ycTY) 7. [remote 和 GitHub](https://youtu.be/ucOqDIrV95s) 8. [stash](https://youtu.be/Ebccsu9tKko) 9. [patch 和 cherry-Pick](https://youtu.be/juPuEiwRvvE) 10. [bisect and blame](https://youtu.be/48eg8_qZxpo) 11. [補充資訊](https://youtu.be/zATF7hwiAGY) ## 建立 GitHub 帳號 GitHub 是個 Git repository 的託管網站,可讓開發者將自己的專案儲存到網路上,與全世界分享,我們可搭配 Git 在本機進行專案管理並發佈於 GitHub。 GitHub 同時提供付費帳號和針對開放原始碼程式的免費服務,提供如 feeds, followers 和顯示開發者們在其 repository 活動的統計圖表。GitHub 也提供類似剪貼簿的功能,issue tracker 和網頁使用 Wiki,藉由 git repository 即可對這些頁面進行編輯。 ![image](https://hackmd.io/_uploads/SkxFRqyja.png) ## 建立新 repository 在和本機的 repository 連動之前,先給自己的專案取個名字,這會是你專案之後的名字,也會是其他人搜尋你專案的時候的關鍵字,好的專案應當有個好名稱。 ![image](https://hackmd.io/_uploads/BydY0qJjp.png) 上圖是筆者新增一個叫做 "Embedded-System-Class" 的 repository,以及 Fork 課程所用的 [embedded2015/arm-lecture](https://github.com/embedded2015/arm-lecture/) 這個 repository。 ## 遞交開發端的 SSH public key 因為要讓 GitHub 知道是我們這台電腦上傳的專案,所以我們要和 GitHub 之間建立信任基礎,後者就是使用 ssh 通訊協定時的 [public key](http://en.wikipedia.org/wiki/Public-key_cryptography),我們給 GitHub 我們本機的 ssh ==public key==,告訴 GitHub 拿著這個 key 的電腦才是這個帳號的使用者, 如此一來就只能由這台電腦進行管理,才不會造成其他人來我們的帳號亂上傳東西的窘境。 * 延伸閱讀: [公開金鑰加密](https://zh.wikipedia.org/wiki/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86) (public-key cryptography; asymmetric cryptography) 首先,點選右上角的工具按鈕,進入帳號設定頁面,在頁面的左下角點選 "SSH keys" ![image](https://hackmd.io/_uploads/S1nj05kjT.png) # SSH key 產生的方法 (``$`` 開頭的表示法,就是說明在 Linux 終端機輸入命令) :::info 透過以下命令檢查是否有現存的 ssh key ```shell $ ls -al ~/.ssh ``` * 如果已有 ssh key,跳到步驟 5 * 若沒有從步驟 1 開始 ::: 1. 輸入命令 ```shell $ ssh-keygen -t rsa -C "your_email@example.com" ``` 後面那是自己申請 GitHub 所使用的信箱。之後 ssh 程式會要求輸入 passphrase 2. 直接按下 Enter 鍵即可。 `Enter file in which to save the key (/Users/[you]/.ssh/id_rsa): [Press enter]` 3. 輸入一個 passphrase,如不想輸入直接按下 Enter 鍵即可。 ``` Enter passphrase (empty for no passphrase): [Type a passphrase] Enter same passphrase again: [Type passphrase again] ``` 4. 此時顯示的是你 SSH Key 的 fingerprint ``` Your identification has been saved in /Users/[you]/.ssh/id_rsa. Your public key has been saved in /Users/[you]/.ssh/id_rsa.pub. The key fingerprint is: 0x:0f:f4:3b:ca:85:d6:17:a1:7d:f0:68:9d:f0:a2:db your_email@example.com ``` 5. 將剛剛產生的 key 加入 ``ssh-agent`` 中 若你已安裝 [Windows 版的 Github](https://windows.github.com/) ,你可在不使用 SSH Key 的狀況下,執行 clone 等操作。Windows版本同時支援許多 Git bash tool,可執行眾多的 Git 命令。 * 如果你已安裝 Git bash,輸入以下命令以啟動 ``ssh-agent`` ```shell # start the ssh-agent in the background $ ssh-agent -s Agent pid 59566 ``` * 如果你使用的是 Linux 或 [msysgit](https://msysgit.github.io/) 等軟體,則輸入以下命令 ```shell # start the ssh-agent in the background $ eval `ssh-agent -s` Agent pid 59566 ``` * 將剛剛產生的 key 加入 ``ssh-agent`` 中 ```shell $ssh-add ~/.ssh/id_rsa ``` * 如果執行 ``ssh-add`` 出現錯誤訊息: Could not open a connection to your authentication agent. 先進入 ssh bash ,就能正常執行 ssh-add ```shell $ssh-agent bash ``` 6. 到 GitHub 網站加入你的 SSH key 將 SSH key 複製到你的剪貼簿,如果你的 key 檔案名稱不為 ``id_rsa.pub``,請自行將以下程式碼中 ``id_rsa.pub`` 修改成你的檔案名稱。 ```shell $ clip < ~/.ssh/id_rsa.pub #Copies the contents of the id_rsa.pub file to you clipboard ``` * 點選工具 icon ![image](https://hackmd.io/_uploads/H1BhCqkj6.png) * 點選SSH Keys * 選擇 Add SSH key * Title 可以自己命名辨識,然後貼上 key ![image](https://hackmd.io/_uploads/SJohA5kjp.png) * 按下 Add key就完成啦! 7. 驗證你有沒有綁定 * 輸入 ``ssh -T git@github.com`` ```shell $ ssh -T git@github.com #Attempts to ssh to GitHub ``` * 你會看到這個 warning,然後輸入"yes" ``` The authenticity of host 'github.com (207.97.227.239)' can't be established. RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no) ? ``` * 你將會看到 ``` Hi [username]! You've successfully authenticated, but GitHub does not provide shell access. ``` > 上方的 username 就是你的 GitHub 帳號名稱 這樣就成功囉! ## 同步 將本地端 repository 和遠端 GitHub repository 同步。 打開空的 repository,Github 會指示你如何將本機 repository 的 remote 設定為遠端的 repository 目錄,並輸入以下命令,即可連線並把目前的 repository 同步到 GitHub 上面了。 ```shell $ git remote add origin git@github.com:你的帳號名稱/你的專案名稱.git $ git push -u origin master ``` 之後只需要輸入 ```shell $ git push ``` 即可 ## Clone 其他使用者的專案 `clone` 是一個較為特殊的稱呼方式,意思是將遠端的 repository 複製一份到本機。在本機的 repository 可以自由修改/實驗,或是針對專案所需要的改善發送 patch 給原 repository,進而貢獻此專案。 如果你有寫入權限的話 (被加入成 "Collaborators"),就可透過 SSH 通訊協定,以 git 去 "clone" 下來: ```shell $ git clone git@github.com:使用者名稱/專案名稱.git ``` 如果沒有寫入權限 (Collaborators) 的話,因為這個專案是公開的,所以你還是可以用 Git 通訊協定 clone 下來: ```shell $ git clone git://github.com/Username/repository.git ``` 若因防火牆限制 git 通訊協定的存取 (如成功大學校園環境),請改用 HTTPS 通訊協定: ```shell $ git clone https://github.com/Username/repository.git ``` ## Pull: 從遠端更新 ```shell $ git pull ``` 或 git push fatal: 目前分支 master 沒有對應的上游分支。 為推送目前分支並建立與遠端上游的追蹤,使用 git push --set-upstream origin master ```shell $ git pull origin master ``` 實際作用是先 git fetch 遠端的 branch,然後與本地端的 branch 做 merge,產生一個 merge commit 節點 ## Push: 將 Commit 送出去 ```shell $ git push ``` 或 ```shell $ git push origin master ``` 實際的作用是將本地端的 master branch 與遠端的 master branch 作 fast-forward 合併。如果出現 [rejected] 錯誤的話,表示你必須先作 pull。 延伸閱讀: * [30 天精通 Git 版本控管](https://github.com/doggy8088/Learn-Git-in-30-days) ## 若想要熟悉 Git 命令 以下是透過圖形化展現 Git 命令所產生結果的網站: * [LearnGitBranching](http://pcottle.github.io/learnGitBranching/) (有繁體中文介面) * [Visualizing Git Concepts with D3](https://onlywei.github.io/explain-git-with-d3/) ## verify commit 有些 repo 中會設定些 ruleset,需要對提交的 PR 或是 commit 做控管。 其中一項為 - [ ] Require signed commits >Commits pushed to matching refs must have verified signatures. 需要認證這個 commit 是由**本人**簽證(signed)過的,在上文中講到 ssh key 的產生以及在 Github 上新增此組 ssh key 來驗證本人身分。 但驗證密鑰(Authentication key)跟簽證密鑰(signing key)兩者目的不同。前者為**存取該 repo 為密鑰持有人**,後者在**確保 commit 是由密鑰持有人提出,而非相同 username 或是 email 的人**。 新增的方式跟上文一樣,但在 key type 請選擇 signing key ![key type selects signing key](https://hackmd.io/_uploads/Hy3MpeMQ0.png) * [GitHub Docs: About commit signature verification](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification)