[IBM實習]Bluemix與車聯網應用-Node-RED

前幾天參加Hackathon時,和附近的組別們聊開。大家的討論很熱絡,點子都非常有創意,規模也非常可觀,感覺如果成功就能改變世界!但一談到如何實作,大家氣氛立刻冷了下來,涉及的範圍越廣,軟硬的結合、伺服器的穩度、演算法、例外處理等…就會顯得越重要,大家都害怕,只是個學生真的能實現這些Cool idea嗎?有沒有簡單好用的開發工具能結合軟體和硬體,引用各式微服務和資料庫,又能像畫圖一樣容易學習呢?IBM的開源工具 Node-RED 正好符合以上條件。

什麼是NodeRED?

NodeRED是基於Node.js所開發出來的工具,以網站的方式運作。原本是專門為了物聯網iot而設計,但現在不論是http建網站、websocket、爬蟲等等…都有包辦! NodeRED安裝完成後,我們就可以在任何電腦的瀏覽器上編輯我們的”node flows”。

車聯網

NodeRED的編輯界面分成四個部分。最左邊是已定義的各種node的列表;中間是工作區,用戶可以拖拉左邊的node到工作區,Node-RED為每個node設置唯一的ID,我們可以通過點擊node來編輯每個Node物件,並通過連接node的input和output構成資料流;最右邊是debug node的輸出區,和node的訊息顯示區,node的訊息顯示區顯示每node的使用方式。右上角有‘Deploy’按鈕,用來把編輯完成的node flows保存到本地端並執行。

我們可以參考官方的NodeRED document,裡面有很清楚的使用說明。我個人推薦這個Node-RED Programming Guide,裡面有很完整的“動手做”教學!讓我們能快速上手!

安裝Node RED

說了這麼多,不如馬上來試試看Node-RED有多方便!在Bluemix內,我們可以直接在型錄找到Node-RED Starter展開Node-RED旅程!

車聯網
車聯網

完成打包後,回到應用程式概觀,點選”新增Git”

車聯網
車聯網

完成新增後按”編輯程式碼”,將此zip檔解壓縮後拉入public資料夾,方便我們實作時,引用js和image。

車聯網
車聯網

拖拉完成後,按左邊Git的版控按鈕,留下commit message,再按確定。最後按推送 (push),讓其自動執行建置和部署。

車聯網

點選右上方的儀表板 (Dashbroad),我們可以發現應用程式列表中已經出現剛剛新增的Node-RED。按下網址後,點擊”Go to your Node-RED flows”,全白的Node-RED編輯器就出現拉!

車聯網
車聯網

Node-RED app小練習第一彈:建立http網站

在實作開始前,先一起做個小練習,活動一下筋骨。

目標: 傳送url並夾帶x和y參數給Node-RED app,Node-RED app要回傳x+y的結果。

(1) 拉出http request input node和http response output node,中間加一個function node計算x+y

車聯網

(2) 如下圖,雙擊function node,在跳出的方框內撰寫邏輯,程式語言為javascript

車聯網

(3) 我們可以拉出debug node做偵錯,點擊右上的Deploy做部署。

車聯網

(4) 快來用此網址: http://”your_bluemix_name”.mybluemix.net/text?x=1&y=2試試看剛剛建的小網站,1+2結果如下。

車聯網

有沒有覺得建立網站突然變得超級簡單呀!XD

Node-RED app小練習第二彈:和iot接上線!

Bluemix的微服務架構,讓多個應用程式可以綁定同一個微服務(Ex: iot),也可以一個應用程式綁定多個微服務,這種架構讓其擴展變得容易且強大!而且Bluemix的每一個微服務都是RESTful service,就算在Node-RED沒有已定義好的node,我們也能自己用http node呼叫微服務,詳細做法會在Geospatial Analytics的章節說明。

(1) 點選儀表板 (Dashbroad),點擊自己Node-RED應用程式的概觀,和之前新增的iot微服務做綁定。

車聯網
車聯網

(2) 重新編譯打包完成後,回到Node-RED Editor圖形化界面,拉一個ibmiot input node和debug node,如下圖。

車聯網

(3) 點擊ibmiot node,做內部的細部設定。

車聯網

(4) 完成後按Deploy,我們可以看到右邊debug區域內,iot模擬車的json資料源源不絕的流出來!超神奇的!有了這些資料就能完全掌握模擬車的動向拉!

車聯網

實作1: 追蹤模擬車的路徑

(1) 建立網站主體

請將這裡的json code複製,import到自己的Node-RED。點選右上方收納盒內的import,選Clipbroad,把所有cartrack.txt的json code都複製到box中,就能完美的匯入。

車聯網

快來用此網址: http://”your_bluemix_name”.mybluemix.net/cartrack試試看這個google map應用。結果如下,目前還只是個普通的google地圖。

