高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

為你自己學 Git

離上一篇文章已經是一個月過去了,又好陣子沒寫 Blog 文章了,其實是在忙別的事(藉口)。這回本來在忙的是公司的線上課程,但因為在準備這個線上課程的過程中需要先準備課綱及講稿,結果就不知不覺的把一本大概 300 頁約 15 萬字左右的書寫出來了(我也不知道是怎麼辦到的)。

既然都寫出來了,而且我自認這些我會的東西都是從網路上學來的,所以也沒什麼好藏私,就一樣放出來給大家參考。

網址:http://gitbook.tw

「為你自己學 Git」,如其標題,學習不需要為公司、長官或同事,不需要為別人,只為你自己。

learn git

所有內容都是我在五倍紅寶石培訓課程以及線上課程「人生不能重來,但 GIT 可以」所用到的教材,若發現內容有誤或有任何問題,歡迎直接來信,或是在該章節頁面下方留言 :)

除了少數幾個章節外,HTML 版本的內容將會在網路上供大家參考,不會收費;實體平面出版物目前已與出版社洽談中,應該這一、兩個月會有下文。當然,線上課程也是希望大家多多捧揚。

希望這本書的內容對大家有幫助。如果您對我們其它的培訓課程有興趣,歡迎您參考這個連結

「你知道 Git 是怎麼一回事嗎」

五倍紅寶石學院推出第一波線上課程 - 人生不能重來,但 GIT 可以,預計於八月底上線,現在預購可享九折折扣。同時配合 ModernWeb 2017 活動,在購買 Git 課程時候可使用折扣代碼「ModernWeb2017」,可再扣抵 300 元費用,有效期限僅到 8/19 止。

你知道 Git 是怎麼一回事嗎

「你知道 Git 是怎麼一回事嗎」這是我在今年 ModernWeb 研討會上分享的講題。這個主題基本上算是一個科普等級的分享,主要是介紹關於 Git 一些你可能知道,也可能還不知道,或是以為已經知道但其實是不知道的東西。

適合對象

主要適合平常工作有在用 Git 或是曾經有用過 Git,或是大概略懂略懂 Git 的朋友,如果這是你第一次看到這三個英文字母的組合,有滿大的機會你可能會不知道我在說什麼。但也沒關係,既然都來了,就安心坐下來吧,就把我當做是天橋底下說書的,當故事聽也可以。

由於場地及投影設備不是非常理想,在場地中、後排的朋友應該看不太清楚台上在表演什麼,轉出來的簡報檔又都是靜態的,無法看到真正原本的樣子。再加上本回主辦單位似乎好像也沒有提供錄影服務,剛好晚上也醒著,於是我就自己愛現的再錄了一次,供大家參考:

投影片連結:https://speakerdeck.com/eddie/ni-zhi-dao-git-shi-zen-mo-hui-shi-ma

有任何問題,都歡迎留言或來信討論 :)

Git 簡單嗎? 困難嗎?

大家覺得 Git 很簡單嗎? 還是很困難? 不就是 git add,然後 git commitgit push 這樣而已嘛,沒什麼難的吧?

我想在座的各位的答案應該跟我差不多:「Git 不好學」,不然大家今天就不會坐在這裡聽我講故事了。Git 是一種看起來不太難但其實很難精通的一種工具,要真的好好的使用這個工具,正確的觀念不可少。

也許你曾經使用過 CVS 或 SVN 之類的版控軟體,但 Git 在設計上跟這些版控軟體有本質上的差異,所以如果各位只是把 Git 當做是 SVN 的加強版的話,那在學習上可能容易卡關,或是誤解。像是他們處理檔案的方式、使用分支的方式等等,都有很大的不同。

20/80 法則

在 Git 裡的指令,主要有分兩種,一種是比較底層的,稱之 Plumbing,另一種比較高階的,稱之 Porcelain,早期版本的 Git 大部份都是底層指令較不易上手,後來才慢慢的加入了比較高階的指令,例如 add、commit 等這些都是屬於高階的指令。還好,我們平常用到的指令雖然不多,但已經足以應付平日的工作了。

一定要認識一下的四大天王

在 Git 的世界裡,有 4 種物件一定要認識一下,分別是 Blob、Tree、Commit 以及 Tag 這四種物件。其中,Blob 物件主要是存放檔案內容,Tree 物件主要是存放目錄以及檔案資訊,Commit 物件,看名字就知道是存放 Commit 的資訊,而 Tag 物件,也就是存放跟 Tag 相關資訊的物件(更正確的說,其實是 Annotated Tag 而不是一般的 Tag)。

