2013년 5월 31일 금요일

Lombok을 활용하여 소스 코딩량을 줄이며 가독성을 높이기

lombok활용

Lombok을 활용하여 소스 코딩량을 줄이며 가독성을 높이기

Java 클래스를 코딩할 때 대부분의 필드 변수에 Getter/Setter 메소드를 만들어야 한다. 이는 지루하고 귀찮은 작업이다. Lombok을 사용하면 어노테이션을 통해 Getter/Setter 메소드를 자동 생성할 수 있다.

Lombok을 사용한 코드를 살펴보자.

@Data
public class SomeEntity {
  private String name;
  private int birthYear;
  private int birthMonth;
  private int birthDay;
  private String phoneNumber;
  private Sex sex;
}

Lombok을 사용할 경우 소스의 길이가 줄어 가독성이 좋아졌음을 확인할 수 있다. Lombok은 컴파일 타임에 해당 메소드들을 자동으로 만들어낸다. 실제 소스상에는 존재하지 않는 상태로.

Getter/Setter 메소드 이외에도 Lombok을 통해 hashCode(), equals(), toString() 메소드를 자동 생성할 수 있으며, @Log나 @Slf4j 같은 어노테이션을 사용하면 log 객체도 생성이 된다.

Eclipse와 같은 IDE들이 getter/setter나 hashCode()들을 자동으로 만들어 주는데 lombok이 필요한 이유가 뭘까? Lombok을 사용하는 개발자의 블로그 내용을 인용하면

첫째는 소스 가독성이다.

습관적으로 getter/setter를 만들다 보면 사실 정말 똑같은 코드가 반복해서 생성되게 된다. 이 상황에서 유달리 다른 로직이 들어간 getter/setter가 가끔 있게 마련인데 이 때 이 특별히 튀는 이 코드를 찾아내는 것이 여간 번거로운 것이 아니다.

lombok을 사용하면 @Data 어노테이션 만으로 기본 getter/setter가 자동 생성되고, 로직이 들어가는 일부 getter/setter만 직접 구현하면 된다. 따라서 소스 코드 가독성이 매우 높아지고 유지보수성도 증대된다.

둘째로 아무리 IDE가 자동으로 getter/setter를 자동 생성해줘도 코딩 도중 지속적으로 추가되는 필드에 대해서 단순 반복 노가다를 한다는 점은 변함이 없다. 노가다 량이 줄긴 하지만. lombok은 @Data 어노테이션만 주면 그 뒤로는 신경쓰지 않아도 된다.

이클립스에 사용

lombok.jar를 실행(더블클릭 혹은 java -jar lombok.jar)후 지시데로 설정한다.

javac(Maven, Ant, Gradle)에 사용

컴파일 클래스패스에 lombok.jar를 포함시키면 된다.

References

Maven의 이해

Cygnus Unit Test 전략

2013년 4월 9일 화요일

Git, 분산 버전 관리 시스템


Git 사용법 정리

본 내용은 인사이트에서 출간한 Git, 분산 버전 관리 시스템 책 내용을 기초로 작성되었습니다.
온라인 자료 위치 : https://github.com/tswicegood

참고 문서

Pro Git : http://git-scm.com/book/ko/
Pro Git(one page) : http://dogfeet.github.com/progit/progit.ko.html
성공적인 git branching model : http://dogfeet.github.com/articles/2011/a-successful-git-branching-model.html

Git 설정하기

윈도에 git 설치 하기

msysGit 에서 최신 버전을 다운로드 한다. 설치 과정에서 PATH 설정 단계에서는 Run Git from the Windows Command Prompt 로 설정한다.
설치가 모두 완료 되었으면 Git bash를 실행하고 git --version을 입력하자. 제대로 설치되었다면 다음과 같은 결과를 얻을 수 있다.
$ git --version
git version 1.8.1.msysgit.1

git 구성 하기

