2013年3月7日 星期四

Github Pull Request 500 錯誤原因

今年一月的時候,因為客戶需求開了新的 branch ,來作另一個 Android 版本的開發,卻遇到了每每 pull request 的時候,不管如何都會先吐個 500 error 給你。
Github 500 error.
一開始不明白發生的原因,只能藉由手動修改網址來指定對應的 branch 下 PR。後來終於察覺到是因為在下 PR 前,雖然已經切換了 branch ,但對應到了客戶端的 repository 時,一樣會是master。

而 Github 的答覆是:
Github response about pull request.
只能在 PR 建立的頁面才可以選擇相對應的 branch。但是,下 PR 就發生 500 錯誤,根本沒辦法進到選擇頁面阿!!!看來目前還是只能手動改網址了...

不過,這些問題跟 500 錯誤有什麼關係呢?當發現新 branch 下 PR 會對應到 master 時就有個底了,答案是因為相對應的 branch 差異過大,導致 Github 發生 timout 例外。

Github 的回應是:
Github response about large diff for pull request
看起來 timeout 的問題 Github 目前也是無解,如果發生這些情況,只好先手動處理了。

2013年3月6日 星期三

多個 SSH Key 對應多個 Github 帳號


  1. 產生個別的 ssh keys
    $ cd ~/.ssh
    $ ssh-keygen -t rsa -C "account1@email.com" -f id_rsa_account1
    $ ssh-keygen -t rsa -C "account2@email.com" -f id_rsa_account2
    
  2. 建立 config 檔
    $ cd ~/.ssh
    $ touch config
    $ gedit config
    
    編輯內容如下
    #account1
    Host github.com-account1
        HostName github.com
        User git
        IdentityFile ~/.ssh/id_rsa_account1
    
    #account2
    Host github.com-account2
        HostName github.com
        User git
        IdentityFile ~/.ssh/id_rsa_account2
    
  3. 修改相對應 repo 的 remote url。例如:
    $ cd /path/to/repo1
    $ git remote set-url origin ssh://git@github.com-account1/account1/repo1.git
    
  4. 完成

Git HTTP 協定的檔案大小限制

使用 git push 經由 HTTP 協定的時候要注意了,因為有檔案大小的限制,預設是 1MB。
發生的錯誤訊息如下所示:
$ git push
Counting objects: 199918, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (188542/188542), done.
error: RPC failed; result=22, HTTP code = 413MiB | 53 KiB/s   
fatal: The remote end hung up unexpectedly
Writing objects: 100% (199918/199918), 1.98 GiB | 7.61 MiB/s, done.
Total 199918 (delta 55401), reused 0 (delta 0)
fatal: The remote end hung up unexpectedly
fatal: expected ok/error,...

有兩種方式可以解決這個問題:
  1. 使用 SSH 來作為 git 的通訊。
  2. 加大 HTTP 檔案大小限制,如下:
    git config http.postBuffer 524288000 #Set to 500MB
    

2013年2月15日 星期五

Yii 安裝 Bootstrap

安裝方法:
http://www.cniska.net/yii-bootstrap/setup.html

Github 版的 Yii Bootstrap 可以從這邊取得:
https://github.com/joujiahe/yii-bootstrap