在使用 Git 開始進行版控後:

  1. 當開始把檔案加到 Git 的暫存區(或稱之索引區),Git 便會開始生出一些 Blob 物件。
  2. 當開始進行 Commit,Git 便會產生出一些 Tree 物件,指向剛剛那些 Blob 物件。或是可能會有其它的子目錄,所以 Tree 物件也可能會指向其它的 Tree 物件。
  3. Commit 的同時,也會產生出 Commit 物件,它會指向某一個 Tree 物件。而除了最一開始的 Commit 之外,所有的 Commit 物件也都會指向它的前一個 Commit 物件。
  4. 最後,Tag 物件則會指向某一個 Commit 物件。

這四種物件的關連圖大概長這樣。

其實 Git 不在乎你!

很重要的觀念:「Git 只在乎檔案的內容,不在乎目錄或檔案名稱」,相同的內容的檔案,不管有多少個,在 Git 裡面都只會存一份而已。而 Git 使用的 SHA1 雜湊演算法,正是使用「內容」來進行計算的。

其實,Git 只是個內容追蹤軟體,只是剛好它可以被拿來當版控軟體而已。

Git 的 SHA1 怎麼算出來的?

以 Blob 物件的 SHA1 計算公式為例:

  1. 「"blob" 字樣」
  2. 「1 個空白字元」
  3. 「輸入內容的長度」
  4. 「Null 結束符號」
  5. 「輸入內容」

用一段 Ruby 的程式碼來說明:

1
2
3
4
5
6
7
require "digest/sha1"

content = "Hello, 5xRuby"
input = "blob #{content.length}\0#{content}"
puts Digest::SHA1.hexdigest(input)

#=> "4135fc4add3332e25ab3cd5acabe1bd9ea0450fb"

什麼是分支(Branch)?

有些人會把分支當做是「把檔案複製出來一份改,改完之後會再合併回去,所以在改的時候才不會影響到原來的分支」,但其實 Git 的分支不是這樣的。另外,為什麼大家常說在 Git 使用分支很便宜? 那是有多便宜?

因為,說白了,分支只是一個指向某個 Commit 的指標,所謂的分支,其實就只是一個有 40 個字元的檔案而已,不相信的話讓我們來看看:

$ cat ./git/refs/heads/master
0ea8463352e5fcac14b9bad84b691058cbbf8eb1

Git 的分支沒什麼,就只是這樣一個檔案而已! 如果你仔細觀察,便會發現這串 SHA1 值,正是某個 Commit 物件的 SHA1 值:

$ git log --oneline --graph
* 0ea8463 add c.html
* 632dca8 add abc
* e368aa4 init

注意到了嗎? 它正指向最後一次的 Commit 0ea8463

所以,為什麼說在 Git 使用分支很便宜? 因為所謂的分支,就說它只是一個 40 個字元的檔案罷了,所以當然不貴。

什麼是 HEAD?

HEAD 是一個指向某一個分支的指標,在分支切換(checkout)的時候,HEAD 會跟著指向切換過去的那個分支。

所以再回顧一下前面那張 4 個物件的圖,每一個分支,都會指向某個 Commit 物件,而 HEAD 則會指著某一個分支:

猜猜看,Git 是怎麼知道現在是哪一個分支?

在 .git 目錄裡有一個名為 HEAD 的檔案,它會記錄目前是在哪個分支的資訊:

$ git branch
  cat
* master

$ cat .git/HEAD
ref: refs/heads/master

可以看得出來現在 HEAD 的內容是指向 master 分支的,接著切換到 cat 分支:

$ git checkout cat
Switched to branch 'cat'

$ cat .git/HEAD
ref: refs/heads/cat

看到了嗎? 這個 .git/HEAD 檔案就是記錄著目前所在的分支。

標籤(Tag)是什麼?

標籤其實是跟分支有點像的東西,差別只在於在 Commit 發生的時候,分支會隨著一起往前移動,但標籤一旦定下來之後就不會再移動了。大家也許看過「海角七號」電影,用電影裡一句很紅的台詞「留下來,或我跟你走」舉例,留下來的是標籤(Tag),跟你走的是分支(Branch)。

沒有蠢問題

有沒有人想過以下這些問題?

Q: 一定要有 Master 這個分支嗎?
A: 其實也不一定,分支就只是一個像貼紙或標籤一樣的東西,想叫什麼名字都可。

Q: 合併過的分支可以砍掉嗎? 為什麼?
A: 看你心情,你想砍就砍,或是想留做紀念也可以。分支也只是一張貼紙而已,砍掉分支只像是把這張貼紙撕起來而已,不會影響原來已經存在 .git 目錄裡的物件。

Q: Master 分支可以砍掉嗎?
A: 可啊,再次強調,分支就只像是一張貼紙一樣,想撕就撕,唯一的限制就是,你要撕這張貼紙的時候,不可以踩在這張貼紙上,不然撕掉之後要去哪裡?

這些問題可能看起來有點蠢,但其實只要觀念是正確的,這些問題根本也算不上是問題了。