車聯網

(2) 加入websocket追蹤行車路徑,請複製以下json code到自己的Node-RED,這個node flows會接收ibmiot的資訊,經過解析後以websocket輸出。主網站會一直保持和此websocket的連線,讓其能隨時接收到ibmiot的經緯度變化。

[{"id":"aa7a16e0.5585e8","type":"websocket-listener","z":"d7cab805.283548","path":"/ws/position2","wholemsg":"false"},{"id":"e2a4854b.1d5b78","type":"websocket-listener","z":"d7cab805.283548","path":"/ws/position1","wholemsg":"false"},{"id":"35ebd19b.ca142e","type":"switch","z":"1c558bd.fe3aa74","name":"simulation or real device","property":"deviceId","propertyType":"msg","rules":[{"t":"eq","v":"testDevice","vt":"str"},{"t":"neq","v":"testDevice","vt":"str"}],"checkall":"true","outputs":2,"x":343,"y":201,"wires":[["75d977c.f8a2688"],["c134e307.3ecb2"]]},{"id":"c134e307.3ecb2","type":"function","z":"1c558bd.fe3aa74","name":"change payload to position (simulation)","func":"var content=msg.payload;\nmsg.payload={id: content.id, lng: content.lng, lat: content.lat };\nreturn msg;","outputs":1,"noerr":0,"x":643,"y":243,"wires":[["e1e6f29d.1e191"]]},{"id":"fbff00ac.0401","type":"ibmiot in","z":"1c558bd.fe3aa74","authentication":"boundService","apiKey":"","inputType":"evt","deviceId":"","applicationId":"","deviceType":"","eventType":"telemetry","commandType":"","format":"json","name":"cars iot track","service":"registered","allDevices":true,"allApplications":"","allDeviceTypes":true,"allEvents":false,"allCommands":"","allFormats":"","x":115,"y":201,"wires":[["35ebd19b.ca142e","fa2804f1.05d7f8"]]},{"id":"75d977c.f8a2688","type":"function","z":"1c558bd.fe3aa74","name":"change payload to position (real device)","func":"var content=msg.payload;\nmsg.payload={id: content.d.id, lng: content.d.lng, lat: content.d.lat };\nreturn msg;","outputs":1,"noerr":0,"x":642,"y":195,"wires":[["e1e6f29d.1e191"]]},{"id":"e1e6f29d.1e191","type":"switch","z":"1c558bd.fe3aa74","name":"check device","property":"payload.id","propertyType":"msg","rules":[{"t":"eq","v":"testDevice","vt":"str"},{"t":"eq","v":"myphone2","vt":"str"}],"checkall":"true","outputs":2,"x":922,"y":217,"wires":[["4db5f8c1.b24a08"],["a69867a7.596798"]]},{"id":"fa2804f1.05d7f8","type":"debug","z":"1c558bd.fe3aa74","name":"","active":false,"console":"false","complete":"payload","x":282,"y":258,"wires":[]},{"id":"4db5f8c1.b24a08","type":"websocket out","z":"1c558bd.fe3aa74","name":"","server":"e2a4854b.1d5b78","client":"","x":1174,"y":190,"wires":[]},{"id":"a69867a7.596798","type":"websocket out","z":"1c558bd.fe3aa74","name":"","server":"aa7a16e0.5585e8","client":"","x":1174,"y":247,"wires":[]}]

匯入後,node flows長相如下圖。

車聯網

(3) 編輯第四個node (check device),將第二條線的判斷依據改成“自己模擬車的deviceID”。

車聯網

(4) 編輯最後一個node (/ws/position2),新增path: /ws/position2。

車聯網

(5) Deploy後,快看一下主網站: http://”your_bluemix_name”.mybluemix.net/cartrack,我們發現車車已經在我們的地圖動起來了!

車聯網

完成了車連網 (V2I)後,下一個章節,我們要使用另一個微服務Geospatial Analytics來對主網站做更多樣的應用,監控車子在自訂區域的進出時間唷!

[IBM實習]Bluemix與車聯網應用-引言篇

互聯網、物聯網、車聯網傻傻分不清,究竟車聯網是什麼東西?又有什麼樣的商機呢?

什麼是車聯網?

車聯網

