Git 五倍紅寶石 - 高見龍 aka Eddie === ## 人生不能重來 但是Git可以(入門篇) ### 上午課程 [高見龍](https://kaochenlong.com) aka Eddie @eddiekao * 紅寶石鑑定家 * [為你自己學 Git](https://gitbook.tw) 關於Git * 不分程式語言 不分前後端 必備技能 為什麼學不好 * 情境跟指令搭不起來 * 基本認知有錯 把它當FTP在用 ![](https://i.imgur.com/kfZGxjq.png) 大部分的人都不知道怎麼做檔案備份 更有效率的備份工具 - 版本控制系統 (ver. control) 方式跟網路上的芳鄰不一樣 備份 * 就像遊戲存檔一樣 歷史紀錄與證據 * 出事的時候會知道從什麼時候開始就有問題 你有聽過Git嗎 * 分散式的版本控制系統 * 分散?版本? 版本 * 人生可以重來 * Days Time line 分散式 * 請搜尋 OK,好 ... * 分散式是檔案可以互相交換,不需要靠伺服器 CVS * subversion SVN 沒有網路就不能寫code? * github壞掉的時候大家都會開玩笑的說可以下班了 * we're having a really bad day.(獨角獸) SOD - Stack Overflow Developer GIt簡介 * Git是眾多版本控制軟體的其中之一 * 是目前業界最多人使用的版控軟體沒有之一 * Git就像是檔案的時光機 * 可以讓檔案回到指定的時間點 * 知道每一行程式碼在什麼時間寫的 Linux Torvalds * for managing linux kernel source code in 2005 * only 10 days (1 day for prototype) GitHub * logo是用買的 * git != github Git優點 * 開源,免費使用 * 速度快檔案小 * 同時支援本地及遠端操作 * 容易與其他人共同協作 (前提:讓大家Git怎麼用) * 是一種容易學不容易精通的工具 * 80/20法則 20%的指令就足以應付平日80%的工作 * 今天就是要介紹20% 安裝Git * 菜市場阿龍? 其實是個Wi-Fi * GUI GitHub - An Chiou(嘖嘖) * TortoiseGit 小烏龜 * GItKraken 夜店風 要用終端機指令還是圖形介面軟體 * 練習的時候用終端機 * 用的時候用圖形軟體 Vim * 神奇活過好幾十年的軟體 * 密室脫逃軟體啊 * stackoverflow各種發問如何離開 * 很討厭的軟體 * Git預設的編輯器 * 參考[超簡明Vim操作介紹](https://gitbook.tw/chapters/command-line/vim-introduction.html) 仔細看終端機的輸出結果 設計基本資料 * git config --list | grep user * git config --global user.name "yy" * git config --global user.email "xx@104.com.tw" ### 初始化 cd /tmp mkdir git-demo * 終端機常用指令介紹 git init #### .git就是所有的精華 * 工作目錄 Working Directory * 暫存區域 staging * 儲存庫 repository | 示意圖 | | -------- | | 工作目錄 | | git add | | ↓ | | -------- | | 暫存區域 | | git commit | | ↓ | | 儲存庫(本地) | | -------- | | ↑git push/pull ↓ | | 儲存庫(遠端) | * 檔案並不是被放到某個目錄 * 比較像是記錄狀態的改變 ### 工作目錄送到暫存區域 1. 新增index 摸/搓一下聽過嗎 touch index.html 2. 檢查狀態 git status 3. 加入暫存區域 git add index.html 4. 新增hello 和 world 指令同上 ### 暫存區域送出 git commit -m "init commit" * 算完成存檔 #### 小功課 還有一個檔案還在外面 (world) 試著做 --- pull request 326 files changed ![](https://i.imgur.com/3p3ticf.png) commit的訊息不要亂寫 * 例子:git commit -m "#34 bug fixed" 什麼時候需要進行commit? ### 檢查紀錄 git log git log --oneline 按Q離開 圖形介面軟體方便使用 ### 練習題 1. 請試做兩次 新增hello.html並commit 修改原來的index.html並commit 2. 想想看 為什麼bug fixed或是update這樣的訊息不是好的訊息? Git小劇場 * [範例檔案](https://ubin.io/git-files) ### 不小心把目錄或檔案刪掉怎麼辦 open . 然後刪掉檔案 or rm command git status git checkout hello.html hello又長回來了 git checkout . 所在目錄全部回在上一個點(最近一次的commit) ### 指令危險性蠻大的 例如 一個檔案刪除(welcome) 一個檔案編輯(hello) 理論上應該打 git checkout welcome.html 但是打git checkout . 是救不回來的 ### 練習題 把某一個檔案刪掉再用git checkout就回來 #### .git 接專案的時候,把.git留下來只交原始碼 你得的到我的肉體 得不到我的靈魂 #### 系統炸掉了,什麼時候多了一行程式碼?抓戰犯 git blame index.html git blame -L 8,10 index.html 很常會blame到自己... 1995大量程式語言出土 如果只想要看某個特定檔案的歷史紀錄 git log -p filename * +新增 * -刪除 GUI 1. 檔案 log selected 2. 目錄 annotate selected ### 為什麼要使用分支 片名:關鍵下一秒(Next) - 超能力可以看到不久的將來 <iframe width="560" height="315" src="https://www.youtube.com/embed/MhK34LGXHvE" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> ### 什麼時候要使用分支 一開始就有一個內建的master分支 git branch commit之後才有分支 ### 分支是什麼? #### 鐵軌? ![](https://i.imgur.com/lUaI8Ls.jpg) #### 樹枝? ![](https://i.imgur.com/HAWOSEW.png) #### 不是~ * 分支長得像貼在某個commit上的貼紙 * 分支只是一張貼在某個commit上的貼紙 1. git branch cat 翻譯蒟蒻:我要新增一個cat分支 在目前head所在地貼上cat貼紙 就這樣沒別的變化 也不會長出甚麼分支形狀 * 如果head指向master * 現在正在master分支上 2. git checkout cat 翻譯蒟蒻:我要切換到cat分支 head移動到cat貼紙 專案變成cat貼紙指到的commit狀態 在這時候其實跟master是一樣的 --- ### 下午課程 git commit -m "add cat 1" 翻譯蒟蒻:我要進行一次存檔 1. cat貼紙與head往前移動 2. 其他分支貼紙留在原地 3. 如果再做一次commit的話...... 貼紙會往前貼 toych cat1.html git add cat1.html git commit -m "add cat 1" toych cat2.html git add cat2.html git commit -m "add cat 2" stree . 就像貼紙的概念一樣,master並沒有動,cat往前移動 ### Git的分支模型一定要理解 分支合併 git checkout cat git merge cat git checkout master 翻譯蒟蒻:我要切回分支 1. head移動到master貼紙 2. 專案會變成master貼紙指導的commit狀態 git merge cat 翻譯蒟蒻:我要合併cat分支 1. master與head移動到cat貼紙的所在地 2. 快轉(fast-forward)合併 git checkout master ls -al //貓不見了 git checkout cat ls -al //貓出現了 合併分支可以看成是移動貼紙 git checkout master git merge cat 貼紙在一起 ### git的本體是commit,分支什麼的都只是浮雲 #### 複雜一點的分支 為什麼我的分支沒有小耳朵 如果各自長大的話 情況就不一樣了 git branch dog git checkout dog touch dog1.html git add dog1.html git commit -m "add dog 1" git checkout master git merge dog dog --no-ff type :wq git branch dog 翻譯蒟蒻:我要建立一個狗分支 * 在目前head的所在地貼上dog貼紙 git check out dog 翻譯蒟蒻:我要切換到dog分支 * head移動到狗貼紙 git commit -m "add dog 1" 翻譯蒟蒻:我要進行一次存檔 1. dog貼紙與head往前移動 2. 其他分支貼紙留在原地 這時候要合併就無法快轉了 git merge cat 翻譯蒟蒻:我要合併貓分支 1. 長出一個合併的commit 2. dog貼紙與head往前移動 dog合併cat跟cat合併dog有什麼不一樣? * 就像TW和CN一樣...... ### 已經合併過的分支可以刪掉嗎 * commit才是本體 * 貼紙刪掉就會多40byte的空間 git branch -d cat 翻譯蒟蒻:我要刪除cat分支 1. 把cat貼紙撕起來 2. 就這樣commit或檔案不會受到影響 ### 發生衝突(conflict)了,怎麼辦? cd ../git-conflict 你們聽過[先水](https://www.itsfun.com.tw/%E4%BB%99%E6%B0%B4%E5%BF%8D/wiki-1161992-7874382)嗎(啥鬼) git merge member conflict git status 編輯index and then commit GUI: 右鍵 git diff HEAD f3d9 ### 另一種方式 rebase re變換 + base根基 a base接在b base後面 //插花圖 ![](https://i.imgur.com/BRgz8vT.png) git rebase cat 我要踩到cat分支的頭上(我要踩在貓頭上) git rebase cat 翻譯蒟蒻:我要踩到cat分支的頭上 C3-C4-C5 C3-C6-C7 1. 複製一份C6接到C5後面,行程C8 2. HEAD移動到C8 3. 複製一份C7接到C8後面形成C9 4. head移動到C9 5. dog往前移動到C9 head指向dog貼紙。 6. C6,C7脫離。 C3-C4-C5-C8-C9 cd ../git-branch2 git checkout dog git rebase cat 它的base變成cat了 #### 用command line看分支圖 git log --oneline --graph --all #### 所以rebase合併有什麼好處 branch越來越多會很厚一層,線圖比較不會那麼複雜 #### rebase的壞處 就是merge的好處,比較無法知道當時有什麼事發生(過程) 無法保留當時的情境 #### 所以該選哪一種 * 歷史紀錄 merge * 乾淨 rebase 講者:我會選rebase啦,該有的做出來就好 ### 如何回到上一步 C1-C2-C3-C4-C5(M,O) * git 不能刪除commit 一新增就無法刪掉 * 沒有人看管它就會消失掉 C1-C2-C3-C4(M,O)-C5 * C5看起來被刪掉 $git reset * 這個指令比較像是become $git reset C4 * 把我現在的樣子變成C4這個樣子 * $git reset C4 --mixed :工作目錄 * $git reset C4 --soft :暫存區 * $git reset C4 -hard :X ### 聽說hard不能隨便亂用 事實上都救得回來 reset真的非常好用 git沒有刪除這個指令 git reset 9a2995 翻譯蒟蒻:我要變成C4的樣子 1. 目前的分支以及head移動到C4 2. C5暫時看不見了 注意不是被砍掉! 3. 原本C5的內容被放置工作目錄 cd git-branch1 HEAD ^ = -1 HEAD ^^ = -2 ... HEAD ~5 = -5 git reset 85e7 預設是mix 回去 git reset C5 --hard 但是看不到 git reflog head只要有移動就會有紀錄 git reset e12d --hard reset不是在砍東西 只是變成那個樣子 後面的參數決定檔案的去留:[mixed / soft / hard](https://gitbook.tw/chapters/using-git/reset-commit.html) 只要有地圖和坐標,就能到那個地方,就像勇者鬥惡龍(? ### 相對定位 \^ caret 卡退特 \~ Tilde 提爾達 賽亞人的名字? git reset f8xxxxx C2-C3-C4-C5(M) 翻譯蒟蒻:我想要變成C5的前一個狀態 1. 目前分支與head移動到C4 2. C5暫時看不見了 C2-C3-C4(M)-C5 git reset HEAD~2 C2-C3-C4-C5(M) 翻譯蒟蒻:我想要變成HEAD的前兩個狀態 1. 目前分支與head移動到C3 2. C4,C5暫時看不見了 3. 原本C4跟C5的內容,會被放置工作目錄 C2-C3-C4(M)-C5 reset跟checkout有什麼差別? git checkout eb396b 翻譯蒟蒻:我想要去C3看一下 1. 分支不動,但HEAD移動到C3(就像上帝一樣(?)) ### Git小聚場 要怎麼取消剛剛這次的合併 git merge cat -m "aaaaa" git reset HEAD^ --hard 連結看起來斷開 git reset #### 扯東扯西時間 有看過電影嗎 brinch? 好像記錯名字 imdb.com?? 地球1 地球2 地球3??? 新的平行時空 git rebase cat merged git reset HEAD^ --hard git reset b174 --hard git reflog ... ### 不小心使用hard模式reset了commit救得回來嗎? git reset HEAD~5 --hard git reflog git reset e12dxxx --hard reflog預設留30天 git reflog expire --all --expire-now //別亂用 git reflog ### 前一天沒睡飽,不小心把還沒合併的分支刪掉了,救得回來嗎? 把貼紙貼回去 git reset ORIG_HEAD --hard cat .git/ORIG_HEAD git branch -D dog git branch new_dog 05xxxxx 使用標籤(Tag) git tag bbb 053fxx git checkout 1.0.0 什麼時候會用到標籤 git tag 1.0.0 xxxxxxxx git checkout 1.0.0 可以視為 里程碑 ### 練習題 請試著在適當的commit上,打上tag以供識別。 ### 標籤跟分支有什麼不同 海角七號 阿嘎 海角七億 范... 田中 真的在一起了太可惡了 演戲演到變成真的(? 留下來,或我跟你走! 我知道怎麼在自己電腦用Git了,但要怎麼上傳到GitHub? GitHub/GitLab/Bitbucket 全球最大的宅宅交友網站 開發者最好的履歷 ### 練習題 請註冊一個GitHub,換預設大頭貼 …or push an existing repository from the command line git remote add origin https://github.com/yangyangisyou/git-test.git git push -u origin master origin 是一個代名詞 可以換成別的 SSH不需要帳號密碼 公鑰私鑰 git push origin master 我要把本地的master分支,推往origun這個遠端節點,並且在遠端形成一個分支 git pull git fetch 拉線上有的我沒有的 00 想到挖礦 git merge origin/master git pull = git fetch + git merge 複製 git clone 某個Git網址 ### 跟其他人一起工作,有時候為何推不上去 先拉再推 git pull --rebase(合併節點) git push -f //不能亂用 ### PR? PR = pull request ![](https://i.imgur.com/l8urheD.png) ### 什麼是squash? 恰恰爆🍊(x <iframe width="560" height="315" src="https://www.youtube.com/embed/eBawjCu2uK4" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe> ### 遊戲時間 參與者送電子書 #### Rule 一台電腦+兩個人(戰鬥員與駕駛員) 戰鬥員洞口指揮步驟 #### 目的 實際動手做 用講的跟動手做是兩回事 看看大家是怎麼解決問題的 #### 範例 操作題 A012 在專案中(目前在dog分支),取用fish分支的add dolphin跟add whale這兩個commit的內容 解: cherry pick ### 為何叫菜市場阿龍 詳情請參考 菜市場阿勇