Spring Security Tutorial : http://static.springsource.org/spring-security/site/tutorial.html

 

Spring Security를 이용한 인증 처리 : http://preludeb.egloos.com/4738521

 

1장 스프링 시큐리티란? : http://springmvc.egloos.com/504862

2장 Intercept와 Granted Authority : http://springmvc.egloos.com/506465

3장 데이터베이스로 이동하는 Authentication 정보 : http://springmvc.egloos.com/516241

4장 JdbcDaoImpl의 커스터마이징. : http://springmvc.egloos.com/518902

5장 스프링 시큐리티에서의 비밀번호 암호화 : http://springmvc.egloos.com/520257

 

 

 

 

 

posted by 뚱2

링크 : http://atconsole.com/2013/06/05/mvc-mvp-mvvm-%EC%9D%98-%EC%9D%B4%ED%95%B4/


'일반' 카테고리의 다른 글

프로젝트 오일러 문제  (0) 2013.10.28
[WBS] WBS (Work Breakdown Structure)  (0) 2013.07.16
의사코드(슈도코드, pseudocode)  (0) 2013.04.24
[PhotoShop] 이미지 흑백 전환  (0) 2013.02.22
[Icon] 무료 아이콘  (0) 2013.01.21
posted by 뚱2

[.Net] Windows 서비스 만들기

.Net/.Net 2013. 4. 17. 14:07

* 연습 : 구성 요소 디자이너에서 Windows 서비스 응용 프로그램 만들기

링크 : http://msdn.microsoft.com/ko-kr/library/zt39148a(VS.80).aspx


* 방법 : Windows 서비스 응용 프로그램 디버깅

링크 : http://msdn.microsoft.com/ko-kr/library/7a50syb3(VS.80).aspx


'.Net > .Net' 카테고리의 다른 글