得罪了方丈還想跑…

其實東西進了 Git,想要把它刪還不太容易,不管是檔案不小心被刪了,或是還沒合併但卻被刪掉的分支,甚至被 Hard Reset 的 Commit,一樣都救得回來。操作細節請見影片介紹。

工商服務 Part 1 - 為你自己學 Ruby on Rails

最近給出版社一本書,是關於 Ruby on Rails 的入門指南,這是我們家在培訓 Ruby on Rails 學員時候會用到的教材。目前正在校稿中,我看了一下,大概 400 多頁,我也不知道我是怎麼辦到的,就發揮了我囉嗦的個性,一直寫寫寫就寫了這麼多了。沒意外的話,大概九月會上市吧。

所以內容均放在網路上,可免費閱讀,有需要的可自取。

網址:http://railsbook.tw

工商服務 Part 2 - 五倍紅寶石學院上線啦

之前常有朋友提到因為時間無法配合,或是人在中南部的緣故,無法參加我們家舉辦的課程。於是,我們開始準備線上課程了,希望之後可以讓更多的朋友在線上參與我們的課程。

網址:五倍紅寶石學院

image

課程預計將包括 Ruby/Ruby on Rails、Elixir/Phoenix、Git、CSS.. 等內容。目前第一波是 Git 課程,將於八月底上線,現在預購可享九折折扣。

線上課程網址:人生不能重來,但 GIT 可以

如果您還是比較偏好實體課程,也可參考這個連結

image

同時配合 ModernWeb 2017 活動,在購買 Git 課程時候可使用折扣代碼「ModernWeb2017」,可再扣抵 300 元費用喔,有效期限僅到 8/19 止。

為你自己學 Ruby on Rails

好陣子沒寫 Blog 文章,其實是在忙別的事(藉口)。雖然 Ruby on Rails 的學習資源向來不少,但看了一下坊間關於 Ruby 跟 Rails 中文書並不多,特別是專門給新手更少,於是在今年趁著參加 iTHome 舉辦的鐵人賽活動,把之前寫了一百多頁的 Rails 書拿出來繼續寫下去。

網址:http://railsbook.tw

「為你自己學 Ruby on Rails」,如其標題,學習不需要為公司、不需要為長官、同事、不需要為別人,只為你自己。該書所有內容是我在五倍紅寶石 Ruby on Rails 培訓課程所用到的補充教材,將以 Ruby 2.4.1 以及 Rails 5.1.0 之後版本為主,若發現內容有誤或有任何問題,歡迎直接來信跟我說(eddie@5xruby.tw),或是在該章節頁面下方留言 :)

HTML 版本的內容將會在網路上供大家閱讀,不會收費;實體平面出版物以及 PDF 電子書版目前已與出版社洽談中,應該近幾個月會有下文。

希望這本書的內容對大家有幫助。當然,如果您對我們的培訓課程有興趣,歡迎您參考這個連結

再見 2016,哈囉 2017!

2016 年快結束了,今年是挺忙的一年,發生了不少有趣的事。

2016 年幹了哪些事

校園推廣

一直以來我跟公司的夥伴都很希望可以把 Ruby 這個有趣且富生產力的程式語言推廣給更多的人,

今年還是有到交通大學、台灣大學、清華大學以及台北商業大學等學校持續的去洗腦宣傳 Ruby。感謝學校跟同學們的邀請,有機會能跟同學們介紹 Ruby 是個什麼樣的工具,以及如何使用 Ruby on Rails 快速開發網站。

數了一下自己去過的學校,發現已解除在「台清交成」演講的小確幸成就。

玩樂

今年九月份公司的日本員工旅遊:

image image

以及一家四口由關西到關東的遊山玩水:

image image

勉強算是有個交待了。

公司

今年大部份時間都是在忙公司的事,主要有幾件大事:

人員

在 2015 年年底,公司人數僅有 8 人,現在 2016 年年底,公司人員正職人員已有 17 員,加上長期配合的實習生及外發單位人員,再外掛一隻脾氣差的貓,公司人口平常已有 20 人上下,已經到了那種搭電梯要分二、三次才能全部下去的狀況。

順利的話,也許明年估計還會再繼續增加 3 ~ 5 名同事(希望坐得下)。

搬家

因為人員增加了,再加上原來的辦公室一開始就不是設計來工作的,老實說工作環境並不是很好,大家常會因為課程或活動需要移動自己的座位。算了一下,似乎公司今年有些盈餘,雖然原來的租約還有 3 年,還是在今年 7 月開始找新的辦公室。找了好陣子,最後找到在台北市 228 和平公園旁邊的一家瑜珈教室:

image

這個地點的生活機能很不錯,外面也有不錯的公園景色,不過隔間、天花板、地板跟冷氣都不適用,所以幾乎是整個砍掉重練:

image

image

雖然花了七位數的錢錢,裝潢了一個半月,不過可以提供給同事們更好的工作環境,也是值得的。

有陽光照得進來的落地窗: image

有個可以看公園景色的休息區: image

如果坐累了,也有地方可以站一下: image

推廣 Ruby 是我們一直以來的目標,所以教室區是一定要的: image

除了自家課程外,也提供給社群活動使用。

感謝同事們的不離不棄,在環境沒有很好的時候也還願意留下來幫忙。

投資

也許有些朋友已從其它媒體得知這個消息,就是我跟幾位社群朋友成立的公司 - 五倍紅寶石 被新加坡電商 Shopmatic 投資,成為其集團之子公司。

image

Shopmatic 是我們長期合作的客戶,從 2015 年 8 月起就開始開發電商開店平台,雙方合作一直非常愉快。後來 Shopmatic 也希望擁有一個專屬的開發團隊來提供更穩定的開發能量,因此與我們開始洽談投資事宜,直到今年 12 月才算完成所有投資程序。

雖然我們是 Shopmatic 在台灣的子公司,現有服務和專案都會持續,不會有太大異動。當然,社群活動也是一定要繼續進行的。

許願

年紀越大,越不敢亂許願(因為許了做不到也是沒用)

  • 希望小朋友們可以繼續平安長大,2017 年也可以再帶他們一起來去旅行。
  • 希望繼續推廣 Ruby 給更多人知道。
  • 希望可以把該寫的出版物完成。
  • 希望公司生意… 順利就好。

願望許完了,2017 年也要繼續努力!

Ruby 語法放大鏡之「在 Gemfile 裡看到版本寫法有好幾款,各是代表什麼意思?」

Ruby 語法放大鏡」系列短文主要是針對在大家學習 Ruby 或 Rails 時看到一些神奇但不知道用途的語法介紹,希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby 或 Rails 是怎麼回事。

隨便打開一個 Rails 專案底下的 Gemfile 檔案,大概會長得像這樣(以 Rails 5.0.0 beta 4 為例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
source 'https://rubygems.org'

gem 'rails', '>= 5.0.0.beta4', '< 5.1'
gem 'sqlite3'
gem 'puma', '~> 3.0'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.1.0'
gem 'jquery-rails'
gem 'turbolinks', '~> 5.x'
gem 'jbuilder', '~> 2.0'

group :development, :test do
  gem 'byebug', platform: :mri
end

group :development do
  gem 'web-console'
  gem 'listen', '~> 3.0.5'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

移除部份註解節省點空間。在這個例子裡,有些 gem 的後面有加註版本號碼,有的沒有,這些分別是代表什麼意思呢?

沒加註版號

先從最簡單的來看。當後面沒有加註版本號碼的時候,像這樣:

1
2
gem 'sqlite3'
gem 'jquery-rails'

這樣將會在安裝的時候選用「最新的穩定(stable)版本」,要注意這裡的重點是「穩定」而不是「最新」。以 Rails 來說,雖然目前最新的版本是 5.0.0 beta 4,但最新的「穩定」版本是 4.2.6 版,所以當沒有加註版本號的時候,它會安裝 4.2.6 版本。

加註明確版號

例如像這樣:

1
gem "rails", "4.2.6"

這相當明顯了,這就是說「我要安裝 rails 4.2.6 版」,應該不需要特別解釋。

大於、小於版號

1
gem 'uglifier', '>= 1.3.0'

我想這個光用看的就猜得出來,就是要選用大於或等於 1.3.0 版本。

1
gem 'rails', '>= 5.0.0.beta4', '< 5.1'

這樣則是會選用在 5.0.0.beta4 跟 5.1 之間的版本。

差不多…

1
gem 'coffee-rails', '~> 4.1.0'

這是指會選用 4.1.0 以上,但 4.2 以下(不含括 4.2)的最新版本。

為什麼這麼麻煩? 舉個例子來說,例如版本號 4.2.6426 三個數字分別代表主要版號(Major)、次要版號(Minor)以及修訂版號(Patch),分別表示:

  • 主要版號:功能大改,公開的 API 做了不少修正,通常沒辦法向下不相容
  • 次要版號:加了某些新功能,但不影響其它功能,向下相容
  • 修訂版號:對現有的功能做了小幅度的修正,可向下相容

這是個不成文的規定(語義化版本),雖然沒有強制,但幾乎大部份的 gem 作者都會依照這個規範。而這個 ~> 可以比較確保在進行 bundle install 指令的時候,因為只會更新到次要或修訂版號的套件,所以比較不會因為原作推出了最新力作(例如 5.0.0),而把原本正常運作的系統弄壞了。

參考資料:

  1. Bundler http://bundler.io/gemfile.html
  2. 語意化版本 http://semver.org/lang/zh-TW/