Git을 이용하려면 몇 가지 정보가 필요하다. git은 분산 환경이라는 특성 때문에 사용자 이름과 이메일 주소를 제공하는 중앙 저장소가 없다. git config 명령어로 이름과 이메일 주소를 설정한다. 당연하겠지만 아래 예시에 자신의 이름을 입력하도록 하자.
$ git config --global user.name "bluehatch"
$ git config --global user.email "bluehatch@gmail.com"
설정값 확인은 git config 명령어에 --list 매게 변수를 이용한다.
$ git config --global --list
user.name=bluehatch
user.email=bluehatch@gmail.com

Git의 gui 사용하기

Git Gui는 두가지 방법으로 실행할 수 있다.
  • 시작 메뉴에서 Git Gui를 실행 후 new/clone/open 명령 사용
  • 탐색기에서 git 저장소 디렉토리를 선택한 후 마우스 우측 버튼을 클릭하여 Git Gui 선택

첫 프로젝트 만들기

저장소 생성하기

$ mkdir mysite
$ cd mysite
$ git init
Initialized empty Git repository in d:/git/mysite/.git/
이것으로 이제 프로젝트를 추적할 수 있는 Git 저장소가 생겼다. git init 명령어는 .git 디렉토리를 생성하고 여기에 저장소 메타데이터를 모두 저장한다. 그리고 현재 비어있는 mysite 디렉토리는 저장소에서 체크아웃 할 코드의 작업 트리가 된다.

변경하기

이제 빈 저장소에 파일을 추가하자. index.html 파일을 생성하고 'Hello World!'란 텍스트를 추가한다. 내용은 다음과 같다.
<html>
<body>
    <h1>Hello World!</h1>
</body>
</html>
이제 추적할 파일이 생셨으니 Git에게 이 파일을 추적하겠다는 사실을 알린다.
$ git add index.html
$ git commit -m "add in hello world HTML"
[master (root-commit) c2c433b] add in hello world HTML
1 file changed, 5 insertions(+)
create mode 100644 index.html
새로운 파일을 저장소에 추가했다. git log를 실행하여 다음과 같은 커밋 내용을 볼 수 있다.
$ git log
commit c2c433be9484dfe59ec47a08c66a2d2fbd66fa83
Author: sungjae <sungjae@nkia.co.kr>
Date:   Mon Mar 25 17:33:49 2013 +0900

    add in hello world HTML

프로젝트를 이용한 작업 시작하기

이제 저장소를 준비했으며 이미 첫 번째 파일을 추적하고 있다. 이제부터 변경 사항을 다뤄보자. html 파일에 <head><title>을 추가하자.
<html>
<head>
    <title>Hello World in git</title>
</head>
<body>
    <h1>Hello World!</h1>
</body>
</html>
방금 파일을 변경하였음을 git도 알고 있다. git status 명령어는 저장소의 현재 시점인 작업 트리의 상태를 보여준다.
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   index.html
#
no changes added to commit (use "git add" and/or "git commit -a")
이 파일을 커밋하기 위해서는 변경 사항을 스테이징(stage) 해야 한다. 스테이징 영역은 작업 트리와 저장소 사이의 버퍼 공간이다.
$ git add index.html
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unset)
#
#       modified:   index.html
#
git status 명령어를 실행하면 헤더 영역이 스테이징 전(Changes not staged for commit)에서 커밋 예정(Changes to be committed) 상태로 바뀐 것을 확인 할 수 있다.
그럼 git commit 명령어를 실행해보자.
$ git commit -m "add <head> and <title> to index" \
-m "This allows for more semantic document"
[master dc82307] add <head> and <title> to index
1 file changed, 3 insertions(+)
두 개의 -m 매개변수를 사용했다. 매개변수마다 하나의 문단으로 취급한다. git log로 메시지가 두 개의 문단으로 구성됨을 확인할 수 있다.
$ git log -1
commit dc823079c1f230b3ec62f9a0e056b343fad06df2
Author: sungjae <sungjae@nkia.co.kr>
Date:   Mon Mar 25 17:56:05 2013 +0900

    add <head> and <title> to index

    This allows for more semantic document
