2012年12月27日 星期四

SSH登入到遠端機器不用輸入password

偷懶一下
這次不自己打了
直接附上link
http://www.csua.berkeley.edu/~ranga/notes/ssh_nopass.html

2012年12月26日 星期三

讓git push變成default push到code review server

假設local 端clone了一份 git project, 現在修改完後要準備push上去
如果單純只是下
   git push
的話, 會變成直接push 到 git server (假設權限允許的話)

但是現在如果多了一道 code review 的流程, 那要如何讓 git push 是先push 到 code review server呢?
一個方法是使用如下command
git push origin HEAD:refs/for/master
如果不想每次都打這麼長或忘記了直接打git push而造成bypass 了 code review階段
那可以在clone下 git project後, 先打下述指令來設定
git config remote.origin.push refs/heads/*:refs/for/*
之後的git push就會先push到code review server了

2012年12月25日 星期二

[C++] Move Semantics,Perfect Forwarding, and Rvalue references

關於C++11所引進的新技術
move semantics, perfect forwarding, and rvalue reference
一定要看Scott Meyers的介紹, 仔細看絕對可以把這些東西弄清楚
http://skillsmatter.com/podcast/home/move-semanticsperfect-forwarding-and-rvalue-references

等吸收完後再來整理重點吧.... 

[C++] Lvalue reference and Rvalue reference

Rvalue reference是從C++11正式被引入的一個屬性
而由於它的引入, 讓move semantics被介紹出來

move constructor與copy constructor不同處在於
較少的memory allocation/de-allocation 和copy, 因此效能也會比較好
Move Constructor不在此文中介紹, 就留待下篇文章吧!

以下節錄自(http://binglongx.wordpress.com/2010/08/20/c0x-rvalue-reference/)
===============================================================
In C++0x (see N2844N2812), the rules are (with const correctness in mind):
  • lvalue reference T& binds to modifiable lvalues only; (making no sense to modify a temporary) (!VC10 is different)
  • lvalue reference T const& (i.e., const T&) binds to all modifiable/const lvalues and rvalues; (harmless const reference)
  • rvalue reference T&& binds to modifiable rvalues only; (do not steal resource from a non-temporary )
  • rvalue reference T const&& (i.e., const T&&) binds to modifiable and const rvalues;
Because a reference itself is an expression, there are rules regarding whether it’s lvalue or rvalue:
  • Named lvalue reference is lvalue;         T& tr = t; // tr is lvalue.
  • Unnamed lvalue reference is lvalue;      std::vector tv; tv.at(); // tv.at() is lvalue, backing object is non-temporary.
  • Named rvalue reference is lvalue;         void foo(T&& t){ // t is lvalue, t’s type is rvalue reference.
  • Unnamed rvalue reference is rvalue;
Named rvalue reference is lvalue. This is convoluted and confusing, isn’t it? In the function body of void foo(T&& t), t is bound to an afloat rvalue object in the caller’s site, from which you can steal its guts, but t itself is lvalue. That means, if you try to pass t in this function to another function, the other function would perceive t as lvalue, and therefore t loses its rvalue-ness. Why? The reason that a named rvalue reference is a lvalue, is because with a name it can be referred to by many occurrences, and obviously not all of these occurrences can steal its resource. If this is not enforced, in the function body of void foo(T&& t), if t is passed to two other functions that expect rvalue, which of them should take t’s guts? No matter which, the program is ill-fated. C++0x makes sure the program is safe by giving the two functions only lvalue so they cannot steal from t. Once you understand this, it is no longer confusing.
================================================================
lvalue reference: 可以想像成是一個物件的另一個名字, 也就是傳統c++所指的reference; reference必須是已經被初始化且不可被改變的. 宣告方法就是type&
例如:
int a = 1;
int &b = a; // it is a lvalue reference, reference to a object

rvalue reference: 與lvalue reference很像, 但是不同的地方是rvalue reference can bind to a temporary (rvalue), 但是 (non-const)lvalue reference can't bind to a rvalue. 宣告方法為 type&&
這個可以回顧一下之前的Lvalue 與 Rvalue的定義說明以及lvalue reference的說明(reference必須是已經被初始化且不可以被改變的)
例如:
A a;
A&& a_ref = a; // an rvalue reference
A& a_ref2 = A(); // Error
A&& a_ref3 = A(); // OK

Reference

[C++] Lvalues and Rvalues

Lvalue and Rvalue在C++裡面算是一個很重要的觀念
但是一直都沒搞得很懂, 所以常常看一些技術文件時都還是霧煞煞
這邊就暫時間做點筆記吧

Lvalue: 就是一個運算式後還保留其狀態的一個物件 就是Lvalue; 也就是說 所有的變數(variables)包含nonmodifiable, const 的變數都是Lvalue.  這邊一個重點是 const的變數也是Lvalue
Lvalue is a 1. named object. 2. lvalue reference.

Rvalue: 就是一個運算式過後其狀態就不會被保留了, 也就是一個暫存的數值
Rvalue is an unnamed temporary object

另一種說法(非完全正確,  但是可以依此來稍做判斷)
能出現在assignment 運算子(=)的左邊的稱為Lvalue, 而只能出現在右邊的稱為Rvalue

這邊只有說出現在左邊的是Lvalue, 但沒說Lvalue不能出現在右邊, 因此Lvalue在=運算子的左右兩邊都是被允許的, 而Rvalue是不能出現在左邊的; 這邊有沒有注意到, Lvalue是可以被放到右邊的, 也就是說Lvalue也可以被當作Rvalue, 但是Rvalue就不能被當作是Lvalue

但是Lvalue有個例外就是了, 屬於non-modifiable的Lvalue也是不允許出現在= 運算子的左邊的, 因為它(non-modifiable)是沒辦法被修改的, 出現在左邊就違反了non-modifiable的特性.
而non-modifiable Lvalues有哪些呢? 包含了有
1. An array type
2. An const-qualified type
3. An incomplete type
4. A structure or union type with one of its members qualified as a const type

以下是一些運算子的要求

Operator
Requirement
& (unary) Operand must be an lvalue.
++ -- Operand must be an lvalue. This applies to both prefix and postfix forms.
= += -= *= %= <<= >>= &= ^= |= Left operand must be an lvalue.


另外 in C++, a function call that returns a reference is a Lvalue. Otherwise, a function call is a Rvalue expression.
例子:


Expression
Lvalue
x = 42 x
*ptr = newvalue *ptr
a++ a
 int& f() The function call to f()



接下來就是更加複雜抽象的Lvalue Reference and Rvalue Reference了
這在就在下一篇文章在紀錄

reference:
1. http://msdn.microsoft.com/en-us/library/f90831hc.aspx
2. http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Flvalue.htm




2012年12月19日 星期三

[ubuntu] 將使用者加入某個group

$ sudo usermod -a -G GROUP-NAME UserName

2012年12月18日 星期二

讓ubuntu也能auto sync Box.com的資料

由於買了sony的手機 於是有了50G的Box可以免費使用(比dropbox的空間多好多) 但是偏偏他提供的client工具並沒有給linux的 但是網路上就是有人有辦法讓ubuntu也能在local端使用Box.com並且自動的同步
廢話不多說, 步驟如下
一. $ sudo apt-get install davfs2 $ sudo chmod u+s /sbin/mount.davfs $ sudo usermod -a -G davfs your-ubuntu-user-account $ sudo vim /etc/fstab 將下行貼上去 (記得要將your-ubuntu-user-account換成你自己的account name) https://www.box.com/dav /home/your-ubuntu-user-account/box.com davfs rw,user,noauto 0 0 $ cd ~ $ mkdir box.com $ mount box.com/ 然後就會提示你要輸入你的box user account (full email) 和 password 另外如果不想要每次都輸入帳號密碼, 可以多做以下動作 $ sudo vim /etc/davfs2/secrets 打入這行內容 https://www.box.com/dav box-user-account box-password 這樣做之後就可以設定成auto mount, 也就是將/etc/fstab的內容從noauto 改成 auto reference: http://dev.modmancer.com/index.php/2011/12/17/access-box-com-box-net-from-your-ubuntu/

Revert/undo commit

git reset --soft HEAD^ reference: http://stackoverflow.com/questions/927358/undo-last-git-commit

檢查client與gerrit server的connection是否正常和正確設定code review

方法如下:
ssh -p PORT User@HostName
如果運作正常, 那應該會顯示下面訊息:
(如果port = 29418)
  $ ssh -p 29418 sshusername@hostname

    ****    Welcome to Gerrit Code Review    ****

    Hi John Doe, you have successfully connected over SSH.

    Unfortunately, interactive shells are disabled.
    To clone a hosted Git repository, use:

    git clone ssh://sshusername@hostname:29418/REPOSITORY_NAME.git

  Connection to hostname closed.


另外, 該如何知道Gerrit server所使用的port number呢?
可以用這個方法
curl http://HostName/ssh_info
這時候就會獲得下述訊息
HostName PORT

這個查詢port number的方法所輸入的url還需要依據實際情況作修正, 以現在公司的情況來說, server的url是http://HostName/DHC
因此如果要查詢 port number 則使用的指令就為
curl http://HostName/DHC/ssh_info

另外 其實這同時也就是code review server的url , 這部份也讓我在編輯repo manifest file時卡好久, 一直無法使用repo upload正確的自動upload commits到code review server

以公司為例, repo manifest file的review欄位就必須要寫成
fetch="ssh://HostName:PORT" review="HostName/DHC" /> remote="yyyy" sync-j="4" /> ........... ..........
reference: https://review.openstack.org/Documentation/user-upload.html

2012年12月17日 星期一

更改git的editor

由於習慣用vim, 所以如果要將git 的editor改成vim的話 可以用下述的指令
git config --global core.editor vim

2012年12月14日 星期五

當你自己的client account與gerrit server上的帳號不一致時, 可以藉由SSH config的設定來達到便利使用目的

首先由於我自己ubuntu的帳號與公司使用的gerrit帳號是不一樣的
所以導致每次我要git clone or repo init 時都要特別指定使用者帳號, 後來查到其實可以設定ssh config來省略一些動作
設定如下
edit ~/.ssh/config
內容如下

Host 名稱
    HostName 主機名稱
    Port 連接阜
    User 帳號

而我自己的設定如下
Host gerrit-server
    HostName gerrit-server
    Port 20002
    User hamer.sun

Reference: 
http://www.lainme.com/doku.php/blog/2011/01/%E4%BD%BF%E7%94%A8ssh_config

mirror android source to an internal git/gerrit server

花了好長一段時間 目前看來終於有初步結果了
就以git://github.com/MIPS/ 為例子

步驟一:
首先創建一個 mirror的參考project, 重點是把相關的access control permission設好, 之後要mirror的project都繼承自該project, 或者是去修改ALL-Projects 的 access permission, 至於要設哪些permission其實我還不是很清楚, 反正我就幾乎全開了XD,  如下:


Rights Inherit From:
Reference:
refs/for/*
Push

Push Merge Commit

Reference:
refs/heads/*
Read


Create Reference

Forge Author Identity

Forge Committer Identity

Forge Server Identity

Push

Push Merge Commit

Push Annotated Tag

Label Code-Review
 
 
Rebase

Submit

Reference:
refs/meta/config
Read

Create Reference

Forge Author Identity

Forge Committer Identity

Forge Server Identity

Push

Push Merge Commit

Push Annotated Tag

Submit

Reference:
refs/tags/*
Read

Create Reference

Forge Author Identity

Forge Committer Identity

Forge Server Identity

Push

Push Merge Commit

Push Annotated Tag

Submit

步驟二:
1. mkdir mirror-folder
2. repo init -u git://github.com/MIPS/manifests.git --mirror
3. repo sync -j4
4. repo forall -c 'ssh -p PORT ACCOUNT@SERVER gerrit create-project PROJECT_ROOT/$REPO_PROJECT;  \
    ssh -p PORT ACCOUNT@SERVER gerrit set-project-parent --parent mirror-project-permission-base PROJECT_ROOT/$REPO_PROJECT; \
    git push ssh://ACCOUNT@SERVER:PORT/PROJECT_ROOT/$REPO_PROJECT 'refs/heads/*' 'refs/tags/*' 'refs/notes/*''


note: 紅色字的部份很重要, 這是試了好多種方式後目前可行的方式

步驟三:
1. 接下來就先去 git clone 其manifests的project的下來 修改其xml file, 使其fetch/review的url能對應到internal server

1. git clone ssh://ACCOUNT@SERVER:PORT/PROJECT_ROOT/manifests
2. 將default.xml 的fetch and review URLs改成internal server, 例如
             fetch="git://github.com/MIPS"
             remote="mips"
             sync-j="4"
==>  
           fetch="ssh://SERVER:PORT/PROJECT_ROOT"
           review="SERVER:PORT"
           remote="mips"
           sync-j="4"

然後push回server

步驟四:
接下來就可以照repo init & repo sync的動作來將整包source tree 都 checkout回來, 如
1. repo init -u ssh://ACCOUNT@SERVER:PORT/PROJECT_ROOT/manifests
2. repo sync

Reference:
https://groups.google.com/forum/?fromgroups=#!topic/repo-discuss/zpqpPpHAwSM
https://wiki.linaro.org/Platform/Infrastructure/GerritNotes
https://groups.google.com/forum/?fromgroups=#!topic/repo-discuss/qXBILfjVV04
https://groups.google.com/forum/?fromgroups=#!msg/repo-discuss/F8wQCreKv4c/L3DOAPPiQpMJ

2012年12月12日 星期三

指令:列出remote server有哪些projects

列出remote server有哪些projects

ssh -p port-number user-account@gerrit-server gerrit ls-projects

透過指令來創建遠端的git project


Create a new project called tools/gerrit:
$ ssh -p 29418 review.example.com gerrit create-project tools/gerrit.git
Create a new project with a description:
$ ssh -p 29418 review.example.com gerrit create-project tool.git --description "'Tools used by build system'"

詳情可以參考

https://review.openstack.org/Documentation/cmd-create-project.html

git clone時發生permission denied (publickey)

當我第一次使用git clone command時發生了 permission denied (publickey) 的錯誤訊息
但是明明我已經在Gerrit server上的個人設定指定好了SSH public key
後來經由同事的告知 才知道原因是因為client端的使用者帳號與server端的不一致所造成

參考這個網站 http://gerrit.googlecode.com/svn/documentation/2.2.1/error-permission-denied.html
其實就可以知道, 當在使用git clone時 是可以指定user account的

因此第一步如果要確認你的設定是否正確 可以使用這個指令來確認
ssh -vv -p port-number user-account@server-address

如果成功就會出現以下訊息

  ...

  debug1: Authentication succeeded (publickey).

  ...

  ****    Welcome to Gerrit Code Review    ****

  Hi John Doe, you have successfully connected over SSH.

  Unfortunately, interactive shells are disabled.
  To clone a hosted Git repository, use:

  git clone ssh://user-account@server-address:port-number/REPOSITORY_NAME.git

因此如果你的client端的user account與git server端的不一樣
那正確clone的指令是要在server-address前面加上user-account@

2012年12月11日 星期二

產生SSH key for Gerrit/Git server

在設定code review server (Gerrit + Git) 的帳號時 當使用的是SSH protocol則會需要設定好你自己的SSH public key, 設定方法如下

A. 產生SSH keys
  1. 檢查你的home目錄下是否存在.ssh資料夾, 如果存在就先備份該資料夾內的東西, 然後移除該資料夾
  2. 產生SSH keys
      ssh-keygen -t rsa -C "your_email@youremail.com"
     跳出提示問題時 直接按enter就好
 3. 接下來會要你輸入passphrase, 如果你在乎的話就輸入字串, 不然直接按enter也可以

B. 將public key內容複製貼上到Gerrit server上的SSH Public keys
     public key 位在 ~/ssh/id_rsa.pub

也可以參考此網站
https://help.github.com/articles/generating-ssh-keys


2012年12月6日 星期四

安裝sun-java6-jdk失敗

當我安裝好ubuntu 12.04後 依照AOSP上的動作來設定環境時 當在安裝java jdk發生了錯誤
錯誤訊息如下:


Package sun-java6-jdk is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source
E: Package sun-java6-jdk has no installation candidate

 
解決方式可以參看 https://github.com/flexiondotorg/oab-java6
基本上步驟為

cd ~/
wget https://github.com/flexiondotorg/oab-java6/raw/0.2.6/oab-java.sh -O oab-java.sh
chmod +x oab-java.sh
sudo ./oab-java.sh
更正, 上述方法安裝後的java 6版本無法用來編譯android. 後來又google了一下後
其中ubuntu論壇上的參考網頁
https://help.ubuntu.com/community/Java

下述這個方法確定可用
安裝jdk6 # sudo add-apt-repository ppa:webupd8team/java # sudo apt-get update # sudo apt-get install oracle-java6-installer or 安裝jdk7 # sudo add-apt-repository ppa:webupd8team/java # sudo apt-get update # sudo apt-get install oracle-java7-installer
另外一開始其實有碰到安裝jdk7 failed的情況 錯誤訊息如下: dpkg: error processing oracle-java7-installer (--configure): subprocess installed post-installation script returned error exit status 1 No apport report written because MaxReports is reached already Errors were encountered while processing: oracle-java7-installer E: Sub-process /usr/bin/dpkg returned an error code (1)

解決方式就是先完全移除jdk, 移除方法如下
# sudo rm /var/lib/dpkg/info/oracle-java7-installer* # sudo apt-get purge oracle-java7-installer* # sudo rm /etc/apt/sources.list.d/*java* # sudo apt-get update
除除後再依照上述步驟重新安裝jdk就可以了

2012年12月5日 星期三

我的linux console環境設定

1. 第一部分是 ls 的 顏色設定, 預設的ls所列出來的directory顏色是深藍色, 這個在螢幕上看起來很吃力, 所以就把它改成淺藍色如下
# declare -x  // 會列出系統相關的設定值, 其中"LS_COLORS"就是ls的顏色設定值
default value為
LS_COLORS="no=00:fi=00:di=00;34:ln=00;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:"
改成了
LS_COLORS="no=00:fi=00:di=01;36:ln=02;36:pi=40;33:so=00;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=00;32:*.cmd=00;32:*.exe=00;32:*.com=00;32:*.btm=00;32:*.bat=00;32:*.sh=00;32:*.csh=00;32:*.tar=00;31:*.tgz=00;31:*.arj=00;31:*.taz=00;31:*.lzh=00;31:*.zip=00;31:*.z=00;31:*.Z=00;31:*.gz=00;31:*.bz2=00;31:*.bz=00;31:*.tz=00;31:*.rpm=00;31:*.cpio=00;31:*.jpg=00;35:*.gif=00;35:*.bmp=00;35:*.xbm=00;35:*.xpm=00;35:*.png=00;35:*.tif=00;35:"

2. vim 的設定, 包含顏色與排版的設定(如tab鑑的定義)
# 把vim 的color scheme放到 ~/.vim/colors/
color scheme可以從這這邊選一個喜歡的download, http://vimcolorschemetest.googlecode.com/svn/html/index-c.html
# edit ~/.vimrc colorscheme slate2 # 指定color scheme set t_Co=256 # 設定用256色來顯示 set tabstop=4 # 設定一個tab 對應4個spaces set shiftwidth=4 # 設定縮排一次縮排4個spaces set expandtab # 將tab轉成space syntax on
3. edit ~/.bashrc
將下面的設定加入
alias ls='ls -F --color' alias h='history 25' alias vi='vim' PS1='\[\033[1;33m\]\u\[\033[1;37m\]@\[\033[1;32m\]\h\[\033[1;37m\]:\[\033[1;31m\]\W \[\033[1;36m\]\$ \[\033[0m\]'