簡單來說,車聯網就是把車子拉入互聯網的世界,因為以目前來講,汽車和我們的互聯網基本上是隔絕的。那車聯網有其必要性嗎?有的,因為一個車子就是一個訊息的載體,擁有很多非常有用的訊息,只要訊息有價值,就能引入互聯網做收集、整理,做進一步的應用。一輛車能產生的有價值的數據如下:

  1. OBD (隨車診斷系統):可以偵測汽車本身產生的數據,像車速、各種溫度、輪速、油門等等…這些數據對保險公司、售後維護、駕駛人本身都有助益。保險公司可以藉由這些數據更精確的判斷肇事原因,甚至能依據駕駛人情形計算保費,維修工廠能根據車子的使用紀錄更快診斷出問題,根據駕駛情況提供客製化維護,駕駛也能根據這些數據做自己駕駛習慣的修正…
  2. 車上的人的嗜好:駕駛員、乘客喜歡什麼歌?常去什麼地方?停留時間等…這些數據對商家很有幫助。
  3. 汽車感應到的狀況:交通、天氣、行車記錄器等…這些數據對政府公共管理有價值,像是汽車結合智慧紅綠燈,在尖峰時段時控制紅綠燈的秒數,讓車輛能快速疏通。

有了車”聯“網 (V2I)後,我們能進一步延伸到網連車 (I2V)、車連路 (V2R),車連車 (V2V)、車連人 (V2H),儼然形成一個龐大的生態系,裡面充滿無限可能的創意應用,像常聽到的google自動駕駛、車隊社群都是其範圍。車聯網目前也還處在摸索階段,需要廠商和大眾一起腦力激盪,探索更方便的智慧生活。

IBM為車聯網戰場準備的武器

IBM身為前衛的大電腦雲端科技公司,沒有像Google一樣製造智慧汽車和傳統汽車廠商競爭,相反的,他要成爲汽車廠商最棒的合作夥伴,用IBM堅固的Bluemix雲端平台和多方位的微服務,協助汽車廠商輕鬆引入車聯網概念。本系列會先用模擬車,以一個小小的實作為範例,展示如何快速用IBM Bluemix做到車連網 (V2I)、車連路 (V2R)和車連人 (V2H),最後再改用你自己的手機模擬真車,連到自己剛剛實作的應用程式。

實作前準備

  • IBM Bluemix帳號:Bluemix有30天試用期,其微服務框架讓使用者的應用服務擴充非常容易,我們需要在這個平台建立我們的應用程式。
  • 登入Bluemix平台後,在左上建立自己的空間(space),我們會把發布的應用程式都放在這個空間內,帳戶地區不要選澳洲的Server,澳洲的Server目前尚未提供IOT服務。
  • 了解什麼是html、javascript,會寫一點java
  • 一顆雖懶惰但願意嘗試的心,因為IBM能帶領懶惰的我們用超簡單的方法實作車聯網XD

建立IOT微服務

(1) 點選型錄,在搜尋引擎內尋找”iot”,點選物聯網服務:Internet of Things Platform

車聯網

(2) 選擇之前就已經建立的空間,幫iot服務命名後,按建立。

車聯網

(3) 等一會,畫面會轉到剛建立的iot服務的管理。啟動儀表板,準備新增裝置 (物聯網的“物”)。

車聯網

(4) 進入儀表板,點選“新增裝置” (add Device)

車聯網

(5) 我們還沒有任何裝置類型可以選擇,所以要先建立裝置類型。

車聯網

(6) 類型名稱打”vehicle”,這個名稱會和之後iot的訊息傳輸有關。

車聯網

(7) 一直下一步,到最後按建立。畫面會回到“選擇裝置類型”,我們可以看到,剛剛新增的裝置類型已經顯示在輸入框框內。

車聯網

(8) 幫新增的裝置命名deviceID,這個值就像裝置的帳號,之後系統會自動產生deviceID所對應的鑑別碼 (裝置密碼)。

車聯網

(9) 接著一直按下一步,最後按新增。我們可以看到下面的畫面,複製組織ID、裝置類型、裝置ID和鑑別記號,貼到自己的記事本記錄下來,在本應用中會不斷被使用到。

車聯網

(10) 複製完後關掉彈出視窗,完成了裝置設定。接下來,我們點選“存取”,準備為應用程式建立api key和鑑別記號 (像應用程式的帳號密碼)。

車聯網

(11) 點選api金鑰,再按右上角產生金鑰。

車聯網

(12) 複製完API key和鑑別記號後,按完成,結束應用程式的帳密建置。這個應用程式帳密,是特別留給車子模擬器使用的,一樣要好好保存。

車聯網

準備車子模擬器

本實作所使用的車子模擬器也是一個應用程式專案,所以需要用剛申請的應用程式帳密(api key和鑑別碼)做認證。 我們的目標是將剛建立的裝置,放到此車子模擬器,去模擬車子的路徑行為。開發期間,我們先用車子模擬器的模擬車做開發,等系統開發完成後再將車子模擬器改成我們的手機。

(1) 進入專案vehicle-simulation,按Fork project,將project複製到自己的空間。做完如下圖的操作後,按Create創建。

車聯網

(2) 等待一會,畫面會切換到我們自己空間的新專案。點選右上角的Build&Deploy,準備部署作業。

車聯網

(3) 點選新增建置,將名稱取名叫Build,其他操作如下圖。“輸入”操作完先別急著按”Create”,到“工作”頁籤新增“建置”,再按Create見完成建置設定了!