git log 명령어에 매개변수로 -1을 이용했다. 숫자를 변경하면 보고 싶은 커밋 개수만큼 git log의 출력을 제한할 수 있다.

브랜치 사용하고 이해하기

mysite 코드는 릴리즈 준비가 거의 끝났지만 그래도 관련된 사람들에게 승인을 받아야 한다. 승인을 기다리는 중에도 다음 버전의 새로운 기능을 추가할 수 있다.
브랜치를 이용하면 릴리즈 준비가 된 코드의 복사본을 보관할 수 있으므로 개발을 멈출 필요가 없다.
$ git branch RB_1.0 master
이 명령어는 master 브랜치에서 RB_1.0이라는 브랜치를 생성한다. Git에서 master는 기본 브랜치명이다.
이제 릴리즈 준비 중인 코드에 영향을 주지 않고도 내용을 변경할 수 있다. index.html 파일에 약력(Biography) 페이지로 가능 링크를 추가한다. </body> 태그 앞에 다음 내용을 추가하자.
<ul>
    <li><a href="bio.html">Brigraphy</a></li>
</ul>
이제 변경 사항을 커밋하자. 이번에는 조금 다른 형태의 명령어를 사용한다.
$ git commit -a
... 편집기가 실행된다. 커밋 메시지를 작성하고 저장 후 종료한다 ...
[master 78f2965] 약력 페이지 추가
1 file changed, 3 insertions(+)
-a 매개변수는 스테이징 과정을 생략하고 git에서 알고 있는 모든 변경된 파일을 커밋한다.
지금 master 브랜치를 변경했고 이는 릴리즈 브랜치에는 없는 내용이다. 릴리즈 브랜치로 변경하고 릴리즈 전에 마지막으로 내용을 수정하자. 브랜치를 변경하는 명령은 git checkout이다.
$git checkout RB_1.0
Switched to branch 'RB_1.0'
index.html을 열어두 편집기가 있다면 파일이 변경되었다고 알려준다. 조금 전에 변경한 내용은 편집기에서는 사라졌지만 master 브랜치에 잘 저장되어 있다.
릴리즈 전에 메타 태그를 추가해 보자. 메타 태그를 추가한 <head> 블럭의 내용은 다음과 같다.
<head>
    <title>Hello World in git</title>
    <meta name="description" content="hello world in Git" />
</head>
저장한 다음 변경한 내용을 커밋한다.
$ git commit -a
... 편집기가 실행된다. 커밋 메시지를 작성하고 저장 후 종료한다 ...
[RB_1.0 dad76b8] 메타 태그 작성
1 file changed, 1 insertion(+)

릴리즈 다루기

