# GIT ###### tags: `工具` {%hackmd Hk1p4LZXS %} ## Git 介紹 參考:[猴子也能懂得Git入門指南](https://backlog.com/git-tutorial/tw/intro/intro1_1.html) ## 下載&安裝 * [下載頁面](https://git-scm.com/downloads) * Linux 系統直接使用 ```shell sudo apt install git ``` ## 基本設定 開啟git-bash / Linux 直接在 terminal 操作 1. 先產生 ssh key ```shell ssh-keygen ``` 2. 查看產生的 ssh key ```shell cat ~/.ssh/id_rsa.pub ``` * ==生成時,務必看清楚生成的檔案存在哪裡== * 上述指令預設使用rsa加密,有需要換成dsa時,可加入參數 -t dsa 3. 設定 git 使用者資訊 ```shell git config --global user.name "XXXXX" git config --global user.email "XXXXX@XXXX" git config --list ``` ## Git 帳號設定 1. 查看 ssh key ```shell cat ~/.ssh/id_rsa.pub ``` 2. 登入Git,在 setting 中找到 SSH key,加入先前產生的 key ![](https://i.imgur.com/dMOzAYG.png) 一台電腦對應一個 ssh key,重灌或是在不同電腦操作都要再產生並加入一次,才可以獲得上傳資料到該 Git 帳號的權限。 ## 操作教學 ### 建立專案 1. 登入後在上方選單找到 Projects > Your projects > New project ![](https://i.imgur.com/EGIuebx.png) 2. 輸入 project 名稱、選擇可視層級。 - private 只有擁有者和共享者可以查看專案 ==(一般選這個)== - internal 只要有 gitlab 帳號並登入的人都可以查看 - public 只要有連結,任何人都可以看到專案 ![](https://i.imgur.com/Vn31tgS.png) 3. 建立完成。 ### 已建立的遠端專案與本地資料夾連結 **分兩種方式** 兩種方式一開始都必須先複製專案的連結。 * 複製(紅框處的網址) ![](https://i.imgur.com/GNkzDZf.png) 接著分成兩種方法 **第一種,將本地端資料夾與遠端做連結** 1. 開啟git-bash(terminal),使用 cd 移動至要作為該專案的資料夾 2. 將資料夾初始化 ```shell git init ``` 指令輸入後資料夾下會多出一個 .git 的資料夾,意思是讓這個資料夾使用一些 git 提供的功能。 3. 將資料夾與遠端的專案建立連結。 ```shell git remote add origin git@XXXXXXXXXXXX (剛剛複製的) ``` **第二種方法,直接複製遠端的專案到本地端** ```shell git clone git@XXXXXXX (剛剛複製的) ``` 成功後會出現 master 文字,表示目前在 master 分支。 ![](https://i.imgur.com/6XGAspJ.png) ==**注意**== * **git-bash 的指令以 git 為主,不要把 git-bash 當做 CMD(terminal) 使用!!** * **git init 會在資料夾底下建立一個 .git 資料夾,若不想讓資料夾使用git 功能把 .git 資料夾刪掉即可。** ==**.gitignore, 排除不想更新至 git 的檔案**== 對於一些測試檔、測試程式或一些產出的資料,通常不希望一起更新至遠端,所以可以在資料夾內編輯一個文字檔,內容為不想加入 git 的檔案或資料夾,並命名為 ```.gitignore``` 範例如下: test、所有的 png 檔和所有的 txt 檔都不會在`git push`時一起更新至遠端。 .gitignore ``` test *.png *.txt ``` 以 `ls -la` 查看本地資料夾大概會長這樣: ![](https://i.imgur.com/SC7NLsn.png) png、txt 檔案因為有寫入 .gitignore 內,所以不會更新至遠端。 ### 修改後更新到遠端分支 ``` git add -A git commit -sm “XXXXX” # 把目前分支更新到遠端的 new_branch分支 git push -u origin new_branch # 通常第一次遠端專案還沒有任何內容時會使用下方指令 git push -u origin master # 有內容後就可以只使用 git push ``` * `git status` 檢查一下目前有哪些檔案修改過、刪除或新增 (與上一次 commit 做比較),會以紅字表示,綠色的表示已經在這次提交內容中。 * `git add -A` 將 status 所有的紅字都加入這次要提交的範圍內。 * `git commit -sm "XXX"` 提交一個名稱為 XXX 的版本並附上簽名。 單純使用 -s 會進入提交的編輯頁面,第一行為提交的標題、接著是內容敘述。 ![](https://i.imgur.com/4DPJclf.png) ### 修改最後一次 commit 名稱&內容 ``` git commit --amend -m "3455555" -m 後面是這次commit修改後的名稱 git commit 會進入文字編輯器的介面(CLI)修改後存檔 ``` ### 衝突處理 **電腦 A 修改檔案後並更新到遠端;電腦 B 仍在修改檔案** 電腦A: ![](https://i.imgur.com/BpgGspI.png) 電腦 B(修改中): ![](https://i.imgur.com/qKSmSyn.png) 當電腦 B 修改完後直接提交、更新,因為在這期間遠端有新版本,所以會導致這次的更新失敗,錯誤訊息如下: ![](https://i.imgur.com/doOGC9O.png) 這時候先 `git pull` 會看到下面的錯誤訊息,原因是同樣在第2行進行更動,但是兩個版本的第2行內容不同,所以造成了衝突。 ![](https://i.imgur.com/bvUG49j.png) 這時候檔案會長成這個樣子: ![](https://i.imgur.com/WCAAiw0.png) 發生衝突時必須又後提交的人處理、決定檔案要如何修改,這邊決定將兩者都保留。 ![](https://i.imgur.com/TlE1SOJ.png) 接著 `git add` 、 `git commit`、`git push` ![](https://i.imgur.com/nUm2Nna.png) 在 Repository 的 Graph 中可以看目前各分支、提交的情況: ![](https://i.imgur.com/o3x1Yzi.png) 電腦 A、電腦 B 這種情況通常會發生在開發不同的功能上,所以一般會使用不同分的分支進行,從圖中也可以看出其實是有出現第二條分支的,但因為兩個都是在 master 分支上進行,所以就直接進行一次的合併。 ### 新增分支 1. `git checkout -b 分支名稱`,建立新分支並切換到該分支,會發現 () 內文字從 master 變成新的分支名稱 ![](https://i.imgur.com/EsMP8Lo.png) 2. 修改檔案後 `git add`、`git commit` 3. 因為這時候遠端還沒有新的分支名稱,所以需要使用 `git push -u origin 分支名稱`,將目前分支更新到遠端的分支(若分支不存在則建立一個) **完整過程** ![](https://i.imgur.com/Ej7mH0k.png) ### 團隊開發 1. 團隊的開發使用 Group 功能,Group > Your group > New group ![](https://i.imgur.com/Tsvi5Al.png) 2. 在 Members 中加入新的成員 ![](https://i.imgur.com/sASoOOD.png) 3. 善用 Issue,作為 TODO list 。 4. Merge requst ## 操作 SOP 1. 開發到一個段落、要關閉電腦、離開時做一次提交。 ``` git status git add -A git commit -sm "XXXX" ``` 2. 每一次 `git push` 前先 `git pull` 3. 統一規範提交內容寫法,如下: 在標題簡單說明這次提交的目的並簡單描述內容,在提交的內容才詳細說明這次做了哪些工作,為了閱讀方便,說明內容通常會溝通一行 N 個字跟條列式描述,詳細描述會放在最下方。 ![](https://i.imgur.com/WYTomMe.png) ![](https://i.imgur.com/3dm6irO.png) 4. Merge ,若有發生衝突必須先處理,處理後再提交一次並更新到遠端。 ## 指令參考 ```shell= git add . 新增所有檔案 git add -u 新增修改過的部分(不包含Untracked) git add -i add的互動模式 [參考] git commit -m 'commit massage' 單行提交(不進入 vi 編輯器) git commit --amend 編輯前一次的 commit 訊息 git commit -sm "[XXX]OOO" 提交名稱 [XXX]OOO git reset 放棄 add,但保留修改 git reset --hard 放棄所有修改,回到上個 commit 完成後的狀態 git reset --hard HEAD 回到最新一個 commit 版本 git reset --hard HEAD^ 回到前一個 commit 版本 git reset --hard HEAD^^ 回到前前一個 commit 版本 git reset --hard HEAD~2 回到前前前一個 commit 版本 git reset --soft HEAD^ 回復到 commit 提交前的狀態( HEAD^ 代表前 1 次) git branch 當前分支 git branch new-branchName 依此 branch 建立新的 branch git branch new-branchName master 從 master 產生新的 branch git branch push -u origin new_branch 建立遠端 branch git branch -f branchName commit-id 把某個 branch 強制移動到某個commit git branch -a 顯示所有branch(包含remote) git bracnch -D xxxx 強制刪除xxxx分支 git checkout branch-name 切換到 branch-name git checkout master 切換到 master git checkout -b new-branch master 從 master 建立 new-branch 並同時切換過去 git checkout -b new-branch 從此 branch 建立 new-branch git checkout -b newlocalbranchname origin/branch-name 建立來自remote的分支 git checkout -- file-name 放棄對檔案的修改(未commit前) git pull 將遠端下載回本地 git pull origin master 更新遠端origin(預設)裡面的master分支到本地端 git push 送檔案到遠端 git push origin master 更新到遠端origin(預設)的remote裡面的master分支 git push remote yourbranch:master 更新某個branch到remote的master上(通常只能夠master push 到 master) git push origin local:remote push到remote git merge branchname 合併分支到目前分支 git diff branch-name 與目標分支進行比對 git stash 暫存 git stash 將修改的部分丟進暫存 git stash list 列出暫存的資料 git stash pop 取出暫存 git tag -l 列出所有 tag git tag -a tag-name -m 'tag massage' 在目前的 HEAD 建立 tag-name 的 tag,並建立 tag massage 訊息 git tag tag-name commit-id 在 commit-id 的 HEAD,建立 tag-name 的 tag git log 記錄 git log 將所有 log 秀出來 git log --graph --oneline --all 展出 branch 水管圖 git clean 清除檔案 git clean -f 刪除專案 untracked 的檔案 git clean -f -d 刪除專案 untracked 的檔案、資料夾 git clean -f -X 刪除專案 ignored 的檔 ``` <style> span.hidden-xs:after { content: ' × yenpc' !important; } </style>