tag tag

(4) 再度點選新增建置,這次將名稱取名叫Deploy,其他操作如下圖。“輸入”操作照著預設即可,直接到“工作”頁籤新增“部署”,再按Create見完成部署設定!

車聯網
車聯網

(5) 切換右上角的頁籤到”Edit Code”,我們需要更改兩個設定檔,如下圖。

車聯網

(6) 我們先編輯config資料夾下的setting.js,裡面必須填入我們要模擬的車子的帳密,和為這個應用程式所準備的帳密。

車聯網
車聯網

(7) 再來編輯manifest.yml,這個檔案將提供部署所需的資料,更改如下。都改好後切到Git版控按鈕。

車聯網
車聯網

(8) 為我們剛剛的變更作版本的紀錄,在commit messaage說明一下變更的內容,再按確定。

車聯網

(9) 我們可以從左邊列看到遠端主支和我們現在本地端主支的不同點,然後按推送 (push),把改變推送到遠端。

車聯網

(10) 馬上到右上角,切到Build&Deploy,我們會發現建置和部署已經自己Run起來了!!

車聯網

(11) 部署完成!畫面如下圖,快點按下網址看看模擬的車車吧!按車子會跳出車子訊息框!如果建置失敗,可以按“檢視日誌與歷程”來查看問題。

車聯網
車聯網

萬事俱備,開始實作!!!

實作文章將陸陸續續出爐,一起快樂體驗車聯網的奧妙吧!

  1. [IBM實習]Bluemix與車聯網應用-引言篇: 本篇將對車聯網做個小介紹,並為接下來的實作章節做事前準備
  2. [IBM實習]Bluemix與車聯網應用-Node-RED: 本篇介紹圖形化的開發工具-Node-RED,用NodeRED和iot做連結並建立網站
  3. [IBM實習]Bluemix與車聯網應用-Geospatial Analytics: 本篇介紹Bluemix的GIS-Geospatial Analytics,並利用Node-RED結合iot和Geospatial Analytics做有趣的應用
[Git]什麼是Github flow

前言

與以前的集中式(SVN)不同,開發者之間的協作方式因為 Git 的分散式特性而變得更為靈活多樣。其中,我認為 Github flow 很適合初學者,它實用又不繁複,對普通的小團隊非常夠用。希望大家先熟悉 git branch 的操作再繼續看下去。

log flow
log flow

Github flow

log flow

整個工作流程如下:

  1. 將遠端repo clone到自己的本地端,並創造一條新分支,在新分支上開發。
  2. 當新功能開發完成後,不要將新分支合併到master,直接向遠端repo發出 pull request,請求遠端接受合併。
  3. 遠端repo的管理人和貢獻者經過code review和一來一往的討論。
  4. 由遠端repo的管理人合併新分支至master。

如何在Github開源社群做貢獻?

以下解說,當我們在 Github 閒逛,看到有興趣的 repo 時,要如何貢獻一己之力。

首先,我們按右上角的 fork,將別人的 Github 專案,完全複製一份到自己的 Github。

log flow

之後我們可以看到同名的專案出現在自己的 Github,此後我們所有的變更都是push到這個 repo。

log flow

Pull專案至本地端,並開始開發新功能。方式是產生一條屬於自己的新branch,以這一條branch做新功能的開發,千萬不要改動專案上的master分支,log flow 如下圖。

log flow

接下來,push專案到自己的Github遠端儲存庫。

log flow

向原來的專案作者發出 pull request(圖上兩個皆可點選),請求他合併自己增加的新功能。注意,發出pull request後是無法取消的,所以要測試充足後再發出。

log flow

留言給原專案作者,說明一下變更的詳細內容。

log flow

往下拉可以看到自己所變更的內容(if you press “compare & pull request”),做最後的檢查。

log flow

我們可以看到,剛剛的發出的pull request已經在上面。接下來只要等原專案作者回覆了。

log flow

遠端專案管理者

遠端repo的管理者需要隨時注意的地方為 issues 區域和 pull request 區域。issues區域需要管理者到”設定”去開放給外來者,如下圖。

log flow

之後不論任何能都能在issues這裡回報問題,並使用簡單的open/close追蹤,issue還能被多個tag標記,讓搜尋issue更方便。搜尋技巧可以見這篇

log flow

專案管理者和貢獻者可以在pull request區域的對話過程中,用#引用issue和commit。有這個功能,讓討論變得非常方便!跨專案的issues引用也是ok的,只是要自行google了!

log flow

結語

Gitflow簡單又好用,但如果要公司形式的多人合作,可以參考傳說中的Git flow,網路上有很多資料可以參考。

[Git]分支的管理與常用功能

這裏是我學git一段時間後,所做的學習筆記。建議各位對git有一定熟悉度再看這一篇。