지금까지 작업한 코드의 1.0릴리즈 준비를 끝냈다. 여기에 태그를 붙혀보자.
$ git tag 1.0 RB_1.0
이 명령어는 브랜치 RB_1.0에 1.0이라는 태그를 붙혔다. git tag 명령어로 저장소 태그 목록을 볼 수 있다.
$ git tag
1.0
이제 코드에 태그를 붙혔으니, 지저분한 내용을 정리해보자. 두 개의 브랜치를 가지고 있고 커밋 내용을 서로 모른다. 2.0 기능을 개발할 마스터 브랜치는 RB1.0 브랜치에 추가한 <meta> 코드에 대해서 알아야 한다.
이 때 git rabase명령어를 이용한다. 새로운 기준 설정은 한 브랜치의 변경 사항을 가져와 다른 브랜치에 적용한다.
현재의 저장소는 다음 그림과 같다.
재정렬 전 mysite 저장소
git rebase 명령어로 재정렬하게 되면 다음 그림과 같아진다.
재정렬 후 mysite 저장소
먼저 마스터 브랜치로 전환하자.
$ git checkout master
Switched to branch 'master'
그 다음에 rebase 명령어를 실행한다.
$ git rebase RB_1.0
First, rewinding head to replay your work on top of it...
Applying: 약력 페이지 추가
저장소 구조가 '약력 페이지 추가'가 이제 RB_1.0 브랜치의 마지막 커밋 이후에 위치한다.
정리 작업의 마지막은 릴리즈 브랜치의 삭제다. 뭔가 위험해 보이지만 걱정할 필요는 없다. RB1.0 브랜치를 커밋하면서 붙혀둔 태그는 여전히 유효하므로 릴리즈 정보는 그대로다.
git branch에 -d 매개변수와 브랜치명을 더해서 브랜치를 삭제한다.
$ git branch -d RB_1.0
Deleted branch RB_1.0 (was b02c2d8).
그렇다면 릴리즈 브랜치 없이 1.0.x 브랜치에 대한 패치를 만들려면 어떻게 할까? 간단히 태그에서 브랜치를 만들면 된다.
$ git branch RB_1.0.1 1.0
$ git checkout RB_1.0.1
Switched to branch 'RB_1.0.1'
git log로 확인해 보면 RB_1.0.1 브랜치에는 오직 세 개의 커밋만 있음을 확인할 수 있다.
$ git log --pretty=oneline
dad76b86c7a08edd89f381e30aa402d5af2487f0 메타 태그 작성
dc823079c1f230b3ec62f9a0e056b343fad06df2 add <head> and <title> to index
c2c433be9484dfe59ec47a08c66a2d2fbd66fa83 add in hello world HTML

Git 브랜치

버전 관리 시스템은 모두 브랜치를 지원한다. 개발을 하다 보면 코드를 여러 개로 복사해야 하는 일들이 자주 생긴다. 코드를 통째로 복사하고 나서 원래 코드와는 상관없이 독립적으로 개발을 진행한다. 이렇게 독립적으로 개발하는 것이 브랜치다.
버전 관리 시스템에서 브랜치를 만드는 과정은 보통 고생스럽다. 브랜치를 만들고자 개발자는 수동으로 소스코드 디렉토리를 복사하는 등의 일을 해야 하고 소스코드의 양이 많으면 브랜치를 만드는 시간도 오래 걸린다.
사람들은 브랜치 모델이 Git의 최고의 장점이라고, Git이 다른 것들과 구분되는 특징이라고 말한다. 당최 어떤 점이 그렇게 특별한 것일까? Git의 브랜치는 매우 가볍다. 순식간에 브랜치를 새로 만들거나 브랜치 사이를 이동할 수 있다. 다른 버전 관리 시스템과는 달리 Git은 브랜치를 만들어 작업하고 나중에 Merge하는 방법을 권장한다. 심지어 하루에 수십 번씩이라고 해도 괜찮다. Git 브랜치에 능숙해지면 개발 방식이 완전히 바뀌고 다른 도구로 대체할 수 없게 된다.
git에서 브랜치간의 이동은 ckeckout이라는 명령을 통해 이뤄진다. 다음은 master를 checkout한 상태이다.

이미지 출처 : http://croute.me/570
다음은 다른 브랜치로 checkout한 상태이다.

이미지 출처 : http://croute.me/570
이 때, 로컬 저장소에는 물리적으로 한 세트의 소스코드만 존재한다. 따라서 git에서는 소스코드의 세트를 여러개 받아놓고 작업할 필요가 없다.

브랜치를 생성할 시기

  • 실험적인 변경 사항
    • 배포를 앞두고 있는 변경 사항과는 상관없이 원하는 작업을 할 수 있다.
  • 새로운 기능
    • 새로운 기능을 추가할 때 브랜치를 생성하고 작업이 완료되면 브랜치를 합쳐라.
  • 버그 수정
    • 버그와 관련된 변경 사항을 추적할 수 있도록 브랜치를 생성하라.
성공적인 브랜치 관리를 위해서 다음 링크를 참고하자. http://dogfeet.github.com/articles/2011/a-successful-git-branching-model.html

브랜치 생성하기

$ git branch develop
$ git branch
$ git checkout develop

