2013년 4월 10일 수요일

git tag 사용하기

* Tag 조회하기
$git tag

* Tag 조회하기(message와 함께)
$ git tag --list -n

* Tag 붙이기
$git tag -a %VERSION_NUMBER% -m '%MESSAGE%'

* 나중에 Tag 붙이기
$ git tag -a %VERSION_NUMBER% %COMMIT_HASH%

* 특정 Tag 공유하기
$git push origin %TAG_NAME%

* 전체 Tag 공유하기
$git push origin --tags

* 로컬의 Tag 제거하기
$ git tag -d %TAG_NAME%

* 원격의 Tag 제거하기
$git push origin :%TAG_NAME%
or
$git push --delete origin %TAG_NAME%


2013년 3월 31일 일요일

git stash 사용하기(just save with no commit to change branch)

stash미국∙영국 [stӕʃ]

동사


[타동사][VN + adv. / prep.] (비격식) (안전한 곳에) 넣어 두다[숨기다]

작업 중이던 파일들을 commit하지 않고, branch를 변경해서 작업하고자 할 경우에 기존 작업들을 안전한 곳(git stack)에 넣어두기 위한 명령어이다.

* branch변경 시, 작업중인 파일들을 commit하지 않고 안전하게 보관하기
$git stash

* stash한 파일(들) 확인하기
$git stash list

* stash한 파일(들) 복원하기(<-- staged상태까지는 복원되지 않는다.)
$git stash apply

* stash한 파일(들) 복원하기(<-- staged상태까지 복원한다.)
$git stash apply --index

위의 apply옵션은 단순히 stash를 적용만 할 분이다. 즉, apply옵션을 사용하여 stash하게 되면,  stash된 파일(들)이 여전히 git stack에 저장되어 있다. 

* stash한 파일(들) stack에서 제거하기
$git stash drop %STASH_NUM%

* stash한 파일(들)을 적용과 동시에 stack에서 제거하기
 $git stash pop

* stash할 당시의 커밋을 checkout 한 후 새로운 브랜치를 만들고 여기에 적용하기
$ git stash branch %NEW_BRANCH_NAME%

2013년 3월 26일 화요일

git history 조회하기

* git history 조회하기
$git log

* 각 commit의 diff결과와 함께 제한된 개수의 git history 조회하기
$git log -p -%LOG_COUNT_INTEGER%

* 각 commit의 통계 정보(commit정보와 +/-량을 표시)를 포함한 git history 조회하기
$git log --stat

* 각 commit을 1라인으로 표시하는 방식으로 graph정보를 포함한 git history 조회하기
$git log --oneline --graph

git branch 사용하기

* branch를 만들면서 checkout하기
$git checkout -b %BRANCH_NAME%


* branch 삭제하기
$git branch -d %BRANCH_NAME%
예제) tnkim@tnkim-N53SV:~/git/hugomachlink$ git branch -d add_cmd_inputgps_git207 
          Deleted branch add_cmd_inputgps_git207 (was c05836e).


* branch 목록보기
$git branch
예제) tnkim@tnkim-N53SV:~/git/hugomachlink$ git branch
                add_cmd_inputgps_git207
               * master


* 마지막 커밋메시지와 함께 branch 목록보기
$git branch -v
예제) tnkim@tnkim-N53SV:~/git/hugomachlink$ git branch -v
               add_cmd_inputgps_git207 c05836e add input gps function and caller
              * master                  c94a1bb trivial: 예외처리 코드 추가 및 코드 정리


* merged branch 목록보기 (<-- merged branch라면 삭제대상이 되는 branch이다.)
$git branch --merged
예제) tnkim@tnkim-N53SV:~/git/hugomachlink$ git branch --merged
        add_cmd_inputgps_git207
       * master


* no-merged branch 목록보기(<-- no-merged branch라면 merge되어야 하는 대상이 되는 branch로서 삭제하면 안된다.)
$git branch --no-merged


