Yakim shu Hi, 這是我擴充腦內海馬體的地方。

[第一週] 版本控制 - 進階指令 & GitHub

根據上一節學到 GIT 基本版本控制,都是處於線性的開發流程,每次 commit 的新版本都是基於上一個版本的修改,這樣單人作業的時候可能不會有太大問題,但當多人協作、或同時要開發不同功能時,可能就會有衝突產生。


沒有 branch 會怎麼樣

來看 Huli 舉的案例:

  1. 公司上線的產品: 穩定版
  2. 近期在開發一個新功能,但只開發到 50% :
    • 穩定版穩定版 + 開發新功能(50%)
  3. 客戶突然傳來有個嚴重的 bug 要修:
    • 穩定版 + 開發新功能(50%)穩定版 + 開發新功能(50%) + 修 bug

因為要修 bug 很急迫,把 (3.) 的版本拉上線,但因為參雜了未完成的新功能,想必是會有更多問題。

有了 branch 會怎麼樣

為了解決以上問題,branch 的作用是讓 開發過程各自獨立、簡單一點。開發新功能 獨立出來變成支線、 修 bug 也是一條支線。

當客戶催著工程師快點修好上傳,就只需要上傳 穩定版 + 修好 bug新的穩定版,至於 開發新功能 這條線想像成離家出走了,開發完就可以回家合併更新的穩定版

有了好用的 branch,修改上個案例:

  1. 公司上線的產品: 穩定版
    • 有三條支線:
      • branch_main_穩定版 主要支線
      • branch_1_開發新功能 獨立成一條支線
      • branch_2_修bug 獨立成一條支線
      • 螢幕快照 2019-04-17 下午12.16.55
  2. 當客戶催著工程師快點修好上傳:
    • branch_main_穩定版 + branch_2_修bugbranch_main_穩定版(v2)
    • 螢幕快照 2019-04-17 下午12.21.00
  3. 新功能可以慢慢開發、等完成了再合併
    • branch_main_穩定版(v2) + branch_1_開發新功能(100%)branch_main_穩定版(v3)
    • 螢幕快照 2019-04-17 下午12.25.26

正式跟 branch 做朋友

有了對 branch 的基本概念,來開始打有趣的指令吧!(有趣嗎?)

操作 branch

如果還沒有新建 branch,系統預設的 branch 就叫做 master


branch -v : 查看當前 branch ( 看你在哪個平行時空 )

( 表示我在 master 支線最新的 commit 碼(前 7 碼)最新的 commit message


自己覺得 branch -v 有點像把 門牌號碼 列出來

螢幕快照 2019-04-17 下午1.59.09


branch <branch-name> : 新建一個 branch ( 新開一個平行時空 )

(啊哈) ( commit 號碼commit 訊息 沒有變,因為中間我沒有新的 commit )


branch -d <branch-name> : 刪除 branch ( 關閉一個平行時空 )

螢幕快照 2019-04-17 下午1.12.40


git checkout <branch-name> : 切換 branch ( 跳耀時空的少女 )

* 當前 branch 被高亮顯示! )

可以把 git checkout 當成拜訪不同的 門牌號碼,也因此會得到不同版本的檔案


重頭戲: merge 合併分支

講了這麼多都在鋪陳 branch 的作用,但 branch 支線 最終還是要 merge 合併成 master 主線,所以在討論如何 merge 之前,先釐清一個觀念。


以下由我自己胡亂設定的故事理解,但不確定對不對


那加強老大惡勢力的步驟應該是:

螢幕快照 2019-04-17 下午2.54.17

以下是 log 內容,可以看到小弟的 commit 訊息有在合併後的老大支線

螢幕快照 2019-04-17 下午2.55.56


重頭戲之二: conflict 發生衝突了啊啊啊啊啊啊啊

這是之前我個人的惡夢,每次遇到衝突就胡搞瞎搞,使用第三方套件的情況下,解決的辦法就是按一按衝突的位置,看能不能改掉再 commit 一次。

看完這堂課才有「啊~原來就這樣而已麻」,人果然很容易對未知的領域感到恐懼。

先了解衝突是怎麼發生的,以詞義來說,聽起來好像是個 錯誤,以前是這樣理解的,所以容易感到很不安。

不過其實就是「 同一個檔案的兩份版本,裡面有一個多個不同的內容 」

而電腦無法幫你選擇哪一個當作最終版本,因為只有你自己知道想要留下的內容是什麼,所以當發生衝突時,只能自己手動編輯


首先為了解決衝突,先故意製造一個衝突

螢幕快照 2019-04-17 下午3.50.35