Git GUI tool: SmartGit

我最初使用git的時候,對branch的概念不熟悉,又固執的只用git shell做git操作,導致每次branch一複雜就會亂了手腳。之後因為一次機緣,試用Git GUI工具才發現,它不只會顯示log flow讓使用者了解目前版本進度,還能直接點選flow上面的commit版本做checkout、reset等操作,對我掌控整個git的版本控制非常有幫助,也讓我比較有“勇氣”用git輔助比較複雜的專案做開發,強烈推薦大家使用。

眾多Git GUI工具中,SmartGit一直蟬聯使用者喜好度的排行榜第一名,可惜它要錢。如果我們只是要在Github上面做貢獻,可以使用SmartGit的non-commercial版本,但如果是公司要使用,可能就要另尋工具了。除了SmartGit,網路上仍有許多免費的GUI工具可以使用,像是TortoiseGit(Windows)SourceTree(Windows/Mac)。提醒一下,SourceTree的log flow要調整為 Ancestor Order(以各版本祖先的順位做排序),才會看到我們比較熟悉的log flow。

SmartGit log flow:

smartgit log flow

點選log flow上面的commit版本並右鍵,就能對其進行checkout/revert等…操作。

log flow中,branch 間的差別

smartgit log flow

SmartGit Diff:

smartgit diff

由左至右可以看到上一個commit和這一次commit間改動的情況。沿著顏色光標,我們可以看到當下這個commit做的變更,將getActivity()刪除了。此外,右上角會有紀錄此commit共增減多少行程式碼,上下箭頭會引導到每個不同的更改內容。

基礎提醒

Git 是如何知道你當前在哪個分支上工作的呢?其實答案也很簡單,它保存著一個名為 HEAD 的特別指標。在Git中,它是一個指向你正在工作中的本地分支的指標,會一直指向分支的頭,在HEAD下commit的版本紀錄才會被分支追蹤到。這裏提供Git原理筆記給大家做進一步了解。

git log & git reflog

  • git log: 顯示開發者自身commit的紀錄
  • git reflog: 顯示“所有”commit的紀錄,包含git操作時自動做的commit,EX: checkout/pull/push等…紀錄

重要原則

Git branch相關的指令多到令人眼花撩亂,但有幾個原則搞清楚,在操作指令時就能比較得心應手。

  • 只有HEAD指標指向的工作目錄,才會被分支追蹤到。
  • 任何指令操作,被改變的永遠都是當下所在分支

以下舉merge和rebase的例子給大家看,針對下圖log flow做操作。

flow

首先是merge! 我們先git checkout master到master分支,之後的操作就只會動到當前分支:master branch。再來用git merge topic,將topic合併到master。如下圖,我們看到master分支被更動,增加了H commit:合併topic branch至master branch

merge
pic from The Will Will Web

下一個例子是rebase,我們先git checkout到topic分支,之後的操作就只會動到topic branch。再來用git rebase master,將當前這個分支的基點移到master上。原來的master分支沒變,只有topic分支的基底位置變了,如下圖。

rebase
pic from The Will Will Web

由上述例子,我們可以知道執行操作時,被改變的永遠是當下所在的分支,接下來我們挑幾個git指令做說明。

Checkout

git checkout是切換工作目錄的意思。 此指令有兩種使用方式,一種是切換工作目錄(含HEAD)至其他branch;另一種是切換工作目錄(不含HEAD)至之前的commit版本(不限定哪個branch),其中有很多細節需要注意。

(1) git checkout branch name

常和git branch一起使用,使用方式如下:

  1. git branch test #增加一個新branch叫test,等於git checkout –orphan test,orphan為孤兒的意思
  2. git checkout test #切換工作目錄至test branch

以上兩個指令可以用一條指令:**git checkout -b test **取代,執行後,工作目錄和HEAD都會在test分支的最新紀錄上。 以下介紹幾條git branch指令:

  1. git branch -d 分支名(刪除分支)/ git branch -D 分支名(強制刪除分支)
  2. git branch –list {pattern}(ex:t*) #條列所有分支(ex:條列所有t開頭的分支)
  3. git branch 分支名 #增加分支

(2) git checkout commit point

本指令將切換工作目錄至之前的commit版本,任何git reflog內有的commit紀錄都能切換到。

但要注意,執行此指令後,因為HEAD沒有跟著此指令做切換(HEAD detached(分離)),在那一點後所做的任何commit都不會有branch追蹤。如果一時疏忽跳到其他branch,從那點後所做的所有commit都會失蹤(commit紀錄都還存在,但沒有branch追蹤的到它們)。如下圖,左圖有2個紀錄,commit: A add 2 和 commit: A add 3,從commit: A.txt延伸出來。commit: A add 2 和 commit: A add 3 上面沒有branch標籤,此時他們沒有被任何分支追蹤到。再來,我們用git checkout master切換到master主支,log flow馬上就更新成右圖,可以發現2個commit: A add 2 和 A add 3 都不見了,因為沒有branch追蹤的到它們。