* branch 공유하기
$git push (remote) (branch)
예제) tnkim@tnkim-N53SV:~/git/fx500machlink$ git push origin fx500machlink_with_standardtimeout 
Counting objects: 13, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 585 bytes, done.
Total 7 (delta 3), reused 0 (delta 0)
To gitolite@sf.thinkware.co.kr:tnkim/fx500machlink.git
 * [new branch]      fx500machlink_with_standardtimeout -> fx500machlink_with_standardtimeout


* 공유된 branch에 코드 push하기
master branch에서와 동일하다.
local에 있는 branch한 뒤에 git push하면 해당 remote branch로 코드 push된다.


tnkim@tnkim-N53SV:~/git/fx500machlink$ git commit -m 'trivial: 불필요한 코드제거'
[fx500machlink_with_standardtimeout 8f44b60] trivial: 불필요한 코드제거
 1 file changed, 8 deletions(-)
tnkim@tnkim-N53SV:~/git/fx500machlink$ git push
Counting objects: 13, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (7/7), 561 bytes, done.
Total 7 (delta 3), reused 0 (delta 0)
To gitolite@sf.thinkware.co.kr:tnkim/fx500machlink.git
   ce7c426..8f44b60  fx500machlink_with_standardtimeout -> fx500machlink_with_standardtimeout

2013년 3월 10일 일요일

unit test에 대한 생각


급한 프로젝트를 진행하면서 항상 갈등에 빠지는 것이 있습니다.

unit test를 만드느냐, 만들지 않느냐, 아니면, 어느정도 까지 만드느냐...
보통은 위와 같은 갈등을 하다가... 바쁘니까(^^)  주어진 시간이라는 리소스를 설계와 개발에 집중을 하기 위해서 다음을 기약합니다.

그런데 프로젝트를 진행하다보면 unit test를 만들어 뒀으면 좋았을 경우를 자주 만나게 됩니다.

  1. 다른 사람 또는 다른 팀에서 전달해 주는 라이브러리를 사용하는 경우 해당 라이브러리를 사용하기 전에 라이브러리를 체크하기 위해 각 인터페이스에 대한 unit test를 만들어 두었다면,
    1. 해당 라이브러리에 의해 발생할 수 있는 다양한 삽질을 미연에 방지하여 리소스를 절약 할 수 있습니다.
    2. 라이브러리 배포 시점에 간단하게 한번만 돌려서 이상 여부를 리포트 할 수 있습니다. 이또한 리소스 절약이 될 수 있네요.
    3. 만약 사용하는 사람이 n명 이라면 절약된 리소스 * n 정도가 절약 될 수 있겠네요.
  2. UI시나리오 별로 unit test를 만들어 두었다면,
    1. 프로그램의 형상을 유지하기 쉽다. 즉, 수정작업에 의해 발생할 수 있는 side-effect를 unit test에 의해 막을 수 있습니다.(물론, 어느정도의 unit test를 구성해 뒀느냐에 대한 차이는 있습니다.^^)
      1. QA검증을 할 수 있는 프로젝트 환경이라면, 더 큰 필요성이 느껴집니다. 그 이유는 side-effect에 대한 비용이 너무나도 크기 때문입니다. 비용은 아래와 같습니다.
        1. QA인력이 테스트 하여 이슈로 등록한다.
        2. (여러 프로젝트가 같이 진행되는 환경이라면) 프로젝트 관리자들에 의해 해당 이슈가 누구의 이슈인지 구분되어야 한다.
        3. 구분된 이슈는 각 프로젝트 개발자가 확인하여 해당 이슈가 자신의 이슈인지 다른 프로젝트의 이슈인지 확인해야 한다.
        4. [반복] 중간 중간 QA인력 또는 프로젝트 관리자에 의해 이슈가 어떤 상태인지 관리가 되어야 한다.
        5. [반복] 관리되는 이슈는 weekly 회의와 같은 회의를 통해 보고되고, 논의되어야 한다.
    2. UI시나리오에 대한 설계서를 조금더 꼼꼼하게 검토해서 구현하게 되는 부가적인 이점을 가질 수 있습니다.
      1. QA검증 이슈에 등록되지 않아서 위에서 언급한 2-1-1에서 발생하는 리소스를 절약할 수 있습니다.
    3. 배포 이전에 개발자가 수행할 수 있는 레벨의 테스트를 자동으로 수행할 수 있다.