브랜치 merge

브랜치를 합치는 방법이 몇 가지 있는데 대표적인 방법은 다음과 같다.
  • 바로 합치기(Straight Merge) : 하나의 브랜치와 다른 브랜치의 변경 이력 전체를 합치는 방법이다.
  • 커밋 합치기(Squashed Commit) : 한 브랜치의 이력을 압축하여 다른 브랜치의 최신 커밋 하나로 만드는 방법이다.
  • 선택하여 합치기(Cherry-picking) : 다른 브랜치의 하나의 커밋을 가져와 현재 브랜치에 적용하는 방법이다.

바로 합치기(Straight Merge)

about.html 파일을 생성하고 다음 내용을 입력하자.
<html>
<head>
    <title>About</title>
</head>
<body>
    <h1>NKIA</h1>
</body>
</html>
새파일을 생성하였으면, 다음과 같이 저장소에 추가하고 커밋한다.
$ git add about.html
$ git commit -m "add about page"
[develop 6709012] add about page
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 about.html
현재 develop 브랜치에 커밋한 내용은 master 브랜치에 존재 하지 않는다. 이제 git merge 명령어를 사용하여 두 브랜치를 합칠 수 있다.
먼저 master 브랜치로 전환하자.
$ git checkout master
Switched to branch 'master'
그 다음 git merge를 실행한다.
$ git merge develop
Updating 0575d8a..6709012
Fast-forward
 about.html | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 about.html

커밋 합치기(Squashed Commit)

브랜치에 변경한 내용들이 하나의 변경사항으로 볼 수 있다면 커밋 합치기 대상이다. 커밋 합치기는 이것저것 실험해 봐야 하는 새로운 기능을 만들거나 버그를 수정할 때 유용하다. 실험한 내용은 추적하지 않아도 되므로 커밋할 필요가 없다. 즉 마지막 결과만 필요할 뿐이다.
master 브랜치에서 contact 브랜치를 생성하고 체크아웃하자.
$ git checkout -b contact master
Switched to a new branch 'contact'
contact.html 파일을 추가한 다음 메일 주소를 입력하고 커밋하자.
$ git add contact.html
$ git commit -m "add contact file with email"
[contact f8f2fed] add contact file with email
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 contact.html
추가 메일 주소를 입력하고 다시 커밋한다.
$ git commit -m "add secondary email" -a
[contact 60e743c] add secondary email
 1 file changed, 2 insertions(+)
이제 contact 브랜치에는 두 개의 커밋이 존재한다. 두 개의 커밋을 master 브랜치에 한 개의 커밋으로 밀어 넣을 수 있다.
먼저 master 브랜치로 전환하자.
$ git checkout master
Switched to branch 'master'
git merge를 실행할 때 --squash 매개 변수를 지정하여 하나의 커밋으로 merge한다.
$ git merge --squash contact
Updating 6709012..60e743c
Fast-forward
Squash commit -- not updating HEAD
 contact.html | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 contact.html
contact 브랜치에 있는 두 개의 커밋이 워킹트리에 적용되어 스테이징 됐지만, 아직 커밋되지는 않았다.
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   contact.html
#
이제 남은건 기존에 커밋하던 방식대로 커밋하는 것이다.
$ git commit -m "add contact page"
[master 8f7742a] add contact page
 1 file changed, 2 insertions(+)
 create mode 100644 contact.html
마지막으로 커밋이력을 확인하자.
$ git log --pretty=oneline
8f7742aef8a79237233ed34f8bb7c84d1e000ec7 add contact page
670901225e975b7b8aeb238e1c363427011da12f add about page
0575d8ab82a4a0ce9acf15db2ceb732de1042b85 cvs ignore 추가
58240f490e290d0948ec4274b17da21d0e686c05 biography를 about으로 수정
b02c2d88e700a8bb1760e4d64621083e10d33767 약력 페이지 추가
dad76b86c7a08edd89f381e30aa402d5af2487f0 메타 태그 작성
dc823079c1f230b3ec62f9a0e056b343fad06df2 add <head> and <title> to index
c2c433be9484dfe59ec47a08c66a2d2fbd66fa83 add in hello world HTML
git reabase와 merge의 차이점을 살펴보자.
  • rebase는 현재 브랜치의 base가 되는 지점부터의 변경 사항을 순서대로 다른 브랜치에 적용하면서 합친다.
  • merge는 merge 할 브랜치의 최종 결과만 합친다.