現在我們要試著手動修改檔案、解決衝突,打開編輯器會看到衝突的位置被清楚標示,視不同編輯器會有不同高亮效果,但有衝突的位置應該都會用 ====== 分隔線隔開。 ( 此圖是用 VS Code 開的 )

螢幕快照 2019-04-17 下午3.44.09

最後我希望的內容是兩邊都各留一點,再加上新的內容,然後記得刪除 提示文字 再存檔。

提示文字指的是:=====<<<<<<<< HEAD>>>>>>>>>> new-feature

螢幕快照 2019-04-17 下午4.03.39

( 其實這圖不是很重要,就只是看你檔案要保留什麼內容而已。 )

衝突修好了、開啤酒慶祝!

把有衝突的檔案改好了,只要再把修好的檔案再 commit 一次就成功啦!ya~


Git VS GitHub

以上學了那麼多,應該知道 Git 就是一種版本控制的程式

GitHub 可以想像成「 提供存放使用 Git 專案倉庫(Repository) 的服務 」,你也可以不要用 GitHub、自己架一個 Git Sever。

意思是就算我們的專案用 Git 做版本控制,也不一定要上傳到 GitHub 作為託管;但如果專案放在 GitHub 上供多人協作開發,代表此專案一定有使用 Git 做版控。

GitHub

世界上最大的程式碼存放網站和開源社群。

當我們把專案傳到 GitHub 上,因為是 GUI 介面,就可以很清楚的看專案的 Commit 紀錄、檔案修改的歷史過程、修改者是誰…等等的資訊,都可以在倉庫 repository 的頁面找到。

Pull request

想像成在 GitHub 上執行 merge 的動作,就是 pull request 。

因為在本地端 merge 的時候,其實不好查看檔案的差異,所以大家習慣是在 GitHub pull request 進行合併。

Issue

專案的討論區,有問題可以在上面發問及回答。


曾經碰到的問題 - 上傳專案到 GitHub

螢幕快照 2019-04-17 下午6.03.12

這裡遇到問題了,當我要上傳本地專案到 GitHub 上,按照網頁的指示,應該輸入這兩行指令就行了。

但當我輸入 git push -u origin master ,會出現錯誤訊息:

螢幕快照 2019-04-17 下午5.47.37

照理來說這應該是沒有權限才會出現的問題,但明明我的帳號啊? 查了一下好像是沒有建立 SSH 公鑰(到底公鑰還私鑰,永遠搞不懂QQ)

一開始有點惶恐,因為 官網文件 列出來的可能因素很多、看了頭好痛,最後找到這個 知乎回答,按照步驟生成 public key,再回到 GitHub 網站上的設定、新增 SSH ,就解決啦!太好了~


與 GitHub 相關的操作指令

push: 推上 repository

pull: 從 repository 拉下來

clone: 從 repository 複製一份

fork : 從 repository 複製一份成為自己的 repository


GitHub flow

GitHub 建議管理專案的流程: 官網說明

所以如果你在 GitHub 看到有興趣的專案,想要參與貢獻:


狀況劇

Q: 可以改 commit message 嗎?

A: 使出 git commit --amend

但如果已經 push ,就盡量不要改,所以保持好習慣,push前都先檢查沒錯再推上去。

Q: 哎呀!還有個東西沒改到,可以放棄剛剛的 commit 嗎?

A: 使出 git reset HEAD^

HEAD 其實就是最新的 commit ,而 ^ 是指上一個,所以 git reset HEAD^ 指的是回到上一次 commit。也可以直接加 commit hashes 碼:git reset <commit hashes>

Q: 哎呀!把東西搞壞了,不過我還沒 commit,可以回復到上次 commit 的狀態嗎?

A: 使出 git checkout -- <file>

上例是改單個檔案的做法,如果想把整個專案的所有檔案都復原:git checkout -- .

Q: 可以改 branch 名稱嗎?

A: 先切換到要改名的 branch 下,使出 git branch -m <new-name>

Q: 要怎麼拉下遠端的 branch?

A: 超級簡單又神奇,在本地端使用 git checkout <branch-name>,本來不存在的 branch 就會從遠端拉下來了


Git Hooks

蠻有趣的功能,意思是說你可以自訂腳本、客製化「 在 某些事件發生 時會 觸發你寫好的腳本 shell 」

舉例來說,像是你可以規定,再提交 commit 之前,先檢查程式碼有沒有符合團隊規範、或是有沒動到一些不能動的檔案等等。

參考資料: Git 客製化 - Git Hooks


( 以上內容大部分是 程式導師實驗計畫第三期 的學習筆記,如有錯誤歡迎糾正,非常感謝 🤓 )