우선은 생각나는 대로 unit test를 만들어 두었다면 좋았을 만한 점들을 정리해 보았습니다.

사실은 정리된 점들 뿐아니라 자신이 만든 프로그램에 대한 자신감, 애착을 가질 수 있고, 개발 초기단계 부터 unit test를 생각하면서 설계에 들어 간다면, 테스트를 위해 각 모듈이 분리되는 것에 의해 프로그램이 자연스럽게 커플링이 줄어드는 설계 및 구현이 될 수 있다라는 장점도 가지게 됩니다.

  마지막으로 unit test에 대한 제 생각을 정리해보겠습니다.
프로토타입을 통한 데모를 보여줘야 하는 프로그램이 아니라면, 전체 프로젝트의 리소스 절약차원에서 반드시 필요합니다. 그렇다고, (경험상) 프로젝트 관리자가 unit test를 위한 일정을 주려고는 하지 않습니다. 따라서, 개발자가 자신의 시간을 쪼개어 unit test 에 대한 경험을 조금씩 늘여 가면서 unit test set을 구성하는 시간을 줄여 가는 노력이 필요합니다. 그렇게 경험을 쌓아 가다보면 짧은 시간에 unit test를 구성할 수 있는 개발자 개개인의 역량이 쌓일 것이고, 그런 역량은 개발자로서의 자기만족과 함께 자연스레 더나은(?) 개발자가 될 수 있는 지름길이 될 것입니다.


2013년 2월 27일 수요일

SharedPreference의 사용범위(access range)

결과 부터 말하면, 사용범위는 one-process(MODE_PRIVATE에 의해)와 multi-process(MODE_MULTI_PROCESS에 의해) 입니다.

참고 사항

  1. MODE_MULTI_PROCESS는 Gingerbread(Android2.3)까지는 always on이었으나, 이후 버전 부터는 기본적으로 off되었다고 하니, 여러개의 process에서 공유하려면, MODE_MULTI_PROCESS를 명시적으로 이용하여 getSharedPreferences()를 이용해야 겠네요.
  2. MODE_WORLD_READABLE과 MODE_WORLD_WRITEABLE은 위험해서 deprecated(API level17에서) 되었습니다.


public abstract SharedPreferences getSharedPreferences (String name, int mode)

Added in API level 1
Retrieve and hold the contents of the preferences file 'name', returning a SharedPreferences through which you can retrieve and modify its values. Only one instance of the SharedPreferences object is returned to any callers for the same name, meaning they will see each other's edits as soon as they are made.
Parameters
nameDesired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
modeOperating mode. Use 0 or MODE_PRIVATE for the default operation, MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE to control permissions. The bit MODE_MULTI_PROCESS can also be used if multiple processes are mutating the same SharedPreferences file. MODE_MULTI_PROCESS is always on in apps targetting Gingerbread (Android 2.3) and below, and off by default in later versions.
Returns
  • Returns the single SharedPreferences instance that can be used to retrieve and modify the preference values.




public static final int MODE_PRIVATE

Added in API level 1
File creation mode: the default mode, where the created file can only be accessed by the calling application (or all applications sharing the same user ID).
Constant Value: 0 (0x00000000)

public static final int MODE_WORLD_READABLE

Added in API level 1
This constant was deprecated in API level 17.
Creating world-readable files is very dangerous, and likely to cause security holes in applications. It is strongly discouraged; instead, applications should use more formal mechanism for interactions such as ContentProvider, BroadcastReceiver, and Service. There are no guarantees that this access mode will remain on a file, such as when it goes through a backup and restore. File creation mode: allow all other applications to have read access to the created file.
Constant Value: 1 (0x00000001)

public static final int MODE_WORLD_WRITEABLE

Added in API level 1
This constant was deprecated in API level 17.
Creating world-writable files is very dangerous, and likely to cause security holes in applications. It is strongly discouraged; instead, applications should use more formal mechanism for interactions such as ContentProvider, BroadcastReceiver, and Service. There are no guarantees that this access mode will remain on a file, such as when it goes through a backup and restore. File creation mode: allow all other applications to have write access to the created file.
Constant Value: 2 (0x00000002)