[.Net] Mutex 클래스  (0) 2013.04.19
[.Net] ServiceController  (0) 2013.04.18
[.Net] HTTP POST/WebClient (C#) and CSV formated string  (0) 2013.04.12
[.Net] RSA 암호화  (0) 2013.03.13
[.Net] EXE를 포함한 외부 DLL을 같이 배포하기  (0) 2013.02.19
posted by 뚱2

[Git] Git Tutorial

VCS/Git 2013. 4. 1. 16:50

( 출처: http://sapeyes.blog.me/70118257910 )

번역 해주셔서 정말 감사합니다.

Lars Vogel이 2009/09/13~2011/08/24 기간 동안에 작성하고 계속 수정해온 튜토리얼이다. 

http://www.vogella.de/articles/Git/article.html 에 원본이 있다.

단순히 번역만 하도록 한다. 



1. Git

  1.1 Git이란 무엇인가?


Git은 분산형 버전 관리 시스템 (DVCS, Distributed Version Control System)이며 C언어로 구현되었다. 버전 관리시스템은 당신이 어떤 파일 집합에 대한 히스토리를 생성하고 관리할 수 있도록 도우며 특정 다른 상태(어느 시점)으로 복귀(Revert)할 수 있는 기능을 가지고 있다. 파일 집합은 주로 소스코드들이다. 분산 버전 관리 시스템에서 모든 사용자는 완벽한 복사본을 가지고 있으며 (소스코드에 대한 히스토리를 포함) 버전 관리 명령어들을 각 사용자의 로컬에서 실행할 수 있다. DVCS는 중앙 저장소 사용을 항상 요구하지 않는 장점을 갖는다. 


만약 당신이 소스코드에 수정을 가한다면 그것에 대해 버전 관리 시스템에 마크(mark)하고 (즉 index/staging으로 add) 그러고 난 뒤 저장소로 추가(commit)한다. Git은 당신이 복귀할 수 있는 모든 버전들을 관리하고 있다. Git 은 커밋을 당신의 지역 저장소로 하도록 하며 당신의 Remote 저장소로 동기화 하도록 돕는다. Git은 저장소들을 복사 (clone) (소스코드의 완벽한 히스토리를 포함)하는 기능도 있다. 저장소 실제 주인은 push (remote 저장소로 변경사항 전송) 과 pull (remote 저장소로부터 변경사항 받기) 의 두 명령을 통해 변경사항들을 동기화 한다.


Git은 분기 (Branching)을 지원한다. 즉 당신의 소스코드에 대한 다른 버전들을 당신이 마음대로 생성하여 가질 수 있도록 하는 것이다. 만일 당신이 새로운 특정 부분에 대해 개발을 원한다면 먼저 소스코드에 대한 분기(branch)를 열고 변경사항들을 마크 (즉 소스코드를 개발 혹은 수정하여 staging index 에 기록) 할 수 있다. Git은 모든 버전들을 추적한다.


Git은 명령어 콘솔로도 사용될 수 있다. 본 튜토리얼에서는 콘솔 명령어 위주로 설명한다. GUI기반 툴이 필요하다면 EGit (http://www.vogella.de/articles/EGit/article.html) 을 사용해 보길 바란다. 


  1.2 중요 용어 정리


Repository - 저장소

저장소는 히스토리, 시간/태그(Tag)/분기(Branch)에 따른 다른 버전들을 가지고 있다. Git에서 저장소를 다른곳으로 복사하더라도 다시 완벽한 저장소가 된다. 저장소는 작업하고 있는 복사본으로 수정본들을 얼마든지 검색할 수 있도록 한다.


Branches - 분기 와 Tags - 태그

Git 저장서는 모든 분기들과 태그(tags)들을 가지고 있다. 분기들중 하나는 master라고 불리는 기본 분기이다. 사용자는 작업에 필요한 어떤 한 버전의 분기를 이 기본분기로 체크아웃(Checkout)한다.  이것을 작업 카피 (Working Copy)라고 한다.


Commit - 커밋

소스 수정사항들은 저장소로 커밋할 수 있다. 이것은 지난 시간까지 추적된 것에 대한 새로운 리비전(Revision)을 만드는 것이다. 각 커밋은 저자와 커밋한 내용(어떻게 수정을 했는지, 누가 커밋 했는지)을 저장한다.


URL

Git에서 URL은 저장소의 위치이다.


Revision - 리비전

소스코드의 버전을 가리킨다. Git은 SHA1 ids으로 리비전을 구분한다. SHA1 ids는 160비트 으로 긴 편이고 16진수로 표현된다. 가장 최신버전은 HEAD로 불리는 주소로 표현되며 이전 버전은 HEAD~1으로 계속 그런 방식으로 버전이름을 가리킬 수 있다.


  1.3 Staging Index


(저자 왈 : Staging은 임시적인 공간, 혹은 단계를 가리킴)

Git 은 당신이 변경사항들을 명확하게 표기하길 요구하고 저장에 적절하게 수정사항들이 표기되길 원한다. 예를들어 당신이 새로운 파일을 다음 변경사항에 적용하고 싶으면 소위 'staging index'에 그 파일들을 'add file' 명령을 이용해 넣으면 된다. Staging index는 변경사항들에 대한 완벽한 스냅샷이다.


2. 설치


우분투에서는 "sudo apt-get install git-core"

윈도우에서는 http://code.google.com/p/msysgit/ 에서 참고


3. 셋업 (Setup)


Git은 ".gitconfig" 파일에 전역 환경설정내용을 저장하고 있다. 이 파일은 사용자의 홈 디렉토리에 있으며 사용자와 비밀번호 혹은 소스코드 글자색상등을 수정할 수 있다.


  3.1 사용자 설정 (User Configuration)


사용자와 사용자 이메일을 Git을 위해 설정하는 것은 다음 명령어를 통해 진행될 수 있다.


# Git에서 사용될 사용자 설정하기
# 당신의 이름으로 설정하면 된다.
git config --global user.name "Lars Vogel"
 
# 이메일 주소도 당신의 것으로 설정하면 된다.
git config --global user.email "Lars.Vogel@gmail.com"
 
# Set default so that always all changes are pushed to the repository (이건 무슨말인지 잘 모르겠음)
git config --global push.default "matching"
 


그리고 Git 설정사항을 확인하기 위해서는 


git config --list
 


  3.2 컬러 하이라이트


콘솔모드에서 글자 하이라이트 설정하는 명령어


git config --global color.status auto
git config --global color.branch auto
 

  3.3 특정 파일 (커밋) 무시하기


Git에게 ".gitignore"파일을 통해 무시하고 싶은 디렉토리를  알려줄 수 있다. 혹은 파일의 패턴을 알려줄 수 있다. 에를들어 git에게 "bin" 폴더를 무시하고 싶다고 알려주고 싶다면 ".gitignore"파일에 다음과 같이 쓰면 된다.

    
bin
 

4. Git 시작하기


다음 내용들은 Git 을 가지고 일을 하는 방법에 대한 가이드이다. 몇개의 파일들을 생성하게 될 것이고 지역 Git 저장소를 생성한 후 당신의 파일을 커밋하게 될 것이다. 이후에는 저장소를 클론한 뒤 push, pull 하여 저장소간 변경사항들을 동기화 하는 방법을 알아보게 될 것이다. 명령어 창을 열고 다음 명령들을 입력해보길 바란다. 명령어 윗줄에 적은 코멘트들은 명령어를 기입하는 이유로 적힌 내용들이다.


  4.1 내용 생성하기 (Create Content)


버전 관리를 받고 싶은 컨텐츠를 생성한다.

    
# 홈 디렉토리로 이동하기
cd ~/
 
# 저장소 폴더 생성하기
mkdir ~/repo01.git
 
# 저장소 폴더로 이동하기
cd repo01.git
 
# 폴더 생성하기
mkdir datafiles
 
# 파일 생성하기
touch test01
touch test02
touch test03
touch datafiles/data.txt
 
# 첫번째 파일에 몇가지 텍스트 기입하기
ls >test01
 


  4.2 저장소 생성하고 커밋하기


모든 Git 저장소는 .git 폴더에 저장되어 있으며 .git 폴더는 당신이 생성한 git 저장소 폴더안에 있다. .git 폴더는 저장소의 환결설정 정보와 저장소의 완벽한 히스토리 정보를 담고 있다. 다음은 Git 저장소를 생성하는 명령어와 파일들을 저장소의 인덱스어 추가하고 변경사항을 커밋하는 과정을 나타낸다.

    
# 지역 Git 저장소 초기화 하기 (즉 저장소 만들기)
git init
 
# 모든 파일을 저장소로 추가하기
git add .
 
# 지역 저장소로 커밋하기 (첫번째 리비전 만들기)
git commit -m "Initial commit"
 
# 로그 파일 보기
git log
 


  4.3 diff 명령으로 차이점 확인 뒤, 차이점 커밋하기


먼저 파일에 변경 가한 뒤, 차이가 생긴 부분들을 한눈에 보고, 이를 저장소로 커밋하기

    
# 파일 변경하기
echo "This is a change" > test01
echo "and this is another change" > test02
 
# 변경사항들을 diff명령으로 확인하기 
git diff
 
# 변경사항 커밋하기, -a는 수정된 파일들에 대해서만 커밋함
# 하지만 새로운 파일은 자동으로 추가하지 않음
git commit -a -m "These are new changes"
 


  4.4 Status, Diff 와 커밋 Log


다음 명령들은 현재 상태(status)와 커밋 리스트를 보기 위한 것이다.

     
# 파일에 변경 가하기
echo "This is a new change" > test01
echo "and this is another new change" > test02
 
 
// 현재 저장소 상태 확인하기 (파일의 변경/생성/삭제을 나타냄)
git status
 
// 마지막에 커밋한 내용과의 차이점 확인하기
git diff
 
// 커밋하기 (-a 명령은 수정된 파일이 커밋되도록 하는 것)
// -a 명령 없이 커밋하려면 사전에 git add test01, git add test02 해야함
git commit -a -m "More changes - typo in the commit message"
 
// 커밋 히스토리 확인하기
git log
 
// 변경사항 GUI로 확인하기
gitk --all
 


  4.5 커밋 메세지 수정하기 - git amend


위 예제에서 커밋 메세지가 틀렸었다. --amend 파라미터를 이용해 마지막 커밋 메세지를 바꿀 수 있다.

    
git commit --amend -m "More changes - now correct"
 

  4.6 파일 삭제


만일 버전관리를 받던 파일을 삭제했을 경우 "git add ."명령은 staging index에서 파일 제거를 할 수 없다. -A 옵션을 사용하여 "git add -A ."을 할경우 파일 제거가 적용된다. 혹은 커밋 명령어에서 -a옵션을 주면 된다. "git commit -a -m ..." (-a옵션 권장)


    
# 파일을 생성하고 버전관리를 받도록 한다.
touch nonsense.txt
git add . && git commit -m "a new file has been created"
 
# 파일을 제거한다.
rm nonsense.txt
 
# 일반적인 커밋을 시도해본다 -> 실패한다.
git add . && git commit -m "a new file has been created"
 
# -a 옵션을 사용하여 커밋을 해본다.
git commit -a -m"File nosense.txt is now removed"
 
# 또는 대신 staging index에서 제거된 파일을 적용하려면 git add -A . 을 이용하여도 된다.
git add -A . 
git commit -m "File nosense.txt is now removed"
 


  4.7 Remote (Bare) Git 저장소 설정하기


이제 Remote Git 저장소를 생성한다. Git 은 원격 저장소를 네트워크나 로컬이나 상관없이 저장하는 것을 가능하게 한다. 단순하게 설명하기 위해서 로컬 원격 git 저장소를 시도해본다. 일반적인 git 저장소는 원격 git 저장소와 다르다. 일반적인 git 저장소는 소스코드와 git 저장소를 가지고 있다. 이 폴더에서 바로 당신은 아무 작업이나 할 수 있으며, 저장소는 소스코드의 Working Copy를 가지고 있기 때문이다.  원격 저장소는 작업 복사본(Working copy)을 가지고 있지 않다. 저장소 파일만 가지고 있다. 이러한 저장소를 생성하기 위해선 "--bare" 플래그를 사용한다.

    
# 저장소로 이동
cd ~/repo01.git
# 
git clone --bare . ../remote-repository.git
 
# 복사된 파일들이 같은지 확인 (.git 폴더에 있는 파일)
ls ~//remote-repository.git
  


  4.8 다른 저장소로 변경내용 Push 하기


먼저 첫번째 저장소에서 파일에 변경을 가한 뒤에,  원격 저장소로 변경내용 Push 하기


    
# 첫번째 저장소로 이동해서 변경을 가해보자
cd ~/repo01
 
# 다음과 같이 두 파일의 내용을 변경한다.
echo "Hello, hello. Turn your radio on" > test01
echo "Bye, bye. Turn your radio off" > test02
 
# 수정된 파일에 대해 커밋을 하려면 -a 옵션을 이용해 commit 을 실행한다.
# 단, 새로 추가된 파일에 대해서는 자동으로 커밋해주진 않는다.
git commit -a -m "Some changes"
 
# 자, 원격 저장소로 푸쉬해보자.
git push ../remote-repository.git


  4.9 Add Remote


원격 저장소로 Push 하는 경우 URL을 전부 써야하는 불편이 있다. 이 주소를 줄여서 사용할 방법이 있으며 "git remote add 별명 url" 형식으로 줄인다. 별명 중에서 "origin"은 특별한 이름으로, 만일 저장소를 clone하여 사용할 경우 자동으로 해당 저장소를 origin으로 별명을 지정하여 사용되는 키워드이다. origin은 원번 저장소를 가리키는 말이고 작업을 최초로 시작하게 된 곳을 가리키게 된다. 다음과 같이 저장소를 최초로 생성해 사용하는 경우에는 origin이 없으며  한번 등록하게 되면 계속 사용 가능하다.


    
# ../remote-repository.git 저장소를 origin으로 추가한다.
git remote add origin ../remote-repository.git 
 
# 자 현 저장소(working copy)에 수정을 가한다.
echo "I added a remote repo" > test02
 
# Staging index 로 commit 한다.
git commit -a -m "This is a test for the new remote origin"
 
# origin으로 push 한다. 만일 git push 만 입력할 경우 자동으로 origin으로 보내게 된다.
git push origin
 


  4.10 저장소 clone하기


당신의 저장소를 새로운 폴더로 checkout 하는 방법.

(Checkout a new version of your repository into a new directory)


    
# 홈 폴더로 이동한 뒤에
cd ~
 
# 새로운 저장소 폴더를 만들자.
mkdir repo02.git 
 
# 새로운 저장소 폴더로 이동한 뒤에
cd ~/repo02.git
 
# 원격(origin) 저장소로 부터 체크아웃 받자.
git clone ../remote-repository.git .
 


  4.11 변경내용 Push 및 Pull 하기


Pull 은 최신 변경 내용을 다른 저장소로 보내는 작업이다. 새로운 저장소에서 변경된 파일들이 있을경우 push 명령을 통해 변경내용을 원격 저장소로 보낼수 있으며 pull 명령을 통해 이러한 변경사항들을 첫번째 저장소로 끌어올 수 있다.  


  두번째 저장소 (내용 변경됨, 최신버전) -> Push  -> 원격 저장소 (최신버전)
  첫번째 저장소 (구버전->최신버전) <- Pull <- 원격저장소 (최신버전)


    
# 홈 폴더로 이동
cd ~
 
# 두번째 저장소로 이동한다
cd ~/repo02.git
# 변경을 가한다.
echo "A change" > test01
# 커밋
git commit -a -m "A change"
# 원격 저장소로 커밋한다.
# origin은 clone 명령어를 사용했기 때문에 이미 등록되어 있다.
git push origin
# 첫번째 저장소로 이동한다. 그리고 변경내용을 pull 한다.
cd ~/repo01.git
git pull ../remote-repository.git/
# 최신 내용이 적용되었는지 파일 내용 확인
less test01
 


5. Revert Changes (변경사항 Revert-되돌리기)


만약  working copy에서 파일들을 새로 생성했는데 이 파일들을 커밋하고 싶지 않다면 다음과 같이 하면 된다. (아직 변경 내용을 staging 영역으로 올리지 않았을 경우입니다. - git clean )


   
# 파일 생성하기
touch test04
echo "this is trash" > test04
 
# dry-run 해보기 (즉 변경사항 취소하면 무슨 파일에 영향이 오는지 보기)
# -n 옵션이 dry-run 입니다.
git clean -n
 
# 자 이제 지웁시다.
git clean -f
 


예전에 커밋된 버전들중에서 구버전으로 체크아웃 할 수 있습니다. 

git log 명령을 치면 commit 이름이 암호문처럼 길게 나온게 있는데 그 커밋 이름을 쓰면 됩니다.
(되돌아 갈때 Conflict 가 발생할 수도 있는데, 이런경우 파일에 /HEAD 부분(최신버전)과 구버전을 구분하여 파일을 남겨둔다. - 변역자 경험임, 경험이 부족해서인지 이부분 난해하게 느껴집니다.)
(참! 특정 버전으로 checkout 하게 되면 원래의 working copy는 HEAD 버전으로 그대로 남아있구요, 이름이 없는 Branch로 들어가서 구버전을 테스트할 수 있는 상태로 됩니다. git branch 해보면 되요. 여기서 수정,커밋도 됩니다. 본래로 돌아가려면 git checkout master라고 해도 되네요.)

  
# 첫번째 저장소로 가본다.
cd ~/repo01.git 
# 커밋 로그를 확인하면, commit 다음에 영문숫자 암호코드가 있는데 이것이 커밋 이름입니다. 다른 이름도 있는데요, 최신버전은 HEAD, 그 바로 아래 버전은 HEAD~1 입니다.
git log
 
# 자 구버전 중에서 하나를 골라 체크아웃 하면, 구버전으로 돌아갑니다. 
git checkout commit_name
 


만약 Staging index로 변경내용을 적용하지 (add 하지) 않았다면 바로 변경내용을 버릴 수 있다. 

   
# 몇가지 멍청한 실수를 저질렀다고 치자.
echo "stupid change" > test01
 
# Staging Index으로 커밋하지 않았을 경우에는 checkout 받으면 이전 버전으로 돌아갈 수 있다. 
git checkout test01
 
# 잘 돌아갔는지 내용을 확인해 보자.
cat test01
 
# 또 실수를 저질렀다고 치자.
echo "another stupid change" > test01
 
# 이번엔 Staging Index로 변경내용을 적용했다. (add, commit 명령어는 staging 영역을 건드림)
git add test01
 
# Staging Index의 test01을 원래대로 복원한다.
git reset HEAD test01
 
# Staging Index로 부터 본래 파일을 Working Copy로 checkout함으로써 실수한 내용을 원래의 내용으로 최종 복원한다. (크아아악 복잡해)
git checkout test01
  


Revert 명령으로 커밋을 되돌릴 수(Revert) 있다.

   
#Revert a commit
git revert commit_name


 (ex) git revert HEAD     // 또 실행할 경우 바로 이전 commit과 최신 커밋을 계속 반복하며 복원함

  - git reset --hard HEAD // 무조건 HEAD로 복원 (working copy, staging index 모두)


만약 파일을 Index에 추가하였는데 커밋을 하고 싶지 않다면 index에서 없앨 수 있다.

   
// 파일을 생성
touch incorrect.txt
// 실수로 파일을 첨부함
git add .
// 이 파일만 commit에서 제외하고 싶을 때
git reset incorrect.txt
// 자 이제 편히 지우세요.
rm incorrect.txt
 


6. Tagging in Git (태그 사용하기)


Git은 히스토리에 존재하는 특정 버전에 대해 태그를 사용할 수 있는 옵션이 있다. 따라서 좀더 편하게 원하는 예전 소스들을 참고할 수 있게된다. 대부분 일반적으로는 공개적으로 릴리스된 버전들에 대해 태그를 주로 달아 쓴다.


다음 명령을 통해 현재 사용중인 태그를 확인할 수 있다.

  
git tag
 


새로운 태그는 다음과 같이 생성한다.

  
git tag -a version1.6 -m 'version 1.6'
 


만약 태그와 관련된 소스를 사용하고 싶을 경우 다음과 같이 체크아웃 한다.

 
git checkout <tag_name>
  


7. 분기 및 합치기 (Branches and Merging)

  7.1 분기 (Branches)


Git은 분기를 생성할 수 있다. 예를들면 소스코드의 독립적인 카피를 만드는 것이다. 각 분기 독립적으로 소스를 수정할 수 있다. 기본 분기는 master이다. git은 분기를 거의 시간을 들이지 않고 아주 빠르게 분기를 생성할 수 있다. 따라서 개발자들은 별 부담 느끼지 않고 마음대로 분기를 만들어 개발할 수 있게 된다.


다음 명령어는 현재 로컬 저장소의 분기 목록을 보여준다. 활성화된 분기는 * 마크가 붙어있다.

    
git branch 
 


만약 모든 분기를 보고 싶다면 (원격 분기 포함) 다음 명령어를 사용한다.

   
git branch -a
 


새로운 분기는 다음과 같이 생성한다.

    
# Syntax: git branch <name> <hash>
# hash 코드는 커밋 이름이다. 만일 과거 커밋중에서 테스트해보고 싶은 자료가 있다면 분기로 만들 수 있는데, 옵션이므로 꼭 사용할 필요는 없다.
# Switch to your new branch
git branch testing
git checkout testing
 
# 분기 testing에서 파일에 수정을 가해본 후 커밋을 한다.
echo "Cool new feature in this branch" > test01
git commit -a -m "new feature"
 
# 마스터 분기로 이동한다.
git checkout master
 
# 마스터 분기에서 수정사항이 적용되었는지 확인해본다. (안됨)
cat test01
 


  7.2 합치기 (Merging)


Merge는 두 분기의 차이를 결합하는 명령어이다. Merge는 3가지 방법으로 두 분기의 최신 커밋 HEAD를 결합한다. 결과적으로 새로운 HEAD를 갖게 된다. 특정 분기로부터 현재 활성화된 분기로 변경사항을 다음 명령을 통해 결합할 수 있다.

  
# Syntax: git merge <branch-name.
git merge testing
  


만약 merge conflict 가 발생할 경우, git은 conflict 가 발생한 파일의 위치에 직접 표시를 해두어 프로그래머가 수동적으로 충돌난 소스를 수정할 수 있도록 돕는다. 수정이 끝난 후 프로그래머는 staging index로 파일을 추가하거나 commit할 수 있게 된다.


  7.3 분기 삭제하기 


더 이상 필요하지 않은 분기를 삭제하려면 다음 명령을 사용한다.

    
#Delete branch testing
git branch -d testing
# Check if branch has been deleted
git branch
 


8. Merge Conflict 해결하기


Git은 merge conflicts 를 해결하는 방법을 제공한다. 다음 명령어들을 통해 일부러 conflict를 발생시켜보자.

   
# 첫번째 저장소로 이동
cd ~/repo01.git
 
# 파일을 만들고 내용을 수정한다.
touch mergeconflict.txt
echo "Change in the first repo" > mergeconflict.txt
 
# Stage로 추가한 뒤 commit한다.
git add . && git commit -a -m "Will create merge conflict repo1"
 
# 두번째 저장소로 이동한다.
cd ~/repo02.git
 
# 같은 파일을 만들고 내용을 수정한다.
touch mergeconflict.txt
echo "Change in the second repo" > mergeconflict.txt
 
# Stage로 추가한뒤 commit한다.
git add . && git commit -a -m "Will create merge conflict repo2"
 
# master 저장소로 push한다.
git push
 
# 첫번째 저장소로 이동한다.
cd ~/repo01.git
 
# Push를 시도해본다. -> 거절 에러가 발생한다.
git push
 
# 변경사항을 master로 받는다.
git pull origin master  
 


위 마지막 명령어를 통해 최신 소스를 가져오면서 Git은 conflict가 발생한 파일의 소스 위치를 표시(mark)해 놓았다. 다음과 같다.

  
<<<<<<< HEAD
Change in the first repo
=======
Change in the second repo
>>>>>>> b29196692f5ebfd10d8a9ca1911c8b08127c85f8


윗 부분은 현재 저장소에 있던 본래 소스이고, 아랫부분은 원격 저장소에 있던 자료이다. 자 이제부터 수동적으로 수정할 수 있고, 수정후에는 변경내용을 새롭게 커밋할 수 있게 된다. 또는 ' git mergetool '을 사용해도 된다. 이 툴은 두개의 vim 창으로 각 소스를 보여주어 좀 더 쉽게 충돌난 소스를 수정할 수 있도록 돕는다.

   
# 수동적으로 파일을 수정하거나 아니면 다음 결합툴을 사용할 수 있다.
git mergetool
# conflict 가 발생한 파일들을 순차적으로 보여주어, 새로운 파일에 어떤 내용을 넣을지 순차적으로 수정할 수 있게 한다.
 
# 모든 내용을 수동적으로 수정한 뒤, 새로운 내용을 다시 커밋한다.
git commit -m "merged changes"
 


9. Rebase 

  9.1 같은 분기에서 커밋들을 Rebase하기


Rebase는 다수의 커밋들을 하나의 커밋으로 만드는 명령어이다. 자, 필요없는 커밋들을 많이 해보자.

    
# 새로운 파일을 만든다.
touch rebase.txt
 
# Git에 추가한 뒤 커밋한다.
git add . && git commit -m "rebase.txt added to index"
 
# 별 필요없는 텍스트를 추가한 뒤 커밋하는 것을 반복한다.
echo "content" >> rebase.txt
git commit -am "added content"
echo " more content" >> rebase.txt
git commit -am "added more content"
echo " more content" >> rebase.txt
git commit -am "added more content"
echo " more content" >> rebase.txt
git commit -am "added more content"
echo " more content" >> rebase.txt
git commit -am "added more content"
echo " more content" >> rebase.txt
git commit -am "added more content"
 
# 커밋된 내용을 확인
git log


자 이제 rebase.txt에 대한 커밋들을 합쳐보자. 

   
git rebase -i HEAD~7


에디터는 커밋 메세지를 변경할 수 있게 한다. 

(번역자:혹시 숫자를 너무 크게 쓰면 다른 소스랑 겹쳐서 에러가나는 바람에 rebase가 안될 수도 있다. 이때는 git rebase -abort 를 해주자. commit한 수를 세어서 숫자를 입력하길 바란다. 아니면 log에서 맨처음은 1로 보고 차근차근 세길 바란다. rebase후에는 git log를 해도 커밋 메세지는 그대로 남아있다. 아무래도 히스토리 내에서 결합이 이루어지는 것 같다.)


  9.2 Rebase Branches


Git을 이용해 두개의 분기를 rebase할 수 있다. merge 명령이 두 분기를 합친것처럼 rebase는 한 분기의 변경사항을 이용하여 패치(patch)를 만들고 다른 분기에 이를 적용한다. 결과는 merge와 같지만 commit 히스토리가 좀더 깔끔하다. 즉 다른분기의 커밋 메세지가 master의 히스토리 최상단에 그대로 뜸으로써 연속성을 갖는다.

  
# 분기 생성 
git branch testing
# 새로운 분기로 이동
git checkout experiment
# 소스 변경
echo "This will be rebased to master" > test01
# 변경내용 커밋
git commit -a -m "New feature in branch"
# Master로 rebase하기
git rebase master
 
   


10. 패치 생성 및 적용하기


다음을 통해 분기를 생성한 뒤 수정된 내용의 패치를 만들고 master에 적용하는 법을 테스트 해보자.

    
# 새로운 분기 생성
git branch mybranch
 
# 이동
git checkout mybranch
 
# 변경
touch test05
# Change some content in an existing file
echo "New content for test01" >test01
 
# 커밋
git add .
git commit -a -m "First commit in the branch"
 
# 패치 생성하기 --> git format-patch master  (여러개가 생길 수 있다)
git format-patch origin/master
# 0001-First-commit-in-the-branch.patch 패치가 생성되었다.
 
# master 분기로 이동한다.
git checkout master
 
# 패치를 적용한다.
git apply 0001-First-commit-in-the-branch.patch
 
# 패치를 지운다.
rm 00*
 
# master 분기에서 이제 일반적인 commit이 가능하다.
git add .
git commit -a -m "Applied patch"
 
   


* 역자 : git add .은 모든 파일이 staging index에 포함되기 때문에 조심해서 쓰는게 좋다. (git add 파일명 을 쓰거나 아니면 필요없는 파일은 지우거나 다른 곳으로 옮긴다.)


11. 별명 지정하기 (Alias)


특정 명령어에 대한 별명을 사용할 수 있다. 예를들어 git add-commit 명령어를 git add .-A 와 git commit -m 명령어로 결합하여 정의할 수 있다. 정의 후에는 "git add-commit "message"" 로 사용하면 된다.


  
git config --global alias.add-commit '!git add . -A && git commit -m'


12. 파일 또는 폴더 추적 멈추기 (Untrack)


간혹 저장소에 포함하지 말아야할 파일이나 폴더가 생길때가 있다. 만약 .gitignore 파일에 제외 파일/폴더 이름들을 기입하면 git은 기입 시점부터 track을 멈춘다. 이건 파일을 지우지는 않는다. 따라서 최신버전은 그대로 유지된다. Untrack 하려면 다음 명령어를 사용한다.

   
# .metadata 폴더를 untrack 하려는 경우
git rm -r --cached .metadata
# test.txt 파일을 untrack 하려는 경우
git rm --cached test.txt


파일은 지워지지 않는다. 이전 커밋 히스토리 까지는 파일이 여전히 남아있다. 만일 히스토리상에서 사라지길 원한다면 "git filter-branch"를 살펴보길 바란다. 이 명령어는 커밋 히스토리를 수정하기 위해 사용되는 것이다.


13. 원격 저장소

  13.1 원격 저장소 클론하기 (Clone)

Git은 원격 명령을 실행할 수 있다. 전송 프로토콜 타입을 지정할 수도 있다. Native(기본 제공 프로토콜)은 git protocol이다.

git clone git://dev.eclipse.org/org.eclipse.jface/org.eclipse.jface.snippets.git
   


대신 HTTP 프로토콜로 같은 저장소를 클론할 수도 있다.

   
git clone http://dev.eclipse.org/git/org.eclipse.jface/org.eclipse.jface.snippets.git
 


  13.2 원격 저장소 추가하기

(이미 나온내용이지만 번역한다.) 원격 저장소를 커밋하면 기본 저장소는 자동으로 origin을 생성하여 push 명령을 통해 다시 수정내용을 적용할 수 있도록 해준다. 그리고 더 많은 원격 저장소를 "git remote add name 원격저장소주소"로 늘릴 수 있다. 예를들어 만약 위 git 프로토콜 주소로 클론을 했을 경우, 다음과 같이 http 주소를 추가할 수 있다.

 
// Add the http protocol 
git remote add githttp http://dev.eclipse.org/git/org.eclipse.jface/org.eclipse.jface.snippets.git


  13.3 원격 명령어 (http / proxy)


http 프로토콜을 사용해 git 저장소를 복제하는것이 가능하다. 만약 방화벽이 http를 제외한 다른것을 모두 막는 경우, http를 이용한 복제가 매우 유용해진다. 예를들어 다음 명령어를 통해 이클립스 프로젝트를 http와 proxy를 통해 복제할 수 있다. 

환경변수를 이용하는 방법

  
// Linux
export http_proxy=http://proxy:8080
// On Windows
// set http_proxy=http://proxy:8080 
git clone http://dev.eclipse.org/git/org.eclipse.jface/org.eclipse.jface.snippets.git
// push back to the origin using https
git push origin
   


git config를 이용하는 방법

   
// Set proxy for git globally
 git config --global http.proxy http://proxy:8080
// To check the proxy settings
git config --get http.proxy
// Just in case you need to you can also revoke the proxy settings
git config --global --unset http.proxy
 



14. 기타 유용한 명령어들


일상 작업에서 유용할만한 기타 명령어들이다.


git blame filename 

- 누가 생성하고 수정했는지 나타냄


git checkout -b mybranch master~1 

- 새로운 분기를 master와 똑같도록 생성하지만 마지막 커밋 바로 이전의 내용이다.


15. git 서버 설치하기


지금까지 설명한바에 의하면 서버는 굳이 필요 없다. 단순히 로컬 파일 시스템에서 사용하거나 공용 git privder (Github)를 사용하면 된다. 하지만 간혹 편리성을 위해 사설 서버가 필요할 수 있다. ubuntu에서 설치하는 방법을 설명한다. 매우 쉽다.


먼저 SSH가 설치되어 있는지 확실히 해둔다.

 
apt-get install ssh
  


Git을 설치한다. (설치 하지 않았을 경우)

    
sudo apt-get install git-core
 


Git 사용자로 로그인 한뒤 bare repository (원격 저장소 - working copy가 없음) 을 만든다.

   
# login to server
# to test use localhost
ssh git@IP_ADDRESS_OF_SERVER
 
# Create repository
mkdir example.git
cd example.git
git --bare init
 
  


이제부터 원격 저장소로 커밋할 수 있다.

 
mkdir gitexample
cd gitexample
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin git@IP_ADDRESS_OF_SERVER:example.git
git push origin master
  


16. GitHub


지금까지 해온 작업은 서버와 연관은 없었다. 서버를 사용하려면 프리 호스팅 서버를 이용할 수 있다. 

GitHub는 ssh key를 필요로 한다. ssh키를 생성하려면 우분투에서 키생성하는 방법을 검색해 보길 바란다. (http://help.github.com/linux-set-up-git/) 윈도우에서는 msysgit 을 사용하면 된다. (http://help.github.com/msysgit-key-setup/)


GitHub에서 계정을 생성하고 저장소를 만들기 바란다. 저장소 생성뒤 GitHub에서 프로젝트를 업로드 하기 위한 명령어들을 알려준다. 이 명령어를 따라서 프로젝트를 업로드하길 바란다.


17. Git을 위한 GUI Tool


Git에는 자체 GUI 툴이 있다. 히스토리를 보여주는 gitk 와 git 명령어들을 사용할 수 있는 git gui이다. 

윈도우에서는 TortoisGit(http://code.google.com/p/tortoisegit/) 이 있다. 이것은 TortoisSVN(http://tortoisesvn.tigris.org/ 과 비슷하다. 

이클립스용 툴도 있다. (http://www.vogella.de/articles/EGit/article.html)



투토리얼 저자를 후원하시려면 (http://book.git-scm.com/3_git_tag.htmlhttp://bit.ly/oiFUXT)



링크모음

Git homepage

Video with Linus Torwalds on Git

Progit book - Free Git book

Video casts about Git

http://code.google.com/p/msysgit/ Git on Windows

http://github.com/guides/git-cheat-sheet Git Cheat Sheets

http://github.com/blog/626-announcing-svn-support SVN Support for GitHub

Git in 5 Minutes by Scott Paul Robertson

Git - SVN Crash Course

http://www.ibm.com/developerworks/opensource/library/l-git-subversion-1/index.html 



- Translated by Chim (sapeyes) -


혹시 이해가 안되는 부분이 있을 경우 http://book.git-scm.com/index.html 사이트에서 

관련 내용을 참고해보시길 바랍니다.

'VCS > Git' 카테고리의 다른 글

[Git] Advanced Git  (0) 2013.11.27
[Git] Git은 어떻게 동작하는가?  (0) 2013.11.26
[Git] Tortoisegit  (0) 2013.04.15
[Git] SourceTree (windows)  (0) 2013.03.30
[Git] A successful git branching model  (1) 2012.11.14
posted by 뚱2

[C++] C++11

C/C++/VC++ / MFC 2013. 1. 29. 09:22

링크 : http://ko.wikipedia.org/wiki/C++11 

posted by 뚱2
posted by 뚱2

* Productivity Power Tools

다운로드 : http://visualstudiogallery.msdn.microsoft.com/d0d33361-18e2-46c0-8ff2-4adea1e34fef 

참고 : http://blog.naver.com/empty_wagon?Redirect=Log&logNo=20123797318 

 

* anksvn

다운로드 : http://visualstudiogallery.msdn.microsoft.com/E721D830-7664-4E02-8D03-933C3F1477F2 

홈페이지: http://ankhsvn.open.collab.net/ 

참고 : http://minjang.egloos.com/2827484

posted by 뚱2

링크 : http://blog.daum.net/onjsystems/274


posted by 뚱2

링크 : http://dalbong2.net/entry/SpringNET-%EA%B0%9C%EB%B0%9C-%EA%B0%80%EC%9D%B4%EB%93%9C 


문서 작성해 주신분께 감사드립니다.


'.Net > Spring.Net' 카테고리의 다른 글

[Spring.Net] Spring.NET_guide_ensoa_v.0.2.pdf  (0) 2012.03.16
posted by 뚱2

Scheduling 서비스

개요

Scheduling 서비스는 어플리케이션 서버 내에서 주기적으로 발생하거나 반복적으로 발생하는 작업을 지원하는 기능으로서 유닉스의 크론(Cron) 명령어와 유사한 기능을 제공한다.
실행환경 Scheduling 서비스는 오픈소스 소프트웨어로 Quartz 스케쥴러를 사용한다. 본 장에서는 Quartz 스케쥴러의 기본 개념을 살펴본 후, IoC 서비스를 제공하는 Spring과 Quartz 스케쥴러를 통합하여 사용하는 방법을 살펴본다.

설명

Quartz 스케쥴러

Quartz 스케쥴러 실행과 관계된 주요 요소는 Scheduler, Job, JobDetail, Trigger 가 있다.

  • Scheduler 는 Quartz 실행 환경을 관리하는 핵심 개체이다.
  • Job 은 사용자가 수행할 작업을 정의하는 인터페이스로서 Trigger 개체를 이용하여 스케쥴할 수 있다.
  • JobDetail 는 작업명과 작업그룹과 같은 수행할 Job에 대한 상세 정보를 정의하는 개체이다.
  • Trigger 는 정의한 Job 개체의 실행 스케쥴을 정의하는 개체로서 Scheduler 개체에게 Job 수행시점을 알려주는 개체이다.

Quartz 스케쥴러는 수행 작업을 정의하는 Job과 실행 스케쥴을 정의하는 Trigger를 분리함으로써 유연성을 제공한다. Job 과 실행 스케쥴을 정의한 경우, Job은 그대로 두고 실행 스케쥴만을 변경할 수 있다. 또한 하나의 Job에 여러 개의 실행 스케쥴을 정의할 수 있다.

Quartz 스케쥴러 사용 예제

Quartz 스케쥴러의 이해를 돕기 위해 간단한 예제를 살펴본다. 다음 예는 Quartz 매뉴얼에서 참조한 것으로 Quartz를 사용하는 방법과 사용자 Job을 설정하는 방법을 보여준다.

사용자 정의 Job

사용자는 Job 개체를 생성하기 위해 org.quartz.Job 인터페이스를 구현하고 심각한 오류가 발생한 경우 JobExecutionException 예외를 던질 수 있다. Job 인터페이스는 단일 메소드로 execute()을 정의한다.

 public class DumbJob implements Job {
    public void execute(JobExecutionContext context)
      throws JobExecutionException
    {
      System.out.println("DumbJob is executing.");
    }
  }
  • DumbJob은 Job 인터페이스의 execute() 메소드를 구현한다.
  • execute() 메소드는 단순히 Job이 수행됨을 표시하는 메시지를 출력한다.
Quartz 사용 코드
  JobDetail jobDetail = 
            new JobDetail("myJob",// Job 명
              sched.DEFAULT_GROUP,  // Job 그룹명('null' 값인 경우 DEFAULT_GROUP 으로 정의됨)
              DumbJob.class);       // 실행할 Job 클래스
 
  Trigger trigger = TriggerUtils.makeDailyTrigger(8, 30);  // 매일 08시 30분 실행
  trigger.setStartTime(new Date()); // 즉시 시작
  trigger.setName("myTrigger");
 
  sched.scheduleJob(jobDetail, trigger);
  • 우선 Job 설정을 위해 JobDetail 클래스를 정의한다.
  • TriggerUtils을 이용하여 매일 8시30분 실행하는 Trigger를 생성한다.
  • 마지막으로, Scheduler에 JobDetail과 Trigger를 등록한다.

Spring 과 Quartz 통합

Spring은 Scheduling 지원을 위한 통합 클래스를 제공한다. Spring 2.5 는 JDK 1.3 버전부터 포함된 Timer 와 오픈소스 소프트웨어인 Quartz 스케쥴러를 지원한다. 여기서는 Quartz 스케쥴러와 Spring을 통합하여 사용하는 방법을 살펴본다. 
Quartz 스케쥴러와의 통합을 위해 Spring은 Spring 컨텍스트 내에서 Quart Scheduler와 JobDetail, Trigger 를 빈으로 설정할 수 있도록 지원한다. 다음은 예제를 중심으로 Quartz 작업 생성과 작업 스케쥴링, 작업 시작 방법을 살펴본다.

작업 생성

Spring은 작업 생성을 위한 방법으로 다음 두 가지 방식을 제공한다.

  • JobDetailBean을 이용한 방법으로, QuartzJobBean을 상속받아 Job 클래스를 생성하는 방법
  • MethodInvokingJobDetailFactoryBean을 이용하여 Bean 객체의 메소드를 직접 호출하는 방법
JobDetailBean을 이용한 작업 생성

JobDetail는 작업 실행에 필요한 정보를 담고 있는 객체이다. Spring은 JobDetail 빈 생성을 위해 JobDetailBean을 제공한다. 예를 들면 다음과 같다.

JobDetailBean 소스 코드

package egovframework.rte.fdl.scheduling.sample;
 
public class SayHelloJob extends QuartzJobBean {
 
	private String name;
 
	public void setName (String name) {
		this.name = name;	
	}
 
	@Override
	protected void executeInternal (JobExecutionContext ctx) throws JobExecutionException {
		System.out.println("Hello, " + name);
	}
}
  • SayHelloJob 클래스는 작업 생성을 위해 QuartzJobBean의 executeInternal(..) 함수를 오버라이드한다.

JobDetailBean 설정

 <bean id="jobDetailBean"
	class="org.springframework.scheduling.quartz.JobDetailBean">
	<property name="jobClass" value="egovframework.rte.fdl.scheduling.sample.SayHelloJob" />
	<property name="jobDataAsMap">
		<map>
			<entry key="name" value="JobDetail"/>
		</map>
	</property>
  </bean>
  • jobDataAsMap 개체를 이용하여 JobDetail 개체에 Job 설정에 필요한 속성 정보를 전달한다.
MethodInvokingJobDetailFactoryBean을 이용한 작업 생성

소스 코드

package egovframework.rte.fdl.scheduling.sample;
 
public class SayHelloService {
 
	private String name;
 
	public void setName (String name) {
		this.name = name;	
	}
 
	public void sayHello () {
		System.out.println("Hello, " + this.name);
	}
}
  • 작업 수행을 할 Bean 클래스를 정의한다.

설정

<bean id="sayHelloService" class="egovframework.rte.fdl.scheduling.sample.SayHelloService">
	<property name="name" value="FactoryBean"/>
</bean>
 
<bean id="jobDetailFactoryBean"
	class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
	<property name="targetObject" ref="sayHelloService" />
	<property name="targetMethod" value="sayHello" />
	<property name="concurrent" value="false" />
</bean>
  • 정의한 Bean 객체의 메소드를 직접 호출하는 작업을 생성하기 위해 MethodInvokingJobDetailFactoryBean을 정의한다.

작업 스케쥴링

Spring에서 주로 사용되는 Trigger타입은 SimpleTriggerBean과 CronTriggerBean 이 있다. SimpleTrigger 는 특정 시간, 반복 회수, 대기 시간과 같은 단순 스케쥴링에 사용된다. CronTrigger 는 유닉스의 Cron 명령어와 유사하며, 복잡한 스케쥴링에 사용된다. CronTrigger 는 달력을 이용하듯 특정 시간, 요일, 월에 Job 을 수행하도록 설정할 수 있다. 다음은 SimpleTriggerBean과 CronTriggerBean을 이용하여 앞서 생성한 작업을 스케쥴링하는 방법을 살펴본다.

SimpleTriggerBean을 이용한 설정

<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
	<property name="jobDetail" ref="jobDetailBean" />
        <!-- 즉시 시작 -->
	<property name="startDelay" value="0" />
   	<!-- 매 10초마다 실행 -->
	<property name="repeatInterval" value="10000" />
</bean>
  • 앞서 JobDetailBean 을 이용하여 생성한 작업을 스케쥴링을 위한 Trigger 에 등록한다. SimpleTriggerBean은 즉시 시작하고 매 10초마다 실행하도록 설정하였다.

CronTriggerBean을 이용한 설정

<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
   	<property name="jobDetail" ref="jobDetailFactoryBean" />
   	<!-- 매 10초마다 실행 -->
   	<property name="cronExpression" value="*/10 * * * * ?" />
</bean>
  • 앞서 MethodInvokingJobDetailFactoryBean 을 이용하여 생성한 작업을 스케쥴링을 위한 Trigger 에 등록한다. CronTriggerBean은 매 10초마다 실행하도록 설정하였다. 크론 표현식에 대한 자세한 설명은Quartz Cron 표현식를 참조한다.

작업 시작하기

스케쥴링한 작업의 시작을 위해 Spring 은 SchedulerFactoryBean을 제공한다.

설정

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
	<property name="triggers">
		<list>
			<ref bean="simpleTrigger" />
			<ref bean="cronTrigger" />
		</list>
	</property>
</bean>
  • SchedulerFactoryBean 을 이용하여 SimpleTriggerBean 과 CronTriggerBean 기반의 각 Trigger 작업을 시작한다.

참고자료



링크 : http://javastore.tistory.com/96 

링크 : http://kamsi76.egloos.com/470846 

링크 : http://briansjavablog.blogspot.kr/2012/09/spring-quartz-tutorial.html 

'Java > SpringFramework' 카테고리의 다른 글

[Spring] Spring Tiles  (0) 2013.04.05
[Spring] 스프링 버전 확인하기  (0) 2013.04.03
[Spring] Spring MVC에서 한글 처리  (0) 2012.07.20
[Spring] Springframework 2.5 fileupload  (0) 2012.07.04
[Spring] WebArgumentResolver  (0) 2012.07.01
posted by 뚱2

[Git] A successful git branching model

VCS/Git 2012. 11. 14. 16:53

출처 : http://dogfeet.github.com/articles/2011/a-successful-git-branching-model.html 

EGit 다운로드 : http://www.eclipse.org/egit/ 

문서 : http://www.javajigi.net/display/OE/Git 

EGit 가이드 : http://wiki.eclipse.org/EGit/User_Guide 

Pro git 한글문서 : http://dogfeet.github.com/articles/2012/progit.html 


Vincent Driessen님은 2010년 1월에 A successful Git branching model을 썼는데 매우 훌륭한 글입니다. Driessen님은 이 글에서 설명한 내용을 ‘git-flow'로 구현해 놓았습니다. 번역하도록 허락해주신 Driessen님께 감사드립니다.

내가 지난 일 년간 프로젝트를 할 때 사용한 개발 모델을 소개하고자 한다. 나는 이 모델을 업무에서도 사용했고 개인 프로젝트에서도 사용했다. 결과는 매우 성공적이었다. 진작부터 이 글을 쓰려고 벼르고 있었지만, 시간이 부족해 완성할 수 없었다. 나는 프로젝트를 진행하는 데 필요한 것을 하나하나 설명하기보다 순수하게 branching 전략과 배포 관리에 대해서 설명하고자 한다.

Git은 버전 관리용

이 그림은 Git으로 버전 관리하는 것을 한눈에 보여준다.

왜 Git인가?

다른 중앙집중식 버전 관리 시스템과 Git을 비교해보고 싶으면 웹에서 찾아라. 거기는 지금 전쟁 중이다. 나는 개발자이고 다른 것보다 Git을 선호한다. Git은 merging/branching에 대해 신세계를 열어 줬다. 예전에는 CSV/Subversion을 썼었는데 항상 merging/branching이 두려웠고(“주의: merge conficts라는 미친개가 물을 수도 있어요!”) 사실 잘 사용하지 않았다.

그런데 Git에서는 merging/branching이 매우 간단하다. merging/branching은 매일 한다. CVS/Subversoin 에서는 merging/branching과 관련된 내용이 마지막 장에 있어서 고급 사용자들이나 읽지만, Git 은 모두 3장 이전에 다룬다.

Git에서 merging/branching은 단순하고 자주 쓰기 때문에 더는 쫄지 않아도 된다. 버전 관리도구는 무엇보다 merging/branching이 쉬워야 한다.

도구에 대한 얘긴 그만 접고 개발 모델에 대한 얘기를 시작하자. 내가 여기서 말하고자 하는 모델은 단순히 소프트웨어 개발 프로세스를 관리하려고 팀원 모두가 따라야 하는 치짐일 뿐이다.

분산이지만 중앙집중식처럼

이 브랜치 모델에는 중앙 저장소가 하나 필요하다. 사람들이 중앙에 두고 공유하는, 의미상으로 “진짜” 중앙 저장소 말이다. Git은 DVCS라서 본질적으로 모든 저장소가 같다. 중앙 저장소라고 해서 금칠 돼 있는 것이 아니다. 이 중앙 저장소를 origin으로 추가한다. Git을 사용하는 사람에게는 origin이라는 이름이 매우 친근하다.

Decentralized but centralized

개발자 모두 origin에 push/pull할 수 있지만, 중앙집중식에서는 모든 개발자가 다른 모듈 팀에서 수정한 것까지도 pull해야 한다. 예를 들어 혼자 하기 어려운 기능은 둘, 셋이서 함께 개발하고 나서 origin에 push해야 한다. 개발 중인 것을 origin에 push하지 않는다. 이 그림에서 Alice와 Bob, Alice와 David, Clair와 David은 각각 팀을 만들었다:

이것을 Git 언어로 풀어보면 Alice는 자신의 저장소에 Bob의 저장소를 bob이라는 이름으로 추가한다는 것을 말한다. 나머지 팀원과 팀도 모두 똑같이 한다.

주요 브랜치

branches

이 개발 모델은 전혀 새롭지 않다. 핵심은 기존에 있던 개념들이다. 주요 브랜치 두 개는 중앙 저장소에 영원히 유지한다:

  • master
  • develop

Git 사용자라면 누구나 익숙한 master 브랜치와 develop 브랜치를 병행으로 유지한다.

먼저 배포했거나 곧 배포할(production-ready) 코드는 origin/master에 두고 관리한다.

그리고 다음에 배포할 것을 개발하는 코드는 origin/develop에 두고 관리한다. 혹자는 이 브랜치를 “통합 브랜치(integration branch)"라고 부르기도 하는데, 이 브랜치를 자동으로 매일 빌드하는데 사용한다.

develop branch의 코드가 안정되고 배포할 준비가 되면 곧 master로 merge하고 배포 버전으로 태그를 단다. 이것을 어떻게 하는지 이 글에서 자세히 설명한다.

즉, 정의한 대로 master로 merge하는 것은 새 버전을 배포하는 것을 의미한다. 우리는 이것을 매우 엄격하게 지킬 것이다. 그래서 master 브랜치에 커밋될 때마다 Git hook 스크립트로 자동으로 빌드하고 말아서 운영 서버로 배포할 수 있다.

보조 브랜치

master와 develop 브랜치말고 다른 브랜치도 필요하다. 기능을 구현하고, 배포를 준비하고, 이미 배포한 제품이나 서비스의 버그를 빠르게 해결해야 한다. 이 모든 것을 동시에 진행해야 하기 때문에 다양한 브랜치가 필요하다.

우리가 사용할 브랜치의 종류는 다음과 같다:

  • feature 브랜치
  • release 브랜치
  • hotfix 브랜치

각 브랜치마다 만든 목적이 있고 어떤 브랜치에서 갈라져 나왔는지, 어떤 브랜치에 merge할 지에 따라 꼭 지켜야 규칙도 있다. 이제 이 얘기를 하려고 한다.

이 분류는 어떻게 사용할지에 따라 나누었다. 하지만 기술적으로는(technically) 모두 같은 브랜치다. Git의 다른 브랜치와도 똑같다.

feature 브랜치

갈라져 나온 브랜치: develop
다시 merge할 브랜치: develop
브랜치 이름 규칙: master, develop, release-*, hotfix-*를 제외한 것

feature 브랜치(토픽 브랜치라고도 부른다)는 다음, 아니면 다다음, 어쨌든 조만간에 배포할 기능을 개발하는 브랜치다. 기능을 개발하기 시작할 때에는 사실 언제 배포할 수 있는지 알 수 없다. feature 브랜치는 그 기능을 다 완성할 때까지 유지하고 다 완성되면 develop 브랜치로 merge한다. 다음 배포에 확실히 넣을 거라고 판단될 때 merge하고 결과가 실망스러우면 아예 버린다.

feature 브랜치는 보통 개발자 저장소에만 있는 브랜치고 origin에는 push하지 않는다.

feature 브랜치 만들기

feature 브랜치를 develop 브랜치에서(base) 새로 만든다.

$ git checkout -b myfeature develop
Switched to a new branch "myfeature"
완성된 기능을 develop에 합치기

어떤 기능이 다 완성돼 다음 배포에 넣기로 했다면 develop 브랜치에 merge한다:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557).
$ git push origin develop

’–no-ff' 옵션을 주면 항상 merge 커밋을 만들어 merge한다. fast-forward로 merge할 수 있어도 fast-forward하지 않는다. 그러면 feature 브랜치에 추가된 모든 커밋이 merge되고 feature 브랜치에서 merge했다는 기록이 커밋 히스토리에 남는다. 그 둘을 비교해보자:

branches

후자처럼 fast-forward merge하면 나중에 커밋 히스토리를 다시 확인할 때 어떤 커밋이 어떤 기능(feature)을 구현한 것인지 확인하기 어렵다. 그래서 히스토리에 있는 커밋 메시지를 하나하나 눈으로 찾아야 한다. 추가한 feature를 되돌려야(revert) 할 때 feature와 관련된 모든 커밋을 되돌려야 하는데 merge 커밋이 없으면 욕이 절로 나올 것이다. –no-ff 옵션을 주고 merge했다면 되돌리기 쉽다.

물론 아무것도 없는 텅 빈 커밋 개체가 하나 추가로 만들어지긴 하지만 이득이 더 많다.

나는 –no-ff 옵션을 기본 옵션으로 설정하는 방법을 찾지 못했다. 나는 꼭 기본 옵션이 돼야 한다고 생각한다.

release 브랜치

갈라져 나온 브랜치: develop
다시 merge할 브랜치: develop, master
브랜치 이름 규칙: release-*

release 브랜치는 제품 배포를 준비하는 브랜치이다. 이 브랜치가 화룡이 승천할 수 있도록 점정하는 곳이다. 배포하는 데 필요한 버전 넘버, 빌드 일정 등의 메타데이터를 준비하고 사소한 버그도 잡는다. 이런 일을 release 브랜치에서 함으로써 develop 브랜치는 다음에 배포할 때 추가할 기능에 집중할 수 있다.

develop 브랜치가 배포할 수 있는 상태에 다다랐을 때 release 브랜치를 만드는 것이 중요하다. 이때, 배포해야 하는 기능이 모두 develop 브랜치에 merge돼 있어야 하고 이번에 배포하지 않을 기능은 release 브랜치를 만들 때까지 기다려야 한다.

release 브랜치를 만든다는 것은 이제 배포 버전을 부여하겠다는 것을 의미한다. 그때까지 develop 브랜치가 다음 배포가 어떤 모습일지 보여주지만, 아직 깨끗하게 정리된 상태가 아니다. 최종적으로 release 브랜치를 만들어 ‘0.1’, ‘0.3’ 같은 버전 넘버 붙을 때까지는 "진짜” 배포라고 할 수 없다. 그러니까 release 브랜치를 만들기로 하는 것이 버전 넘버를 새로 부여하기로 하는 것을 의미한다. 이것은 규칙이다.

release 브랜치 만들기

release 브랜치는 develop 브랜치에서 만든다. 예를 들어 배포할 수 있을 정도로 develop 브랜치가 준비돼 이제 곧 새 버전을 배포할 것이라고 하자. 그리고 현재 배포된 버전이 ‘1.1.5'이고 새 버전은 '1.1.6'이나 '2.0'이 아니라 '1.2’ 버전으로 배포하기로 했다. 그럼 다음과 같은 이름으로 release 브랜치를 만든다:

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

브랜치를 새로 만들고 버전 넘버를 생성했다. bump-version.sh는 버전 넘버가 들어 있는 파일을 전부 수정하는 가상의 쉘 스크립트다. 손으로 직접 수정해도 된다. 중요한 것은 이 시점에 파일을 수정한다는 점이다. 그리고 수정한 파일을 커밋한다.

새로 만든 release 브랜치는 잘 말아서 진짜로 배포할 때까지 유지한다. 그동안 발견한 버그는 develop 브랜치가 아니라 이 브랜치에서 해결하고 새 기능은 이 브랜치에 추가하지 않는다. 그런 기능은 develop 브랜치에 merge하고 다음 배포로 미뤄야 한다.

release 브랜치 마치기

release 브랜치가 진짜 배포할 상태가 되면 배포한다. master 브랜치에 있는 것을 배포하는 것으로 정의했으므로 먼저 release 브랜치를 master로 merge한다. 그리고 나중에 이 버전을 찾기 쉽도록 태그를 만들어 지금 master가 가리키는 커밋을 가리키게 한다. 그리고 release 브랜치를 develop 브랜치에 merge하고 다음에 배포할 때 release 브랜치에서 해결한 버그가 적용되도록 한다.

먼저 처음 두 단계, master에 merge하고 tag를 단다:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

release 브랜치로 해야 할 일을 끝냈고 미래를 위해 tag도 달았다. tag를 달 때 -s나 -u 옵션을 주고 암호화 알고리즘을 이용해서 서명할 수도 있다.

그리고 develop 브랜치에 다시 merge해서 release 브랜치에서 수정한 것이 앞으로도 계속 유지되게 한다:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

버전 넘버를 수정했기 때문에 여기서 merge할 때에는 충돌이 날 확률이 높다. 충돌이 나면 수정해서 커밋한다.

이제 진짜로 배포했기 때문에 release 브랜치는 더는 필요 없다. 삭제한다:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

hotfix 브랜치

갈라져 나온 브랜치: master
다시 merge할 브랜치: develop, master
브랜치 이름 규칙: hotfix-*

hotfix branches

미리 계획을 세워두지 않는다는 점만 빼면 hotfix 브랜치도 새로운 배포를 준비하는 것이기 때문에 release 브랜치와 비슷하다. 이것은 이미 배포한 운영 버전에 생긴 문제를 해결하기 위해 만든다. 운영 버전에 생긴 치명적인 버그는 즉시 해결해야 하기 때문에 문제가 생기면 master 브랜치에 만들어 둔 tag로부터 hotfix 브랜치를 만든다.

그리고 버그를 잡는 사람이 일하는 동안에도 다른 사람들은 develop 브랜치에서 하던 일을 계속 할 수 있다.

hotfix 브랜치 만들기

hotfix 브랜치는 master 브랜치에서 만든다. 예를 들어 현재 운영 버전이 1.2이고 심각한 버그가 발견됐다. develop 브랜치는 아직 불안정하기 때문에 hotfix 브랜치를 만들고 거기서 버그를 잡는다:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

브랜치를 만들고 버전 넘버를 바꾸는 것을 잊으면 안 된다!

버그를 해결하고 나서 커밋한다. 한두 개의 커밋으로 해결한다:

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)
hotfix 브랜치 마치기

버그를 잡았으면 다시 master에 merge하고 다시 develop 브랜치에도 merge해야 한다. 그래야 다음에 배포할 때도 포함된다. release 브랜치를 마치는 방법과 같다.

먼저 master에 merge하고 tag를 단다:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

이때에도 -s나 -u 옵션으로 tag에 서명할 수 있다.

그리고 develop에도 merge한다:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
erge made by recursive.
(Summary of changes)

만약 아직 release 브랜치가 삭제되지 않고 있다면 develop 브랜치가 아니라 release 브랜치에 merge한다. release 브랜치가 완료되면 결국 develop 브랜치에 merge될 것이다. 그런데 develop 브랜치도 즉시 해결해야 하면 release 브랜치가 끝날 때까지 기다리지 말고 develop 브랜치에 즉시 merge한다. 문제가 생기지 않도록 조심스럽게 merge한다.

이제 이 임시 브랜치를 삭제한다:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).

결론

이 모델은 전혀 새로운 게 아니다. 이 모델이 제시하는 그림은 내가 프로젝트를 할 때 정말 유용했다. 팀원 모두 머릿속에 같은 그림을 그리고 일할 수 있다. 이 모델은 팀이 브랜치와 배포 프로세스를 이해하고 공유 개발할 수 있도록 도와준다.

고품질 PDF 버전도 올려 두었으니 언제든지 볼 수 있도록 벽에 붙여두면 좋다.

다이어그램 이미지 파일의 Apple Keynote 파일도 요청하는 사람이 많아서 올렸다.

'VCS > Git' 카테고리의 다른 글

[Git] Advanced Git  (0) 2013.11.27
[Git] Git은 어떻게 동작하는가?  (0) 2013.11.26
[Git] Tortoisegit  (0) 2013.04.15
[Git] Git Tutorial  (0) 2013.04.01
[Git] SourceTree (windows)  (0) 2013.03.30
posted by 뚱2

[Struts] 스트럿츠

Java/Struts 2012. 10. 30. 00:45

스트럿츠 흐름 : http://blog.naver.com/ewideplus?Redirect=Log&logNo=10085765282

스트럿츠 셋팅 : http://blog.naver.com/eunicon?Redirect=Log&logNo=100044759135 



posted by 뚱2

링크 : http://www.cdrinfo.co.kr/121 

posted by 뚱2

http://easymicro.egloos.com/5488188 

http://blog.naver.com/PostView.nhn?blogId=rookieangel&logNo=140155967057  


http://www.superkts.pe.kr/helper/view.php?seq=264&PHPSESSID=5447acbb880ada74d8d967e36eac58eb 




posted by 뚱2

[POI] Java Excel 파일 읽기

Java/POI 2012. 9. 19. 22:32

http://visu4l.tistory.com/362 


posted by 뚱2

윈도우에서 javascript를 사용할수 있는 방법
CreateObject로 COM을 사용할수 있기때문에 조금만 머리 굴리면 웬만한건 다 될듯 하다.

 


Object Model : http://msdn.microsoft.com/ko-kr/library/a74hyyw0.aspx
링크         : http://msdn.microsoft.com/ko-kr/library/9bbdkx3k.aspx
Reference : http://msdn.microsoft.com/ko-kr/library/98591fh7.aspx
참고         : http://bybi.tistory.com/320

 

간단한 javascript 코드를 테스트 한다거나 유틸리티성 변환 프로그램을 만들때 쉽고 가볍게 만들수 있어


애용 하고 있습니다.


요즘 추세대로 익명함수를 바로 호출하여 지역화 시켜서 사용하면 편합니다.


Windows Host Script : http://www.taeyo.pe.kr/lecture/20_Tips/wsh_01.htm 


// 테스트 코드

(function($) {

var msg    = "기본신청기간(2011년 11월 01일 ~ 2012년 01월 05일 )";

var result = /.*?\((.*?)\).*?/gi.exec(msg);

if ( result != null )

{

$.Echo(result[1]);

}

})(WScript);


posted by 뚱2

링크 : http://luvstudy.tistory.com/13 

posted by 뚱2

링크 : http://www.zdnet.co.kr/news/news_view.asp?artice_id=00000039147106&type=det 

 

posted by 뚱2

링크 : http://blog.daum.net/toto-red/7861311 



1_iBATIS-SqlMaps-2_ko.pdf



목차


  1. [2008.08.20] resultClass="java.util.HashMap" 으로  Date 형식을 가져오면 yyyy-mm-dd 까지만 가져오고 시간짤림
  2. [2008.07.29] Caused by: java.sql.SQLException: 데이터 크기가 해당 유형의 최대 크기보다 큽니다: 7891 (Clob 처리)
  3. [2008.07.23] The content of elements must consist of well-formed character data or markup.  Query에 '<' 사용시 #
  4. [2008.07.03] parameterClass, resultClass 모두 HashMap으로 처리하던 중 CLOB를 읽으면 oracle.sql.CLOB@12ca580 이렇게 됨#
  5. [2008.06.16] iBatis-Oracle, HashMap 사용시 컬럼을 소문자로 받아보자#
  6. [2008.06.11] 설정정보#
  7. [2008.06.11] SQLMaps를 사용하기 위한 객체 생성#
  8. [2008.06.11] Paging 처리#
  9. [2008.06.11] 두개이상의 테이블에 대한 조회 #
  10. [2008.06.10] Query 보기#
  11. [2008.06.09] SQL 조합하기#
  12. [2008.06.09] Dynamic Query#
  13. SVN 정보 ##
  14. 번역문서 ##
  15. 강좌및 관련작성문서##
  16. 관련툴## 

posted by 뚱2

[log4j] log4j 설정

Java/log4j / logback 2012. 7. 5. 15:37

링크 : http://rahxephon.tistory.com/1460 

properties : http://blog.naver.com/zoom7810?Redirect=Log&logNo=50032106915 



링크 : http://slog2.egloos.com/3574039 



Log4jQuickRef.pdf


posted by 뚱2

링크 : http://springsource.tistory.com/91 

posted by 뚱2

'.Net > XtraGrid' 카테고리의 다른 글

[XtraGrid] Online Document  (0) 2012.04.13
[XtraGrid] Copy & Paste 구현  (0) 2012.04.11
[XtraGrid] Checkbox 구현하기  (1) 2012.04.06
[XtraGrid] Fixed Columns  (0) 2012.04.05
[XtraGrid] DevExpress XtraGrid  (0) 2012.03.28
posted by 뚱2

[Util] Ping Test Easy

Network 2012. 4. 6. 13:32
도스용 핑 테스트와 똑같은 기능을 구현한 프로그램이다

네트웍 프로그램을 만들거나 테스트 할 때 유용 할 듯 하다.


링크 : http://www.pingtester.net/



pingtest.exe



'Network' 카테고리의 다른 글

[KT EGG] 스트롱에그 KWD-B2600  (0) 2012.09.20
[Ping] KT 핑 테스트  (0) 2012.06.30
아이피 위치 확인 하는 방법  (0) 2012.02.07
hosts 파일 수정  (0) 2011.09.22
유용한 NETSTAT 명령어  (0) 2008.07.14
posted by 뚱2

[XtraGrid] DevExpress XtraGrid

.Net/XtraGrid 2012. 3. 28. 22:26

'.Net > XtraGrid' 카테고리의 다른 글

[XtraGrid] Online Document  (0) 2012.04.13
[XtraGrid] Copy & Paste 구현  (0) 2012.04.11
[XtraGrid] How to make my grid columns read-only  (0) 2012.04.08
[XtraGrid] Checkbox 구현하기  (1) 2012.04.06
[XtraGrid] Fixed Columns  (0) 2012.04.05
posted by 뚱2

'.Net > Spring.Net' 카테고리의 다른 글

[Spring.Net] Spring.Net 개발가이드  (0) 2012.12.10
posted by 뚱2

[SourceGrid] 즐겨찾기

.Net/SourceGrid 2012. 3. 14. 14:35
링크 : http://sourcegrid.codeplex.com/ 
문서 : http://sourcegrid.codeplex.com/documentation 

이번에 프로젝트를 위해서 무료 그리드를 찾던중 발견한 그리드 몰랐는데 역사가 오래되었다.
개발툴을 만드는 용도기 때문에 기본 기능으로 충분할 것 같다.

 
posted by 뚱2

[C#] internal 지정자

.Net/C# 2012. 3. 12. 14:26

'.Net > C#' 카테고리의 다른 글

[C#] log4net  (0) 2012.04.03
[C#] vshosting.exe 가 뭘까요?  (0) 2012.03.26
[C#] Dynamic Method Call With Out Parameter  (0) 2012.03.22
[즐겨찾기] C# TreeView MultiSelect  (0) 2012.03.15
[즐겨찾기] 무료서적 Inside C# 2nd  (0) 2012.03.10
posted by 뚱2

[.Net] System.CodeDom namespace

.Net/.Net 2012. 3. 9. 13:10
posted by 뚱2

[즐겨찾기] .Net Install

.Net/.Net 2012. 3. 8. 10:30
posted by 뚱2