tag tag

但別緊張! 輸入git checkout master指令後,我們可以看到git給我們的提示。它引導我們幫之前所做的紀錄建立一條新支線。

tag

輸入git branch myTest(分支名) 9063ebd(切換分支前最新的commit id)後,我們可以看到下圖,新的分支myTest保存了之前的commit紀錄。

tag

Reset

和git checkout不同,git reset不只工作目錄,連HEAD都會回到之前的commit版本。如下圖,左邊是git reset HEAD~1 前,右邊是git reset HEAD~1 後,我們可以看到master HEAD退回到上一個commit,看不到master branch上的A.txt紀錄了。這指令跟上一頁的感覺很像,圖上的綠箭頭是目前的工作目錄的位置。

tag tag
  • 你可能有發現,只有master branch退後到前一個commit,其他branch都沒動。因為我們現在所在的branch為master,所以我們只會reset master分支。換言之,我們如果要reset master的commit,就要checkout到master!千萬別忘記,否則會有無預期的狀況發生。

下面介紹三種不同的reset方式,其中比較常用的是–mixed和–hard。

  • git reset –mixed {commit id} #HEAD指到{commit id},所在branch將取消追蹤{commit id}之後的所有commit,但檔案變更仍保留(working tree沒改變)。當想要取消之前的幾次commit紀錄,又想保留之前所做的所有檔案變更,就可以用這個指令。和取消上次存檔的感覺很像。
  • git reset –hard {commit id} #包含HEAD和檔案全部回復到{commit id},和回到上次存擋狀態很像。
  • git reset –soft {commit id} #是git reset –-mixed {commit id}後,又做了一次git add

Fetch

我們用git remote add {遠端資料庫名} http://………git 來設定遠端儲存庫(可設定多個),並利用git fetch {遠端資料庫名} {遠端分支名} 在本地端建立名為 {遠端資料庫名}/{遠端分支名稱} 的遠端追蹤分支,同步遠端伺服器上的資料到本地。如果想刪除本地端的遠端追蹤分支,可以使用 **git push {遠端分支名稱} :{遠端分支名稱} **指令,或直接用 git remote rm {遠端資料庫名} 刪除儲存庫紀錄,此時遠端追蹤分支也會跟著一起被刪除。

tag

經由上面的指令,我們可以看到原來左圖的log flow變成右圖的log flow,多增加了同步後的origin1/master分支在A.txt版本。

tag tag

使用這個指令,我們可以得到和遠端伺服器一樣的版本資料。本地的遠端追蹤分支有個特點,就是不能在上面做commit,要commit請在本地端相對應名稱的分支做commit,因為遠端追蹤分支如其名,專門只用來追蹤遠端伺服器的版本。

Merge

本指令會將其他分支的最新版本合併到所在分支,其中需要注意的就是fast-forward和non fast-forward的差別,這一篇Git教學文章寫得很清楚,在此截取其中一段:

fast-forward 在 Git 是一種 merge 術語,當 B branch (例如一個 local branch) 是從 A branch (例如一個 remote branch) 的最新版(HEAD)分支出來的,那當 A 要把 B merge 進來時,因為 B 的 parent commit 是 A 的 HEAD,所以這兩個 branch 唯一的差異就是 B 後來的 commit 而已,而不會有任何 conflict。所以實際上的動作只要把 A 的 HEAD 改成 B 的 HEAD 就好了,線圖上這兩個 branch 根本是同一條線,此謂 fast-forward。

以下實際用log flow做演示。首先是初始狀態,我們可以看到myTest分支的基點是master分支的最新版。

tag

然後,我們要在master主支,將myTest分支合併回來:

  • 左圖使用fast-forward指令(git預設): git merge –ff myTest,我們可以發現log flow沒有小耳朵,直接連成一條直線,myTest和master的HEAD都來到最新版本。當我們在合併遠端追蹤分支到本地分支時,我們會希望同一人開發用同一條branch就好,不要因為這個單純的同步,讓分支到處分岔出去添亂。
  • 右圖使用no fast-forward指令: git merge –no-ff myTest,這個指令在開發者把“別人”的分支合併回master時常用。為了追蹤方便,我們習慣把分岔出去的小耳朵,認為是別人開發的分支,這樣會比較方便追蹤。
tag tag

工作習慣整理:

  1. 我們習慣把分岔出去的小耳朵,認為是別人開發的分支合併進來的結果
  2. 我們習慣將自己開發的commit保持在同一條branch上
  3. fast-forward無小耳朵; no fast-forward有小耳朵

Pull

