# 簡易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就是開一個新的空間去存一個專案的概念。 * ![](https://i.imgur.com/P9k2kgn.png) ## 本機?伺服? * 本機端指的就是你電腦正在開發的專案版本,而伺服端就是目前在Git上的版本。 * 本機端可以有很多個、代表有很多個人在開發同一個專案,但他們都應該上傳到同一個伺服端。 ## 新建專案 * 先在GitHub上面新增一個資料庫。 * ![](https://i.imgur.com/OTlbOgd.png) * 然後在你電腦想放檔案的地方建一個新的資料夾,並右鍵執行Git Bash。 * ![](https://i.imgur.com/FOn6K9X.png) * 先回到GitHub,找到你剛剛新增的資料庫,裡面有個**Clone or download**,將裡面的URL複製起來。 * ![](https://i.imgur.com/f7XwC8f.png) * 再回到Git Bash,輸入`git clone [剛剛的Url]`。 * ![](https://i.imgur.com/SYH5hGO.png) * 注意一下,Git Bash的複製貼上快捷鍵可能不一樣。 * 按下Enter之後,等它跑出`done`,應該就可以在資料夾看到你Clone下來的專案了。 * ![](https://i.imgur.com/4ShMoQx.png) * 到此為止,你已經完成新建一個專案了。接著你只要在新跑出來的資料夾裡面,開始你的作業即可。 * ![](https://i.imgur.com/d7CbD0p.png) ### 如果我已經有專案檔或code,而不是從頭開始,我要怎麼辦? * 你一樣先在GitHub上建立一個新的資料庫,一樣在電腦裡Clone。 * 出來新資料夾之後,在把你原有的檔案複製到資料夾內即可。 * 記得要進行下面的更新,GitHub才會有東西喔。 ## 更新專案 * 今天我已經修改的我的文件(範例為main.cpp,你可以是任何檔案,包含專案檔),但是我看GitHub上面並沒有改變阿? * ![](https://i.imgur.com/DRx7dLk.png) * 那是當然,因為你需要進行`Push`。也就是將你的檔案推上Git。 * 要進行`Push`,先找到你的資料夾,一樣右鍵開啟Git Bash。 * ![](https://i.imgur.com/7UVKje5.png) * 確認路徑是你放檔案的地方,結尾應該要有分支名稱(新建的話就是master)。 * 確認無誤後,輸入以下三行: * ![](https://i.imgur.com/K63og5G.png) ```git git add . git commit -m [你修改了什麼] git push ``` * 這時候已經完成`Push`。到GitHub去看也確實更新上去了。 * ![](https://i.imgur.com/VlxVOEp.png) ### add, commit and push? * 這三行到底分別是幹嘛? * 你可以想像今天伺服端和本機端是兩塊大陸,你想要把檔案從本地端更新至伺服端,必須開船過去。 * add指令是將檔案加入到一個清單,清單決定那些檔案要放到船上。 * add . 代表所有有更動的檔案都加上去。 * commit則是真的把檔案搬到船上。 * push是船真的開出去,將檔案真正運到伺服端。 ## 分支——多線開發 * Branch是一個重要的技巧,不僅在多人開發中會使用,即使單人開發也強烈建議使用Branch。 * 今天你如果只是像上面教的,有修改就push,這樣你和使用Google Driver好像也沒什麼差別。 * 分支的概念是push的時候,不要都push到同一個地方,而是對不同功能的開發push到各自的分支。 ### 範例一:假設多人共同合作開發一款遊戲: * 寫敵人的就都push到上面的分支。 * 寫地圖的就都push到中間的分支。 * 寫道具的就都push到下面的分支。 * 最後再把大家的code merge起來。 * ![](https://i.imgur.com/5SJbvJq.png) * 好處:我寫敵人的時候,可能中間要push好幾次檔案,如果都push在同一個分支,我push一次就得整合一次大家的code;改成多個branches,變成大家都開發完畢之後,merge最後一次就好了。 ### 範例二:同一個事情我有兩種演算法: * 今天一個function我有兩種想法,但我不知道哪一種比較好。 * 我可以先寫第一種,寫完之後push到branch 1。 * 接著寫第二種,push到branch 2。 * 實測完哪一種比較好之後,再決定master要merge哪一邊的code。 * 好處:我不必把兩種演算法擠在一起測試,也不必為了做第二種演算法先把第一種刪掉。且不論我最後選了哪個,兩種演算法都有好好記錄起來。 ### 使用branch * 要新建一個Branch很簡單,一樣打開Git Bash之後,輸入以下指令: * ![](https://i.imgur.com/DxiAVLd.png) ```git git checkout -b "分支的名字" ``` * 這樣就成功新建並切換到一個新的分支了,接著我將我的檔案做一點修改,然後push上去測試看看。 * 你可能會發現push不上去,那是因為你剛剛新創了一個branch,要先把branch推上去才行。 * ![](https://i.imgur.com/oouWWN7.png) * 因此我們將指令`git push`改為`git push --set-upstream origin newBranch`。 * ![](https://i.imgur.com/A0m4RQt.png) * 這時候就順利完成了,去GitHub看也有看到新的分支。 * ![](https://i.imgur.com/6IfF9fp.png) ## 回到上一個版本 * git中有許多版本控制的功能,在這邊來教一個最基本的功能:**回到最新提交的版本**。 * 今天假設我修改了我的code,然後發現整個專案炸裂,而且我不知道該從何下手去修正它: * ![](https://i.imgur.com/jzqGDFB.png) * 這個時候打開你的`Git Bash`,輸入`git reset --hard HEAD`。 * ![](https://i.imgur.com/xxVP48U.png) * 再回去看你的檔案,會發現它已經回到你最新一次commit的結果了。 * ![](https://i.imgur.com/I19AGoV.png) ### 關於版控,更多內容 * 那如果今天你一不小心,已經將爆炸的版本push上去了,那要怎麼辦呢? * 上述的`HEAD`是一個指向最新版本的指標,因此你可以用指令`git reset --hard HEAD~n`(`n`為數字),來回到上`n`次的版本。 * 如果你不知道哪個版本是哪個,可以用`git log`來看你所有提交歷史: * ![](https://i.imgur.com/H9i8zPI.png) * 之前的範例提交太少次了,隨便找了一個專案來當作範例。 * 你可以發現,除了時間可以當作你判斷檔案的依據之外,就只能看你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`