이미지 출처 : http://git.mikeward.org/

충돌(conflict)다루기

먼저 git의 merge 방식을 살펴보자. git merge는 fast-forward merge와 3 way merge를 사용한다.
fast forward merge는 merge할 브랜치가 가리키고 있던 커밋이 현 브랜치가 가리키는 것보다 '앞으로 진행한' 커밋일 경우 master 브랜치 포인터는 최신 커밋으로 이동한다. 이런 Merge 방식을 'Fast forward'라고 부른다. 다시 말해서 A 브랜치에서 다른 B 브랜치를 Merge할 때 B가 A 이후의 커밋을 가리키고 있으면 A가 그저 B의 커밋을 가리키게 할 뿐이다.
fast-forward merge
현 브랜치가 가리키는 커밋이 merge할 브랜치의 조상이 아닐 경우 'Fast-forward'로 merge하지 않는다. 이때는 각 브랜치가 가리키는 코밋 두 개와 공통 조상 하나를 사용하여 3 way merge를 한다.
CVS나 Subversion 같은 버전 관리 시스템들은 개발자가 직접 공통 조상을 찾아서 Merge해야 한다. Git은 다른 시스템보다 Merge가 대단히 쉽다. 3 way merge란?
3 way merge
가끔씩 3-way Merge가 실패할 때도 있다. Merge하는 두 브랜치에서 같은 파일의 한 부분을 동시에 수정하고 Merge하면 Git은 해당 부분을 Merge하지 못한다. 이 때는 git이 자동으로 merge된 커밋을 만들지 못한다. 변경 사항의 충돌은 개발자가 해결해야만 한다.
충돌을 어떻게 다루는지 확인해보자. 먼저 예제를 위해 about이라는 새로운 브랜치를 생성한다.
$ git checkout -b about master
Switched to a new branch 'about'
그 다음 about.html에 선호하는 프로그래밍 목록을 입력하자.
$ git add about.html
$ git commit -m "a list of my favorite programming languages"
이제 두 번째 브랜치로 about2를 생성하자. 아직 브랜치를 전환하지는 말자.
$ git branch about2 about
브랜치를 전환하기 전에 about.html 파일에 다른 언어를 추가하고 변경 사항을 커밋한다.
$ git commit -m "add javascript to list" -a
커밋하기 전에 두 번째 브랜치를 만들었기 때문에, about 브랜치에는 존재하지만 about2브랜치에는 존재하지 않는 변경 사항이 생겼다.
about2 브랜치로 전환하자. 편집기를 새로 고치면 마지막으로 입력했던 내용이 없다는 사실을 확인 할 수 있다.
$ git checkout about2
Switched to branch 'about2'
about.html 마지막에 다른 언어를 추가하고 커밋하자.
$ git commit -m "add c++ to list" -a
[about2 17d2f20] add c++ to list
 1 file changed, 2 insertions(+), 1 deletion(-)