簡單說,Pull = Fetch + Merge,pull預設的merge就是fast-forward,我們可以使用git pull –no-ff指令,指定no fast-forward。如果在pull時遇到衝突,可以使用git reset –merge回復到merge前的狀態(也就是只執行到fetch),查看衝突再merge。

  • 我們可以將pull預設改用 fast-forward only: git config –local pull.ff only,好處是當我們無法pull時,馬上就知道遠端伺服器的版本被更動了!此時用git fetch 先同步遠端追蹤分支,查看遠端的變更再手動merge。

Rebase

git rebase是重新定義基底點的意思,其說明在這篇Git-rebase小筆記說得很清楚。他的感覺就像把樹枝拔下來重新插在其他分支,如下面左圖,執行以下指令:

  1. git checkout myTest #切換到myTest分支才能更改myTest的基點
  2. git rebase master #把myTest分支的基點接到master的HEAD

就會產生右圖的log flow,更改的只有myTest分支,master分支沒有任何變更。

tag tag

Cherry-Pick & Revert

兩者的相同點在於,會在做完變更後commit留下紀錄,不同點在於前者是“撿”幾個版本的變更到所在分支並重新commit,後者是取消幾個版本的變更重新commit。這篇git cherry-pick寫得非常清楚,下面這條很重要,擷取給大家看。

使用git cherry-pick&git revert的注意事項

「工作目錄」必須是乾淨,工作目錄下的「索引」不能有任何準備要 commit 的檔案 (staged files) 在裡面,否則將會無法執行。

(1) Cherry-Pick展示:

見左圖,我們可以看到2條分支,一支是master,另一支為test。我們現在要將test分支的2個commits(被光標的2個)像撿櫻桃那樣,撿到master分支。我輸入的操作如下:

  1. git checkout master
  2. git cherry-pick {commit id: add test}
  3. git cherry-pick {commit id: add test2}

我們可以看到log flow變成右圖,test上的2個commits被原封不動的搬到master上,成為master的新版本。

tag tag

沒有發生衝突還好,一發生衝突時,怎麼繼續進行cherry-pick就很重要。我們看到下圖SmartGit的Cherry-pick操作,有兩個選擇:cherry-pick & commit 跟 cherry-pick。

含commit的選象為cherry-pick預設,我們處理完衝突後,要用git cherry-pick –continue讓git留下commit紀錄,才算完成整個cherry-pick流程。如果覺得衝突太多想取消這次cherry-pick,可以輸入git cherry-pick –abort放棄這次cherry-pick;下圖最右邊的選項,cherry-pick指令有加上–no-commit。此指令只有把所選的版本的變更合併進所在分支後,就完成cherry-pick了,沒有督促我們留下任何commit紀錄。我們能使用這個指令,合併完變更版本後再做一些客製化修改,再commit。

tag

執行git cherry-pick {commit id} 發生衝突時,git會提醒我們做修正,如下。此時cherry-pick流程還沒有結束,為了保險,我們可以用git status查看是否還在cherry-pick process。

tag

衝突發生時的解決方法,可以操考這篇的Resolve conflicts,cherry-pick不會告訴我們哪些檔案有conflict,但我們可以用 git status 查閱到,如下圖。

tag

解決完衝突後,別忘記git cherry-pick –continue,完成cherry-pick的程序。否則一不小心忘記而跳到別的branch,之前所做的修正可能會都不見。

小知識:

cherry-pick會把之前的版本原封不動的搬到所在分支上,所以cherry-pick的新commit的時間和作者等…都和原本的commit一模一樣,這樣讓人方便追蹤是誰何時做的版本變更。

tag

(2) Revert展示:

首先,看到下圖的log flow。我們希望“取消“之前的commit: fix所做的變更。

tag

commit: fix變更了test.txt的內容,修正了衝突。我們希望將test.txt回復到修正衝突之前。

tag

如果沒有遇到衝突,就能看到log flow變成下圖。 git revert會取消指定commit的變更,並下新的commit紀錄此次恢復。我們可以在指令加上–no-commit,讓revert執行後不要系統自動commit,讓我們有空間做些許調整後再自己手動commit。

tag

revert遇到衝突時的應對方式和cherry-pick一模一樣,通常會在我們試圖revert “一直被變更的文件” 的舊commit時發生,因為舊commit和新commit對同份文件的變更可能會相衝到,參照下圖。遇到衝突時,多用** git status **查看是好用的。

tag

結語

git的觀念雖然比較難具象化,但懂的話,一輩子受用無窮,可說是最棒的版本追蹤+備份工具。下篇將解說如何用git做協同合作,期待再見XD

[API interface]Swagger的使用

API interface的生態