注意: 需將 webapp/protected/extensions/bootstrap/theme/* 下的檔案複製到
webapp/themes/bootstrap/ 

Yii 使用偽靜態網址

在 webapp 下新增一個 .htaccess 檔,並將以下內容複製貼上:
RewriteEngine on

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# otherwise forward it to index.php
RewriteRule . index.php

修改 webapp/protected/config/main.php 設定檔來啟用 urlManager:
		// uncomment the following to enable URLs in path-format
		'urlManager'=>array(
			'urlFormat'=>'path',
			'showScriptName'=>false,
			'urlSuffix'=>'.html',
			'rules'=>array(
				'<controller:\w+>/<id:\d+>'=>'<controller>/view',
				'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
				'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
			),
		),
這樣就可以將 index.php 藏起來並偽裝成 .html 的網址了。

2013年2月7日 星期四

Yii 抽象資料庫欄位類型的支援



Yii Migration 支援多種抽象欄位類型,如下所示:
  • pk: an auto-incremental primary key type, will be converted into "int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY"
  • string: string type, will be converted into "varchar(255)"
  • text: a long string type, will be converted into "text"
  • integer: integer type, will be converted into "int(11)"
  • boolean: boolean type, will be converted into "tinyint(1)"
  • float: float number type, will be converted into "float"
  • decimal: decimal number type, will be converted into "decimal"
  • datetime: datetime type, will be converted into "datetime"
  • timestamp: timestamp type, will be converted into "timestamp"
  • time: time type, will be converted into "time"
  • date: date type, will be converted into "date"
  • binary: binary data type, will be converted into "blob"


2013年1月31日 星期四

整合 Mantis 與 Gitolite

前陣子整合了公司的 mantis 和 gitolite,主要的目的就是要讓開發人員 push commits 到 gitolite 的時候,能夠同時更新 mantis 的 issue ,方便持續追蹤。

要完成這樣的功能,關鍵就在 git 的 post hooks,完整架構如下:
整合 Mantis 與 Gitolite

如上圖所示,當 gitolite 中的 git repo 收到開發人員的 commits 時,post hooks 會被呼叫,對應到的 hook 檔是 post-receive,與 svn 的 post-commit 不同,如下圖所示:
Post hook 的過程

瞭解了大概的架構之後,開始著手進行 post-receive 的撰寫。Gitolite 共用的 hooks 檔案位於 "/usr/share/gitolite/hooks/common/*",找到我們要的 post-receive 後開始編輯。
# 讀取輸入的物件檔案
while read oldrev newrev ref
do
    # 取得 commit 資訊
    subj=`git show -s --format="%s" $newrev`
    diff=`git show $newrev...$oldrev`
    msgs="$subj
$diff"
    # 將資訊餵給用來跟 mantis 同步的 perl 程式
    /home/gitolite/git2mantis.pl "$msgs"
    ...
done

這段 post hook 的目的是將收到的 git commit 資訊讀出來,然後餵給一隻 perl 程式來進行處理。撰寫完這個 hook ,還必須執行 gl-setup,這樣才會把這個 hook 放到每一個 git repo 下。

接下來,來看看 "/home/gitolite/git2mantis.pl" 做了什麼事情。
#!/usr/bin/perl
#
# 使用者 mantis 的 ssh key 必須在 192.168.26.103 主機上設定好,
# 才能允許自動登入。
$host = "mantis@192.168.0.1";

$sshcmd = "/usr/bin/ssh ";
$phpcmd = "/usr/bin/php";

# mantis 的 checkin 程式
$checkincmd = "/var/www/mantis/scripts/checkin.php";

$msg = $ARGV[0];

# 透過 ssh 來執行遠端主機的程式
`$sshcmd $host $phpcmd $checkincmd <<< "$msg"`;

這隻 perl 程式的工作就是把收到的訊息,透過 ssh 的方式,傳送給遠端的程式並且執行。

就這樣,完成了簡易的 mantis 和 gitolite 的整合,可以使用 mantis 來追蹤 git 的開發過程了。

2013年1月28日 星期一

繼承 Yii Framework 中的 AR 類別

關聯式資料庫並不支援繼承,但是,我們可以藉由繼承 AR 的方式來產生子類別繼承。什麼時候會需要繼承 AR 呢?最常見的情況應該是使用者分角色的時候,

例如:網站的使用者,區分為管理員、一般和進階使用者。不管哪一種角色都使用同一個資料表,並藉由繼承 User AR 的方式來產生各自的 AR。

Yii 官方維基有一篇介紹文章,使用 Car AR 來繼承產生 Sport Car 和 Family Car。寫得簡單明瞭,可以參考看看:
http://www.yiiframework.com/wiki/198/single-table-inheritance/

2013年1月24日 星期四

Git 有沒有像 SVN Export 一樣的功能?

答案是,沒有。

在 Git 中,沒有 export 這樣的指令來將程式碼輸出。

但是,Git 有提供封存(archive)的功能,稍微作點變化就可以達到像 svn export 一樣的功用。如下所示:
# 將當前狀態封存,並取出至指定位置
$ git archive HEAD | tar -x -C /path/to/export

在 Git 中建立一個空的 branch

到 Git 庫裡面下指令:
# 建立一個獨立的分支
$ git checkout --orphan empty-branch

# 清空所有東西
$ git rm -rf .

2013年1月23日 星期三

存取 Struct 中的欄位

存取 C Struct 中的欄位,可分為變數和指標兩種型態來存取,存取方式如下所示:
// 如果是變數:
fish.age

// 如果是指標:
(*fish).age
// 或
fish->age

2013年1月20日 星期日

建立 Ubuntu 的 Live USB

從 Ubuntu 11.04 以後,就開始支援 live USB 了。所以,不再需要額外的工具建立 bootable USB,直接使用下載的 ISO 檔來建立 live USB。

建立方法如下:

$ cat ubuntu-12.10-desktop-amd64.iso > /dev/sdb


注意, sdb 是 usb 裝置的位置,實際位置依狀況會有所不同。

接下來,就可以進入 BIOS 更改開機順序為 USB 優先,然後插入 USB 之後就可以開始進行安裝了!

2013年1月16日 星期三

陣列的索引值

陣列的索引值是指,距離第一個字元的偏移量(offset)。

例如:第一個字元 a[0],第二個字元 a[1],以此類推。

會有這樣的設計因為陣列指標是直接指向記憶體位址的,透過偏移量的方式可以直接運算,來取得其他元素的位置。

為什麼 Mac 或 Linux 執行程式要加上 ./?

為什麼常常在 Mac 或是 Linux 中執行程式都要加上 ./

例如:./a.out。

這是因為在 Unix 形式的作業系統裡,要求執行的程式必須包和路徑位置,除非該路徑已被列在環境變數當中。

C 語言種類

C 語言有三種,依時間順序為:
  • C89 (1989,常被稱作 ANSI C)
  • C99 (2000)
  • C11 (2011)

C99 開始支援 // 的註解形式。

C 語言特性:
  • 不支援現成的字串,而是由字元陣列取代。