이제 충돌이 발생했다. 물론 대개는 이후에 두 브랜치를 합치려고 할 때 git알려주기 전까지는 충돌이 발생했음을 알아차리지 못할 것이다.
about 브랜치로 전환하고 about2 브랜치를 합쳐보자.
$ git merge about2
Auto-merging about.html
CONFLICT (content): Merge conflict in about.html
Automatic merge failed; fix conflicts and then commit the result.
CONFLICT 줄을 보면 about.html 파일에 충돌이 있음을 알려 준다. 편집기로 충돌 내용을 확인해 보자.
java
<<<<<<< HEAD
javascript
=======
c++
>>>>>>> about2
합칠 내용이 간단하다면 직접 수정한다. 변경 사항을 지정하고, 일반적인 경우와 마찬가지로 변경 사항을 스테이징 후 커밋한다.
복잡한 내용을 합칠 때는 merging tool이 유용하다. git mergetool을 실행하면 합치기 도구를 찾으려고 한다. git mergietool은 구성에 있는 merge.tool 값을 통해 합치기 도구를 찾는다.
적합한 도구가 설치된게 없다면 eclipse egit의 내장된 merge tool을 사용하자.
실행하는 방법은 파일 선택후 마우스 우측 버튼 > Team > Merge Tool 을 선택한다.
충돌을 성공적으로 해결했다면 커밋하자. -m 옵션을 생략하면, 방금 일어난 사항을 설명하는 메시지가 채워진 편집기가 실행된다.
$ git add about.html
$ git commit
[about a1b3b8a] Merge branch 'about2' into about

브랜치 삭제하기

브랜치는 쓰임새가 다한 이후에는 저장소의 브랜치 개수가 늘지 않도록 삭제해야 한다.
$ git branch -d about2
Deleted branch about2 (was 17d2f20).
브랜치 삭제 명령은 삭제하려는 브랜치가 성공적으로 현재 브랜치에 합쳐졌을 때만 동작한다. 시험해 보자. 먼저 마스터 브랜치로 전환한다. about 브랜치는 어떠한 변경 사항도 아직 합치지 않았기 때문에 삭제에 실패한다.
$ git checkout master
Switched to branch 'master'
$ git branch -d about
error: The branch 'about' is not fully merged.
If you are sure you want to delete it, run 'git branch -D about'.
about 브랜치를 master에 합치하고 지워 보자.
$ git merge about
Updating 8f7742a..a1b3b8a
Fast-forward
 about.html | 3 +++
 1 file changed, 3 insertions(+)
$ git branch -d about
Deleted branch about (was a1b3b8a).

브랜치명 변경하기

$ git branch -m contact contacts

원격 저장소를 이용하여 작업하기

네트워크 프로토콜

git은 원격 저장소와 통신하는 데 다음 세 종류의 프로토콜을 사용한다.
  • SSH
    • 보안
  • git
    • 속도가 빠르다
    • 9418 포트를 사용. 방화벽 이슈.
    • 익명 접근을 사용하므로 대부분 읽기 전용으로만 사용
  • HTTP/HTTPS
    • 방화벽 이슈에서 해방

원격 저장소 복제하기

원격 저장소를 사용하는 가장 쉬운 방법은 존재하는 저장소를 복제하는 것이다. 원격 저장소를 복제하면 저장소의 지역 복사본이 생성된다. 혼자 프로젝트를 시작했고, 그 다음 이를 공유한다면 원격 저장소는 나중에 구성될 수 있다.
작업하려는 저장소를 복제하려면 git clone 명령어를 사용한다.
$ git clone http://xxx.xxx.xxx/git/test/mysite-remote.git
Cloning into 'mysite-remote'...
remote: Counting objects: 12, done
remote: Finding sources: 100% (12/12)
remote: Getting sizes: 100% (6/6)
remote: Total 12 (delta 2), reused 12 (delta 2)
Unpacking objects: 100% (12/12), done.
git clone은 서버에 저장된 저장소를 다운로드하고 mysite-remote 디렉토리에 지역 복사본을 설정한다.
$ cd mysite-remote
$ ls
index.html

최신 상태 유지하기

원격 브랜치 확인하기
$ git branch -r
  origin/HEAD -> origin/master
  origin/master
원격 브랜치도 체크아웃할 수 있지만 변경은 안된다. 원격 브랜치를 변경하려면 먼저 원격 브랜치로부터 지역 브랜치를 생성한 다음 변경할 수 있다.
git fetch를 실행하면 지역 저장소의 원격 브랜치가 갱신된다. 이 때 지경 브랜치에 가져온 변경사항을 합치지는 않는다. 원격 서버에서 변경 사항을 가져와서 동시에 지역 브랜치에 합치려면 git pull을 사용한다.