當我們開發者想要將自己的資源寫成API開放給外人使用時,有沒有好用的工具和撰寫方式可以參考呢?當然有。 在Open source社群裡,各種API文件產生工具如雨後春筍般冒出。只要照著它的規則撰寫,它不只能快速產生Web API文件,而且能直接透過JSON或YAML進行Web API的匯入與匯出,並且可以快速的對你的Web API進行測試,不論此Web API是在本機或是遠端。有了它,我們甚至不用撰寫Server端程式碼,因為API文件產生器已經自動把我們Server端要撰寫的測試部分和開放說明部分全部產生出來了,真是太神奇了!

這麼多文件產生器,我到底要用哪一個呢?目前最紅並最常被拿來比較的產生器有三個,API Blueprint,RAML和Swagger,這三個都是開放在github上的原始碼,比較表可以見這裡。其中Swagger是最老的,所以社群活動和語言支援大勝另外兩個文件產生器,這也是這次以Swagger為說明主題的原因。當然Swagger也有因為API document不夠易懂直觀等…原因,而被強大的API管理公司,MuleSoft開發出來的RAML急起直追,但2015-09釋出的Swagger 2.0似乎有大大的改善此等缺點,看來Swagger應該暫時還會立於不敗的地位。更棒的比較文章請入內。

Swagger的過去與現在

Wordnik公司在2011年,將自己的API文件撰寫規範開源出來,並陸續釋出自己開發的互動性API產生文件, 程式碼自動產生器, API Server端開發工具等等…讓開發者在撰寫API文件上更為快速方便。 因為好寫的JSON撰寫規格和新穎的想法,Swagger成為開放軟體社群中最受歡迎的API文件撰寫方式,也是在Web API文件開發裡,最多人投入的開源專案。在2013年,RAML和API Blueprint問世,RAML以YAML為基礎做撰寫;API Blueprint則以markdown為基礎做撰寫,兩者皆有比Swagger更易撰寫、更有彈性、規格考慮更全面等優點…尤其是RAML,背後有像MuleSoft那樣強大的API管理公司在開發,讓他們的使用者急劇上升。Wordnik為了保持領導地位,也成立開放工作小組,並在2014年釋出Swagger 2.0,大大改善了Swagger原有的缺點。個人覺得Swagger支援的語言數實在大勝RAML和API Blueprint太多了,應該還會繼續維持領導地位一陣子。這裏有中文版的訪問紀錄

Swagger的撰寫方式:JSON格式

詳細的撰寫方式,官方文檔都說明的很清楚,以下只做個大概瀏覽,希望這些亂亂的截圖大家能看得懂XD

(1) API info部分撰寫

這裏為Swagger文件最前端,撰寫像開發者、license等內容…左邊文件是右邊JSON文檔所對應的,之後系統自動產生Client/Server端程式檔後的結果。其中consumes為API request的MIME type;produces為API response的MIME type,這2個定義在各自path內比較常用些。定義在全域的話,會套用在所有path。

API info

(2) API request parameters撰寫

API request

(3) API response and definitions

response的結構定義在文件最下面的definitions,上面只要用$ref指向definitions。如果response回傳的JSON結果,內有string也有JSON Object等…(如圖片的tag),可以在definition內再引用definition的結構來達到描述。

API response

當然其他還有如何描述金鑰、Oauth2等…安全性設定,就請大家慢慢看官方說明文件吧。

Swagger Editor

不論是線上API測試。

Swagger ui

還是程式碼自動產生。

code genarate

全部都能在線上工具Swagger Editor一次滿足,所有原始碼都被放在Github,非常值得一看。 我們只要將寫好的JSON文件匯入Swagger Editor,就能直接線上測試API和自動生成給Server/Client用的API程式碼,還支援非常多的語言和框架,如下。

tag tag

*其中要注意的就是CORS Support,CORS是一個防止網站被壞東西竊取個人資訊的一項技術,現在很多瀏覽器和javascript工具包不只支援這項技術,甚至強制要使用這些工具的Server遵守,所以Swagger也強制使用它製造API的Server也必須支援CORS Support。

想要自己的Server支援CROS非常簡單,只要在HTTP response加上以下header參數:

Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept

Swagger支援非常多語言和框架,Generate Server會產生類似Swagger UI demo的測試程式碼給使用者測試自身API,裡面已經實作了跟原來Server端的呼叫邏輯,我們只要下載下來後再加入自己Server的程式碼就好了,他還很貼心的將IP改為localhost,如果想要改變IP可以到api資料夾內的swagger.json檔修改,如下圖。

tag

Generate Client有超多語言和框架可以選擇,我選擇node.js的express框架,先用npm install express部署好express,再用node main.js運行,main.js可以查看並修改port。

tag

*Generate Client中的Android甚至自動實作了呼叫API動作的java code,真的是方便很多開發者。

小結

開源專案的蓬勃發展真的幫助了很多開發者,除了大大增加了開發速度,更加速新創團隊的崛起…我要好好努力,希望未來也能為開源社群有所貢獻。