參考該文章,並實做,並依序 Git 使用 - 基礎
一直以來我們都是在一個叫 master 的分之上提交 Patch,以下我們新增一個檔案並且重新建立 Git,它就會提示我們目前在 master 上
初始化 Git init 時,分支 master 也會被創建出來
分支的功能在於,任何的 Patch 都可以有自己的分支,我們可以新增刪除分支,並且平行開發不會相互引響,分支修正完成後還可以合併回 master 主分支,想要簡單測試時也可以迅速分支出來,以下是 commit tree 的概念圖
指令式、UI 圖形界面查詢兩種
指令式
可以看到目前分支在 master 上
Gitk 圖形 UI 圖形界面
Gitk 是內建於 git 的圖形化界面工具,有一些版本當安裝好 git 時它就存在了,而也一些需要使用指令另外安裝
當你提交新的 Patch 時 Gitk 並不會自己更新,必須要使 F5
刷新界面
指令 | 功能 |
---|---|
git branch | 查看所有的分支 |
git branch <new branch name> | 建立 新的分支 |
git checkout <branch name> | 切換 分支 |
git checkout -b <new branch name> | 建立 & 切換分支,將兩個動作和為一個指令 (滿好用的) |
git checkout -b <new branch name> <commit_id> | 功能同上,但是可以另外指定 Patch id,在該 Patch 上建立 (滿好用的) |
git branch -f <branch name> <commit_id> | f 是 force 強制的意思,在指定的 patch 上建立 branch,若該 branch 以存在則切換過去(轉換 branch) |
git branch -D <branch name> | 刪除 指定分支,不能在要刪除的分支上 |
git branch <new branch name> 建立新的分支
git checkout <branch name> 切換分支
使用 Shift + F5
刷新 Gitk 界面,會發現 bugFix 變粗體字(有點不明顯)
在新的分支,提交新的 Patch
在 log 中可以看到 HEAD 已經移動到 bugFix,Gitk 字體轉為粗體並且 目前所在的分支節點會呈現黃色點
在 fixBug 再次提交新的 Patch,最後移動回 master 分支上並做提交
這樣就可以從 gitk 中看出分支的差異
git checkout -b <branch name>,創建分之並切換
git branch -f <branch name> <commit_id>,在指定 Patch 上新增分支
git branch -D <branch name> 刪除分支
要先了解到 branch & HEAD 是可以分開的,我們可以單獨移動 HEAD
or Branch
Patch 的表示法
指令 | 描述 |
---|---|
git checkout <commit_id> | 移動 HEAD 的位置 |
git checkout <commit_id> 移動 HEAD 位置;HEAD 代表目前所在 patch 的位置(點)
大部分 HEAD 都會和某個 branch 重疊在一起(像是 master 分支),但仍然可以單獨移動 HEAD 的
原來的 branch 並未移動,並且會提醒目前 HEAD 所在的 Patch ID 在哪裡
使用 amend 修改目前 HEAD 的提交標題,在查分支 & log 狀況
使用 amend 後多了一個新的 Patch ID (尚未有分支,下面步驟會在創建一個分支給這次的修改)
cherry-pick 一個 Patch 進來
使用 git checkout -b <new branch name> (建立 & 切換分支,將兩個動作和為一個指令)
前面有說到單獨創建 branch 分支,而我們可以針對 branch 開新的資料夾,並在該資料夾之下創建分支
合併分支有幾種方式
方式 | 描述 |
---|---|
cherry-pick | 一個一個移動,實際上來說它並不算是合併 |
rebase | 充新定義分支的基準點,git rebase <主要分支> <將要被合併分支>,要特別注意是 誰 rebase 誰 |
Merge | 切換到 要合併的分支,再使用 git merge <將要被合併分支>,會保有原本 branch 資訊 |
新增檔案到 bugFix 分支
這是目前的分支
使用 cherry-pick 把 bugFix 分支中所有的 Patch 移動到 master 分支上
使用 cherry-pick 一個一個移動
使用 rebase 真正的合併分支到主分支(它會整理分支並合併,不會留下原本分支)
結果圖 1
結果圖 2 可以從 log 中看到 fixBug 全部移動到 master 之後了
也可以合併部份的 Patch 而不是整個分支
以下將會使用 GitHub 作為範例,所以必須要先有 GitHub 帳號
新增專案
按右上角的 +,選擇 New repository
輸入 Repository name 也可以輸入一些描述
這裡 先不要 勾選 "Initialize this repository with a README"
點擊 Create repository 就會創建出一個新專案了
創建出專案後可以看到它有兩種連線方式 SSH、Https 兩者是使用不同的加密協定,也可以看到下方有提示如何操作該倉庫的指令
在 Ubuntu 中 ssh 通常會在用戶的主資料夾中 ~/.ssh (隱藏資料夾),在該資料夾下生成 rsa 非對稱加密的 key,rsa 是非對稱加密,會有兩把 key(公鑰、私鑰),使用公鑰加密、私鑰解密
使用 man ssh-keygen
可以查看到如何生成 rsa key
生成 key 的過程中沒有特別設定就一直按 enter 就好,之後就會在該資料夾下生成公鑰、私鑰,如果之前生成 rsa key 過則會被覆蓋
在 GitHub 上設定公鑰,公鑰是每個人都可以取得的,但是單單有公鑰也無法解開通訊加密,所以可以公佈在 GitHub 上
Setting
-> SSH and GPG keys
-> New SSH key
使用 cat 查看剛剛生成的 id_rsa.pub
公鑰,私鑰不可以給別人,複製到 key 欄位並點擊 Add SSH key 儲存
測試 SSH 連線
可用 man ssh
查看 T 的操作
第一次連線它會出現無法辨別主機真實性,輸入 yes 不用特別在意
在上面新增專案後,底要有一個提示要如何使用指令 push 到倉庫中,其中就使用到了 remote
指令格式 | 功能 |
---|---|
git remote add <name> <repo_url> | 新增遠端 url 指令,並為此 url 取別名 |
git remote -v | 看所有的 remote url |
git remote rename <目標名稱> <新名稱> | 修改之前取的名稱 |
git remote remove <目標名稱> | 移除 url |
新增 url,url 可以是本地的地址,也可以有多個 url
修改名稱 rename
刪除 remove
Git 在上傳程式碼到 server 時,必須是以分支為單位
指令格式 | 功能 |
---|---|
git push <url 別名> <分支名稱> | 上傳分支 (不須 checkout 到指定分支上傳) |
git branch -a | -a 也就是 –all,可以查看所有的分支,包括遠端分支 |
git log <分支名稱> | 可以透過 log 指令查看指定分支的 log(包括遠端) |
上傳分支 git push <url 別名> <分支名稱>,指定我們剛剛建立的 url 別名,還有需要上傳的分支
查看分支實會看到遠端分支(紅色字),如果遠端沒有 master 這個分支時就會自己新增
網頁重整就可以看到 master 分支
在 gitk 這個 UI 界面也可以看到遠端分支,遠端分支的內容會與 server 上的內容一致
查看遠端分支 log
上傳分支 bugFix 分支(我刪除了舊的合併 bugFix 分支,並且建立新的 bugFix 分支,該分支建立在某個 Patch 上)
上傳前後在 gitk 的比較
網站刷新後就會看到新的 branch
更新 master branch,先更新本地端的 master 分支(新增 Patch)
前後對比上傳前後遠端的差異
參數 -u
等同於 --set-upstream
,設定 upstream 可以使分支開始追蹤遠端分支,使用 git status 時就會 Git 就會比較遠端 & 本地的 commit 差異
只需要一次 git push -u <遠端分支名> <本地分支名> 成功後,之後只需要使用 git push 就可以直接上傳分支
指令 | 功能 |
---|---|
git push -u <url\ 別名> <本地分支名> | 上傳並設定分支 upstream |
git branch -u <url\ 別名>/<遠端分支名> | 設定遠端 upstream,使用 git status 會顯示追蹤的訊息 |
git branch –unset-upstream | 取消追蹤遠端分支 |
git push -u <遠端分支名> <本地分支名>,遠端分支名 可以使用 remote -v 查詢
git branch -u <url 別名>/<遠端分支名>,設定遠端 upstream,git status 就會改變
git branch -u gitHub/master master 可以合併指令,這樣就不用切換到 master 分支去操作
Your branch is up to date with 'gitHub/master'
代表本機端的 master 與遠端的內容分支一致
本地新增移除 Patch,讓遠端 master & 本地 master 發生差異
Your branch is ahead of 'gitHub/master' by 1 commit
代表目前本地分支領先遠端 gitHub/master 分支一個 Patch
Your branch is behind 'gitHub/master' by 2 commits, and can be fast-forwarded.
代表本地分支落後遠端 gitHub/master 分支 2 個 Patch
git branch –unset-upstream
在 github 上可以透過 clone 找到遠端 https or ssh 的下載連結
指令 | 功能 |
---|---|
git clone <遠端 url/> | 下載專案 |
git clone <遠端 url/> -b <branch name> | 下載指定分支 |
git clone <遠端 URL> <folder name/path> | 下載到指定位子 |
git clone <本地 project> | 建立專案副本 |
remotes/origin/HEAD -> origin/master
,remotes/origin/HEAD
是專案的預設分支,而後面指向的是預設分支 master
git remote 預設名稱為 origin (git remote rename 可以修改名稱)
當遠端已經被其他人更新時,會發生自己的 Patch 無法 push 上去,會產生衝突而導致 rejected (如下圖)
指令 | 功能 |
---|---|
git fetch <remote name>/<remote branch name> | 更新 "指定" 分支,fetch 後可以在 gitk 上看到遠端的更新 |
git fetch –all | 更新所有的分支 |
git remote update | 相當於 git fetch –all 的功能,它會更新所有分支 |
git pull <remote name & bramch> <本地 branch name> | 同步分支,預設使用 merge |
git pull –rebase <remote name> <本地 branch name> | git 使用 rebase 來解決衝突 |
首先先在 remote 端,也就是 github 上手動添加一個 RemoteFile2 檔案
添加後的 GitHub 顯示
在本地添加一個檔案 three.txt
,並提交一個 commit,最後一起推送
因為更遠端不同步,所以產生衝突,被遠端拒絕(rejected)
執行 fetch
:發生衝突後第一件事,是 fetch 遠端 Git
使用 fetch 後,再用 gitk 就可以看到遠端的差異 (很丑不好看)
執行 pull
:同步分支,將遠端資料與本地資料同步(這過程可能會稱圖)
本地 diverged(發散),有一個不同的 Patch,並且它會提示要使用 pull 更新
由於發生版本衝突,必須手動解決 (默認使用 Merge),以下由於沒有改動到相同文件,所以直接儲存退出
解決完稱衝突後
Gitk 差異,可以看到它會產生 Merge Path (又稱為 Merge History)
查看 log 可以看到 Merge branches 資訊(以下是 merge 本地端 master & remote 端 master)
衝突也可以選用 rebase 解決
衝突使用 rebase 解決,它將本地 master 重新 rebase 到遠端之後
執行 push
:別忘了我們之前在本地鎖新增的 four.txt
這個 Patch,記得把它 push 出去
在 Git 上我們就可以看到 four.txt 這個檔案
Gitk 上也更新遠端到 master,同步完成 !
指令格式 | 功能 |
---|---|
git blame <option> <指定檔案> | 可以追溯指定檔案,該檔案中的更改紀錄 & 更改者 |
緩存尚未 Commit 之前的所有資料,add 前、後的也可以,不包括未追總檔案,這個指令十分的方便,可以在任何時候存入,並放入你所需的檔案中(中途 checkout 放置到其他的 Patch 也可以)
指令格式 | 功能 |
---|---|
git stash | 儲存一個暫存資料,並回復為上一次 Patch 並未改動的狀態 |
git stash list | 查看所有 stash |
git stash apply <指定 stash or 不指定> | 拉出 stash 套上目前的 Patch,並未刪除 stash |
git stash pop 指定 stash or 不指定> | 拉出 stash 套上目前的 Patch,並刪除 stash |
git drop <刪除指定 stash> | 刪除指定 stash 紀錄 |
git stash clear | 清除所有 stash |
添加新檔案 & 改動
儲存暫存檔案
無法儲存未追蹤檔案(Untracked files)
套用 stash:以下使用 apply(不刪除 stash)
刪除 stash
在需要的地方添加標籤 tag,這個 tag 也可以使用 gradle 獲取,它的功能與 branch 很像,但是差異是在 branch 可以不斷更新,Tag 無法更新,通常使用在正式版的本的 master Patch 上
指令格式 | 功能 |
---|---|
git tag | 查看所有的 Tag |
git tag <tag name> <commit id> | 打標籤在指定 Patch 上 |
git tag -a -m <描述字句> <tag name> <commit id> | 功能如上,但是添加了 Message 訊息在 tag 上 |
git tag -d <tag 名稱> | 刪除指定 Tag |
git push –tags | 推送 全部 Tag |
git push <url 代稱> <Tag 名稱> | 推送指定 Tag 至 GitHub |
建立 tag
在 gitk 上面也可以看到新增了 tag
Message Tag
刪除 tag
推送 remote Tag
刪除 remote Tag,刪除遠端必須先刪除本地標籤
學習如何在本地創建一個 git 本地倉庫 (當前環境在 Ubuntu)
首先當然是要有 git 對應套件
我們在 /opt
目錄下創建一個 git 目錄,再創建一個自己的目錄
opt 目錄 (Ubuntu目錄介紹)
默認為空目錄,給主機而外安裝軟體所擺放的目錄
為了讓遠端當檔案可以被寫入,有兩種方法 (則依即可)
將該目錄底下的資料夾內容全部改為可執行
改變該目錄所屬者
安裝 ssh 套件
創建本地 ssh key
測試 ssh 服務是否開啟
若 ssh 沒有啟動則使用指令啟動 ssh (也可以使用 systemdctl 來啟動服務)
在本地做一個簡單的 git 提交
添加遠端 remote 地址
本地 ip 預設是 127.0.0.1
,若要查詢的話可以使用 ifconfig 指令
儲存本地網路對應的地址
push 本地 git 到自己建立的本地遠端;成功透過 ssh 上傳資料到本地倉庫
Git