변경 사항 푸싱하기

원격 저장소에 변경 내용을 공유 하기 위해서는 git push를 사용한다. git push에 매게 변수 없이 실행할 경우 우선 origin 저장소에 푸싱한다고 생각하며, 또한 지역 저장소의 현재 브랜치를 원격의 같은 이름의 브랜치에 푸싱한다고 여긴다. 이 때 원격 저장소에 같은 이름의 브랜치가 존재해야 한다.

새로운 원격 저장소 추가하기

nkia 저장소에 새로운 저장소를 추가해보자. 테스트 하기 위한 저장소이며 다른 저장소와 구별될 수 있도록 저장소 이름에 본인의 이름을 넣어 보자.
$ git remote add origin http://xxx.xxxx.xxx/git/test/mysite-자신이름입력.git
$ git push origin master
nkia 저장소는 익명 쓰기를 허용하지 않기 때문에 계정과 패스워드를 입력해야 한다.

git command set diagram


이미지 출처 : http://robotics.usc.edu/~ampereir/wordpress/?p=487

Hibernate에서 Tibero DB 사용하기

Hibernate에서 Tibero DB 사용하기

Hibernate에서 Tibero DB 사용하기

Tibero는 별도의 hibernate dialect을 지원하지 않는다. 대신 Tibero의 메타 데이터와 SQL 문법이 Oracle과의 호완성을 유지하기 때문에 Oracle diaclect을 사용할 수 있다. 그러나 몇가지 부분에서 Oracle 호완성이 유지 되지 않는 문제가 있다.

본 문서에서는 Hibernate에서 Tibero DB를 사용하기 위한 방안을 제시한다.

TiberoDialect 작성

DB 스키마를 자동으로 생성/업데이트를 할 때 Spring의 org.springframework.orm.hibernate3.LocalSessionFactoryBean 클래스에서는 createDatabaseSchema()updateDatabaseSchema() 메소드들을 사용한다. 이 메소드를 실행할 경우 Oracle dialect이 Tibero와 호완성이 맞지 않아 에러가 발생하게 된다.

다음과 같이 TiberoDialect을 작성하고 이를 사용한다.

import org.hibernate.dialect.Oracle9iDialect;

public class TiberoDialect extends Oracle9iDialect {
    @Override
    public String getQuerySequencesString() {
        return " select sequence_name from all_sequences";
    }
}

View metadata 요청 에러 workaround

class의 hibernate mapping을 table이 아닌 view로 할 경우 updateDatabaseSchema() 호출시 다음과 같은 에러가 발생하게 된다.

org.springframework.jdbc.UncategorizedSQLException: Hibernate operation: could not get table metadata: V_CLUSTER_PERFORMANCE; uncategorized SQLException for SQL [???]; SQL state [ERRPS]; error code [-20003];  'DCA'.'V_CLUSTER_PERFORMANCE' table does not exist..
TBR-15163: Unhandled exception at SYS.DBMS_STATS,  line 1755.   ; nested exception is com.tmax.tibero.jdbc.TbSQLException:  'DCA'.'V_CLUSTER_PERFORMANCE' table does not exist..

위 에러는 V_CLUSTER_PERFORMANCE라는 view의 table 메타 정보를 요청하면서 Tiber JDBC Driver에서 에러를 발생시켰다.

이 에러를 근본적으로 해결 하기 위해서는 Tibero JDBC를 수정하거나 org.hibernate.cfg.Configuration.generateSchemaUpdateScript() 메소드에서 TiberoDialect에 대한 예외 처리 코드를 추가해야 한다.

좀더 간단한 방법으로 updateDatabaseSchema()를 호출하기 전에 hibernate mapping 된 view를 drop한다. updateDatabaseSchema() 호출이 완료된 후 생성된 table을 drop하고 view를 생성 한다.