Mac, Linux, Window 상관없이 외장하드를
써야하는 상황에서는 FAT32로 포멧하는것이 필요하다.

Swissknife 홈페이지
다운로드 :

이 SW는 다양한 디바이스와 포멧유형을 선택할 수 있게해주는 프로그램이며 무료사용가능하다.


SW를 사용하지 않고 format 명령어가 있는 윈도우의 경우라면
format /FS:FAT32 F:
같은 명령어를 사용하여 처리하는 방법도 있다.





TortoiseSVN 초보자 가이드

2005-03-23 광운대학교 K-NET 5기 조형렬

 

 

 

차 례

1. 무엇을 설명하고 있는 문서인가?    2

2. TortoiseSVN 설치하기    2

2.1 TortoiseSVN 설치    2

2.2 TortoiseSVN 한글 언어팩 설정하기    3

3. TortoiseSVN 시작하기    4

3.1 저장소 생성하기    4

3.2 작업용 복사본 가져오기 (SVN 체크아웃)    5

3.3 폴더 및 파일 추가하기    7

3.4 저장소에 반영하기 (SVN 커밋)    9

3.5 파일 수정하기    11

3.6 폴더 및 파일 삭제하기    12

3.7 폴더 및 파일 이름 바꾸기    12

3.8 폴더 및 파일 이동하기    13

3.9 수정사항 되돌리기    13

3.10 수정사항 확인하기    14

4. TortoiseSVN 속성 다루기    16

4.1 무시목록 사용하기    17

4.2 키워드 사용하기    19

5. TortoiseSVN 리비전 다루기    20

5.1 로그보기    20

5.2 원하는 리비전 체크아웃 하기    21

5.3 익스포트    21

5.4 저장소 브라우저    22

6. TortoiseSVN 여러 사용자와 사용하기    23

6.1 업데이트하기 (SVN 업데이트)    23

6.2 충돌 처리하기    23

6.3 패치 사용하기    27

6.4 브랜치/태그 사용하기    29

7. 참고자료    32

 

1. 무엇을 설명하고 있는 문서인가?

TortoiseSVN은 Subversion이라는 버전 컨트롤 시스템을 위한 윈도우용 클라이언트 프로그램입니다. 여기서 버전 컨트롤 시스템이란 폴더 및 파일의 모든 수정 내역을 효율적으로 기록하고 관리하는 시스템을 의미합니다. 버전 컨트롤 시스템을 사용하면 언제든 예전에 수정하였거나 삭제한 파일을 다시 불러와 확인할 수 있습니다. 또한 여러 사용자가 동시에 파일을 열거나 수정할 경우 발생할 수 있는 모든 문제들도 처리하여 줍니다. TortoiseSVN은 이러한 버전 컨트롤 시스템을 사용자가 쉽게 사용할 수 있도록 윈도우의 쉘과 통합된 형태의 인터페이스를 제공하는 클라이언트 프로그램입니다. 게다가 자체적으로 로컬 서버의 기능도 가지고 있어 따로 Subversion 서버를 설치하지 않고도 사용할 있다는 장점을 가지고 있습니다. Subversion은 새로운 버전 컨트롤 시스템으로서 CVS라는 유명한 버전 컨트롤 시스템의 단점을 개선하여 CVS를 대체하기 위해 만들어진 프로그램입니다. 이 문서는 이러한 버전 컨트롤 시스템을 처음 사용하는 사용자가 TortoiseSVN을 사용하여 파일의 버전을 관리하고 여러 작업을 수행할 수 있도록 그 시작을 돕는 문서입니다.

 

2. TortoiseSVN 설치하기

2.1 TortoiseSVN 설치

TortoiseSVN은 http://tortoisesvn.tigris.org/download.html에서 TortoiseSVN 설치프로그램과 한글 언어팩을 다운로드 받아 설치할 수 있습니다. 설치는 일반적인 윈도우 프로그램 설치와 동일합니다.

 

TortoiseSVN 다운로드 페이지

 

 

 

 

TortoiseSVN 설치 화면

TortoiseSVN은 오직 윈도우 탐색기에서 마우스 오른쪽 버튼을 클릭하여 나오는 메뉴를 통해서만 사용할 수 있습니다. 다음은 윈도우 탐색기에서 마우스 오른쪽 버튼을 클릭하여 나오는 메뉴의 모습입니다.

2.2 TortoiseSVN 한글 언어팩 설정하기

TortoiseSVN의 한글 언어팩을 설치하였다면, 다음과 같이 언어를 한글로 설정할 수 있습니다.

 

3. TortoiseSVN 시작하기

버전 컨트롤 시스템에서는 원본 파일을 직접 수정하여 저장할 수 없습니다. 대신 항상 원본에 대한 복사본을 얻어온 후 작업해야 합니다. 복사본을 얻어 와 새롭게 추가하였거나 원하는 데로 수정을 하였다면 이를 다시 원본에 반영해야만 원본이 변경되게 됩니다. 이러한 일련의 과정이 버전 컨트롤 시스템을 사용하는 기본적인 방법입니다. 여기서 원본 파일들에 대한 정보는 저장소라는 곳에 저장이 됩니다. 따라서 항상 버전 컨트롤 시스템을 사용하기에 앞서 먼저 저장소를 생성해야 합니다. 이 문서에서는 지역 저장소만을 사용합니다.

 

3.1 저장소 생성하기

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* 저장소 형식 선택 시 참고사항

버클리 데이터베이스(BDB)의 경우 데이터베이스 파일을 여러 사용자가 동시에 사용할 때 데이터베이스 파일이 깨지는 경우가 발생한다는 보고가 있습니다. 또한 BDB는 읽기 전용 속성의 저장소나 네트워크 공유에 저장소를 만들 수 없고, 프로그램의 비정상 종료 시에도 데이터베이스 파일이 깨질 수 있습니다. 반면에 FSFS의 경우 높은 이식성과 빠른 속도를 제공하지만, BDB에 비해 사용된 기간이 짧고 모든 버전 정보가 각각의 일반 파일들로 저장되기 때문에 파일이 많이 생긴다는 단점이 있습니다. 여기서 어떠한 저장소를 선택하든 저장소의 안정성에 대해 맹신해서는 안됩니다. 데이터 보호를 위해 항상 저장소를 주기적으로 백업하는 것이 좋습니다.

 

3.2 작업용 복사본 가져오기 (SVN 체크아웃)

작업을 하기 위한 복사본을 가져오는 작업을 체크아웃(checkout)이라고 합니다. 다음과 같이 체크아웃을 해서 저장소로부터 작업용 복사본을 가져옵니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* .svn 폴더에 대하여

윈도우 탐색기에서 숨김 파일 및 폴더를 표시하도록 설정하였다면 저장소로부터 체크아웃 된 모든 폴더에 대해 다음과 같은 .svn이라는 폴더가 있는 것을 볼 수 있습니다.

이 폴더는 TortoiseSVN에 의해 내부적으로 사용되는 정보를 저장하고 있는 폴더입니다. 따라서 절대로 임의로 수정하는 일이 있어서는 안됩니다.

 

3.3 폴더 및 파일 추가하기

먼저 작업용 복사본에 원하는 폴더 및 파일을 추가합니다. 여기서는 trunk 폴더와 HelloTortoiseSVN.cs 라는 파일을 추가하였습니다.

 

 

 

 

 

 

추가된 폴더 중 가장 최상위 폴더의 부모 폴더 안에서 다음과 같이 마우스 오른쪽 버튼을 클릭한 후 TortoiseSVN -> 추가를 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* 오버레이 아이콘에 대하여

체크아웃 된 최상위 폴더를 포함하여 작업용 복사본에 있는 폴더와 파일들의 아이콘에 다음과 같은 추가적인 오버레이 아이콘이 표시되는 것을 볼 수 있습니다.

 

 

 

 

 

TortoiseSVN은 체크아웃 된 폴더 및 파일들에 대하여 다음과 같은 오버레이 아이콘을 사용하여 폴더 및 파일의 상태를 시각적으로 표현합니다. 이를 통하면 직관적으로 폴더 및 파일의 상태를 확인할 수 있습니다.

 

저장소로부터 업데이트 된 후 아무 변경도 없었다는 것을 나타냅니다.

파일이 수정 된 후 아직 커밋 되지 않았다는 것을 나타냅니다.

업데이트 중 저장소와 작업용 복사본 사이에 충돌이 발생했다는 것을 나타냅니다.

(충돌에 대한 내용은 이후에 설명합니다.)

다음 커밋 시 저장소에 추가될 폴더 또는 파일이라는 것을 나타냅니다.

다음 커밋 시 저장소로부터 삭제될 폴더 또는 파일이라는 것을 나타내거나 버전 컨트롤 되는 파일이 폴더에 없다는 것을 나타냅니다.

 

3.4 저장소에 반영하기 (SVN 커밋)

작업용 복사본에서 파일을 추가, 수정 또는 삭제하는 등의 변경 작업을 했다고 해도 저장소에 바로 반영되는 것은 아닙니다. 모든 변경 작업은 커밋(commit)을 해야 저장소에 반영됩니다. 변경된 항목 중 가장 최상위 항목의 부모 폴더 안에서 다음과 같이 마우스 오른쪽 버튼을 클릭한 후 SVN 커밋…을 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* 리비전 번호에 대하여

폴더 및 파일을 추가하거나 수정하거나 삭제하는 등의 모든 변경 사항에 대한 정보는 리비전 번호로 관리됩니다. 리비전 번호는 커밋 할 당시의 모든 폴더와 파일의 구조 및 상태를 나타내는 버전 정보입니다. 즉 하나의 파일을 수정하고 커밋하거나 여러 개의 파일을 수정하고 커밋하거나 또는 기타 어떠한 변경 작업을 하고 커밋하여도 모두 하나의 리비전 번호를 증가시킨다는 것을 의미합니다.

Subversion은 이와 같이 모든 변경사항들을 하나의 리비전 번호로 관리하고 있습니다. 또한 커밋 작업 시 변경사항들이 모두 저장소에 반영되거나 또는 모두 반영되지 않도록 관리하고 있습니다. 이는 기존의 파일 단위로 버전을 관리하던 CVS와 같은 버전 컨트롤 프로그램에서 여러 파일들을 동시에 커밋하였을 때 프로그램 에러 및 시스템 에러 또는 네트워크 에러 등에 의해 커밋 작업이 비정상 종료되었을 경우 커밋 작업이 모두 취소되는 것이 아니라 일부 저장소에 반영된 채로 중단되었던 문제를 해결한 것입니다.

 

3.5 파일 수정하기

작업용 복사본에서 원하는 파일들을 수정합니다. 파일을 수정하면 파일의 아이콘이 변경되는 것을 볼 수 있습니다. 수정작업을 완료하였다면 수정된 파일들을 모두 포함하는 가장 최상위 폴더 안에서 마우스 오른쪽 버튼을 클릭하여 변경사항을 저장소로 커밋하면 됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

3.6 폴더 및 파일 삭제하기

작업용 복사본에서 삭제할 폴더 및 파일들을 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 삭제를 선택하여 삭제한 후 커밋합니다.

 

 

 

 

 

 

 

 

 

 

3.7 폴더 및 파일 이름 바꾸기

작업용 복사본에서 이름을 바꿀 폴더 또는 파일을 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 이름 바꾸기…를 선택하여 이름을 변경한 후 커밋합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.8 폴더 및 파일 이동하기

작업용 복사본에서 이동할 폴더 및 파일들을 선택한 후 마우스 오른쪽 버튼으로 클릭 드래그하여 목적지 폴더 위에서 오른쪽 버튼을 놓았을 때 나오는 메뉴에서 Subversion에 있는 파일을 여기로 옮김을 선택하여 옮긴 후 커밋합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.9 수정사항 되돌리기

작업용 복사본에서 아직 커밋 되지 않은 모든 변경사항을 취소하고자 한다면 모든 변경사항을 포함하고 있는 폴더 안에서 마우스 오른쪽 버튼을 클릭하여 나오는 메뉴에서 TortoiseSVN -> 되돌리기를 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.10 수정사항 확인하기

작업용 복사본에서 아직 커밋 되지 않은 모든 변경사항을 커밋하기 전에 미리 확인해 볼 수 있습니다. 모든 변경사항을 포함하고 있는 폴더 안에서 마우스 오른쪽 버튼을 클릭하여 나오는 메뉴에서 TortoiseSVN -> 수정내역 확인을 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* TortoiseSVN 명령 실행에 대하여

지금까지 해 온 것처럼 작업용 복사본에서 어떠한 항목도 선택하지 않은 상태로 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN 명령을 실행하면 이 명령은 해당 폴더에 대해서 실행됩니다. 폴더에 대한 명령실행은 대부분의 경우 폴더에 포함된 모든 항목에 대해서도 영향을 줍니다.

 

 

 

 

 

 

 

 

 

 

반면에 특정 항목을 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN 명령을 실행하면 이 명령은 선택된 항목에 대해서만 실행이 됩니다.

 

 

 

 

 

 

 

 

 

4. TortoiseSVN 속성 다루기

Subversion에서는 저장소에 저장된 폴더 및 파일에 대하여 임의의 이름/값 형태로 정보를 설정할 수 있습니다. 이렇게 설정되는 정보를 속성이라고 합니다. 속성은 아래와 같이 윈도우 탐색기에서 폴더 또는 파일의 속성을 선택하여 나오는 대화상자에서 Subversion 탭을 선택하여 설정할 수 있습니다. 속성도 버전관리가 되기 때문에 만약 속성을 추가, 수정 또는 삭제하였다면 커밋을 통해 이를 저장소에 반영해야 합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

속성 이름 중 "svn:"으로 시작하는 이름은 Subversion에 의해 예약된 이름으로 Subversion에 의해 특별한 의미로 사용됩니다. 따라서 임의의 목적으로 사용할 수 없습니다. 마찬가지로 "tsvn:"으로 시작하는 이름은 TortoiseSVN에 의해 예약되었고 "bugtraq:"으로 시작하는 이름은 버그 추적 도구를 위해 예약되었기 때문에 임의로 사용할 수 없습니다. 이들 예약된 속성 이름의 용도에 대한 자세한 설명은 관련 도움말을 참고하기 바랍니다. 여기서는 이들 중 자주 사용되는 두 가지를 소개하도록 하겠습니다.

 

4.1 무시목록 사용하기

작업용 복사본에서 작업을 하다 보면 그 결과로 자동으로 생성되는 폴더와 파일들이 존재할 수 있습니다. 예를 들어 텍스트 에디터에서 자동으로 생성해 주는 백업 파일이나 컴파일러에 의해 컴파일 된 실행파일 등이 있습니다. 이러한 폴더와 파일들은 대부분 없어도 되기 때문에 저장소에 저장되지는 않습니다. 그러나 TortoiseSVN은 이러한 불필요한 파일들을 구분할 수 없기 때문에 항상 아직 버전관리가 되지 않은 다른 중요한 파일들과 함께 관리하고 표시하여 줍니다. 이러한 불필요한 폴더와 파일들을 무시하게 하려면 이런 항목들을 무시목록에 추가하면 됩니다. 아래 그림과 같이 무시할 폴더 및 파일들을 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 무시 목록에 추가 -> [파일이름] 또는 *.[확장자]를 선택한 후 커밋합니다. 이 때 *.[확장자] 형태를 선택하면 해당 확장자의 모든 파일이 무시됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

무시목록은 폴더의 "svn:ignore" 속성으로 관리됩니다. 무시목록을 설정한 후 무시목록에 추가된 폴더 및 파일들의 부모폴더에서 Subversion 속성을 보면 다음과 같이 "svn:ignore" 속성 이름으로 값이 설정되어 있는 것을 볼 수 있습니다. 따라서 임의로 "svn:ignore" 속성을 수정하면 무시목록을 마음대로 관리할 수 있습니다. 특히 무시목록은 하위폴더에 영향을 주지 않기 때문에 만약 모든 하위폴더에도 같은 무시목록을 사용하고 싶다면 "svn:ignore" 속성을 수정하고 반복(C) 체크박스를 체크하여 적용한 후 커밋하면 됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

4.2 키워드 사용하기

키워드 속성을 사용하면 텍스트 파일에 파일의 리비전 번호와 마지막으로 저장소에 저장된 시간 등의 정보를 자동으로 작성하도록 할 수 있습니다. 예를 들어 다음과 같이 텍스트 파일을 작성합니다.

 

 

 

 

 

그 다음 해당 텍스트 파일의 "svn:keywords" 속성을 아래와 같이 설정합니다.

 

 

 

 

 

 

 

그리고 나서 커밋하면 텍스트 파일의 내용이 아래와 같이 자동으로 변경되는 것을 볼 수 있습니다.

 

 

 

 

 

키워드는 $Keyword$ 형식으로 되어있는 문자열로서 "svn:keywords" 속성 설정 여부에 따라 커밋 시 자동으로 특정 정보로 대체됩니다. 텍스트 파일에 사용할 수 있는 키워드는 다음과 같습니다.

 

LastChangedDate

파일이 커밋되어 저장소에서 변경되었던 시점에서의 마지막 수정시간을 나타냅니다. Date로 줄여 쓸 수 있습니다.

LastChangedRevision

파일이 커밋되어 저장소에서 변경된 후의 리비전 번호를 나타냅니다. Revision 또는 Rev로 줄여 쓸 수 있습니다.

LastChangedBy

파일을 커밋하여 저장소로 반영한 사용자를 나타냅니다. Author로 줄여 쓸 수 있습니다.

HeadURL

저장소에 있는 파일의 가장 최신 버전의 전체 URL을 나타냅니다. URL로 줄여 쓸 수 있습니다.

Id

이 키워드는 다른 키워드들이 나타내는 정보를 압축 조합하여 표시합니다.

 

5. TortoiseSVN 리비전 다루기

5.1 로그보기

지금까지 기록된 모든 수정사항에 대한 로그를 보려면 로그를 볼 폴더 및 파일들을 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 로그 보기를 선택합니다. 이 경우 선택된 폴더 및 파일들에 대한 로그만 표시됩니다. 만약 모든 로그를 보고 싶다면 작업용 복사본의 최상위 폴더를 선택한 후 로그 보기를 실행하면 됩니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

5.2 원하는 리비전 체크아웃 하기

SVN 체크아웃 대화상자에서 아래와 같이 체크아웃 하기를 원하는 리비전 번호를 지정하면 특정 리비전을 체크아웃 할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

* TortoiseSVN 체크아웃과 폴더에 대하여

TortoiseSVN을 사용하여 체크아웃 할 때 항상 저장소의 가장 최상위 폴더만을 체크아웃 할 수 있는 것은 아닙니다. TortoiseSVN의 체크아웃 된 각각의 폴더들은 부모 폴더와 어떠한 의존관계도 없기 때문에 독립적으로 존재할 수 있습니다. 따라서 만약 체크아웃되는 폴더 및 파일들이 상당히 많이 있다면 작업에 필요한 폴더만 지정해서 체크아웃 할 수 있습니다.

 

 

 

5.3 익스포트

익스포트는 ".svn" 폴더가 없는 복사본을 저장소로부터 가져옵니다. 윈도우 탐색기에서 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 익스포트…를 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

5.4 저장소 브라우저

저장소의 폴더 및 파일의 트리 구조를 확인하고 직접 수정 및 삭제 등의 작업을 하고 싶다면 저장소 브라우저를 사용하면 됩니다. 윈도우 탐색기에서 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 저장소 브라우저를 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6. TortoiseSVN 여러 사용자와 사용하기

Subversion의 저장소는 동시에 여러 사용자에 의해 사용될 수 있습니다. 즉 여러 사용자가 동일한 저장소로부터 동일한 작업용 복사본을 받아 수정작업등을 거친 후 동시 다발적으로 커밋하여 저장소를 변경시킬 수 있습니다. 따라서 저장소를 혼자만 사용하지 않는다면 다른 사용자에 의해 커밋 된 저장소의 변경사항을 수시로 확인하여 자신의 작업용 복사본에 반영해야 합니다.

 

6.1 업데이트하기 (SVN 업데이트)

저장소로부터 현재의 작업용 복사본을 업데이트하려면 업데이트할 항목들을 선택한 후 마우스 오른쪽 버튼을 누르거나 업데이트할 모든 항목들을 포함하고 있는 폴더 안에서 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 SVN 업데이트를 선택합니다.

 

 

 

 

 

 

 

 

6.2 충돌 처리하기

파일을 수정한 후 커밋하거나 업데이트 할 때 이미 다른 사용자가 해당 파일을 먼저 수정하고 커밋하였다면 그리고 서로의 수정사항이 안전하게 병합될 수 없다면 충돌이 발생합니다. 충돌이 발생하면 자신의 파일과 저장소에 저장된 파일 사이의 충돌사항을 확인하여 해결해야 합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Subversion은 충돌이 발생할 경우 충돌된 파일에 대하여 각각 3개의 추가적인 파일을 생성합니다. 생성되는 파일들은 아래와 같습니다.

 

filename.ext.mine

저장소로 커밋하려던 사용자의 원본 파일입니다.

filename.ext.rOLDREV

filename.ext.mine의 수정 전 원본이 되는 파일입니다.

filename.ext.rNEWREV

filename.ext.mine과 충돌을 일으킨 저장소에 저장된 새로운 버전의 파일입니다.

 

충돌을 해결하려면 충돌된 파일을 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 충돌 상황 편집을 선택합니다. 충돌 상황 편집을 선택하면 TortoiseSVN은 내부 병합도구인 TortoiseMerge를 실행하여 충돌사항을 확인하고 편집할 수 있도록 합니다. 그러나 현재 TortoiseMerge는 한글 처리에 문제가 있습니다. 따라서 여기서는 WinMerge라는 외부 병합도구를 설정하여 사용하였습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

병합도구를 사용하여 충돌사항을 확인하고 편집을 완료하였다면 아래와 같이 TortoiseSVN -> 충돌 해결됨을 선택하여 충돌상황 처리를 완료합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

* WinMerge에 대하여

WinMerge는 파일의 비교 및 병합에 사용되는 오픈소스 소프트웨어입니다. 현재 TortoiseSVN에서 제공하고 있는 기본 파일 비교 및 병합 프로그램인 TortoiseMerge가 한글을 제대로 지원하고 있지 않기 때문에 WinMerge를 대신 사용하면 유용합니다. WinMerge는 http://winmerge.org에서 다운로드 받아 설치할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

WinMerge를 다운로드 받아 설치하였다면 아래와 같이 TortoiseSVN 설정 대화상자의 비교/병합 탭에서 WinMerge를 TortoiseSVN의 파일 비교 및 병합 작업에 사용되는 기본 프로그램으로 설정할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

위와 같이 설정을 하였다면 이제 WinMerge는 충돌상황 해결을 위한 병합 프로그램으로서 사용될 뿐 아니라 파일 비교가 필요한 다양한 상황에서도 사용됩니다. 예를 들어 아래와 같이 파일을 수정한 후 TortoiseSVN -> 비교를 실행하면 해당 파일의 현재 수정사항을 확인할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

6.3 패치 사용하기

패치는 현재의 작업용 복사본에 대한 모든 수정사항을 저장하고 있는 파일입니다. 패치는 주로 저장소에 대한 쓰기권한이 없는 사용자가 쓰기권한이 있는 관리자에게 자신의 수정사항을 보내기 위해 사용합니다. 패치를 생성하려면 아래와 같이 수정사항을 모두 포함하고 있는 폴더 안에서 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 패치 생성…을 선택합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

관리자는 패치를 받은 후 아래와 같이 패치생성에 사용된 폴더와 동일한 폴더 안에서 TortoiseSVN -> 패치 적용…을 선택하여 패치를 적용할 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

패치파일은 속성에 대한 수정사항과 바이너리 파일에 대한 수정사항은 포함하지 않습니다. 따라서 이와 관련된 수정사항은 따로 전달하여 수동으로 적용해야 합니다.

 

6.4 브랜치/태그 사용하기

저장소 안에 있는 폴더 및 파일들에 대하여 따로 복사본을 만들어 사용하고 싶다면 브랜치/태그를 사용합니다. 이 때 이들 복사본을 어떻게 사용하느냐에 따라서 브랜치 또는 태그로 구분할 수 있습니다. 브랜치는 새로운 복사본을 만들어 기존 폴더 및 파일들을 건드리지 않으면서 테스트 등의 목적으로 임의의 수정작업을 하고자 할 때 사용합니다. 브랜치는 관례에 따라 저장소의 루트 폴더 아래의 branches라는 폴더에서 관리됩니다. 따라서 먼저 아래와 같이 branches 폴더를 생성합니다.

 

 

 

 

 

이제 브랜치를 만들려면 브랜치를 만들 폴더를 선택한 후 마우스 오른쪽 버튼을 눌러 나오는 메뉴에서 TortoiseSVN -> 브랜치/태그…를 선택합니다. 여기서는 trunk 폴더를 브랜치로 만들었습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

태그는 저장소의 특정 리비전을 따로 버전 번호를 부여하여 기록하고자 할 때 사용합니다. 예를 들어 프로젝트가 버전 1.0.0 이 되어 배포될 예정이라면 아래와 같이 버전 1.0.0 프로젝트의 태그를 만들어 관리할 수 있습니다. 태그도 관례에 따라 tags 폴더에서 관리되기 때문에 태그를 만들기 전에 먼저 tags 폴더를 추가한 후 진행합니다. 태그는 내부적으로 브랜치와 동일하기 때문에 만드는 방법도 브랜치와 동일합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

태그는 한 번 만들었으면 절대 수정하지 말아야 합니다. 그러나 만약 버그 등에 의하여 부득이 태그를 수정하여야 한다면, 먼저 해당 태그에 대한 브랜치를 만들어 수정하고, 수정이 완료되었을 경우 이를 새로운 태그로 만드는 방법을 써야 합니다. 예를 들어 위에서 만든 태그 같은 경우 release_v1.0.0의 버그를 수정해야 한다면, 브랜치를 만들어 버그 수정을 완료한 후 release_v1.0.1 이라는 새로운 태그를 만들 수 있습니다.

Subversion이 브랜치/태그를 만들 때 폴더와 파일들을 실제로 복사하는 것은 아닙니다. 브랜치/태그는 단지 원본이 되는 폴더 및 파일들에 대한 링크만을 저장합니다. 따라서 복사본의 증가에 따른 하드디스크 용량 증가 문제를 걱정하지 않아도 됩니다.

 

* 저장소의 폴더 구조에 대하여

위에서 본 것처럼 브랜치와 태그는 관례적으로 branches 폴더와 tags 폴더 안에서 관리한다고 하였습니다. 이와 비슷하게 Subversion은 사용자가 저장소의 주요 작업 폴더 및 파일들을 저장소에 저장할 때 trunk 라는 폴더를 만들어 저장할 것을 권장하고 있습니다. 따라서 만약 저장소에 하나의 프로젝트만 있다면 저장소의 루트 폴더는 다음과 같은 세 개의 폴더를 포함하게 됩니다.

 

/trunk

/branches

/tags 

 

만약 저장소에 하나 이상의 프로젝트가 있다면 다음과 같이 각각의 프로젝트 별로 trunk, branches, tags폴더를 만들 수 있습니다.

 

/engine/trunk

/engine/branches

/engine/tags

/gui/trunk

/gui/branches

/gui/tags 

 

또는 다음과 같이 trunk, branches, tags 폴더 안에 각각 프로젝트 폴더를 만들 수 있습니다.

 

/trunk/engine

/trunk/gui

/branches/engine

/branches/gui

/tags/engine

/tags/gui 

 

저장소에 저장된 프로젝트들이 서로 긴밀하게 연관되어 있다면 두 번째 방법을 사용하는 것이 편리합니다. 저장소로부터 체크아웃 할 때는 trunk 폴더, branches 폴더 안의 브랜치들, tags 폴더 안의 태그들 중 필요한 폴더만 선택적으로 체크아웃 하여 사용합니다.

 

7. 참고자료

'삽질로그' 카테고리의 다른 글

Leopard 설치  (0) 2010.01.05
외장 HDD FAT32로 포멧하는 방법  (0) 2010.01.04
TortoiseSVN 초보자 가이드  (0) 2010.01.03
MSSQL 테이블명세 출력용 쿼리  (0) 2009.12.28
원격지원을 위한 SW  (1) 2009.12.16
원격지원 Tool TeamViewer  (0) 2009.12.15
Declare @i Int, @maxi Int
Declare @j Int, @maxj Int
Declare @sr int
Declare @Output varchar(4000)
--Declare @tmpOutput varchar(max)
Declare @SqlVersion varchar(5)
Declare @last varchar(155), @current varchar(255), @typ varchar(255), @description varchar(4000)

create Table #Tables  (id int identity(1, 1), Object_id int, Name varchar(155), Type varchar(20), [description] varchar(4000))
create Table #Columns (id int identity(1,1), Name varchar(155), Type Varchar(155), Nullable varchar(2), [description] varchar(4000))
create Table #Fk(id int identity(1,1), Name varchar(155), col Varchar(155), refObj varchar(155), refCol varchar(155))
create Table #Constraint(id int identity(1,1), Name varchar(155), col Varchar(155), definition varchar(1000))
create Table #Indexes(id int identity(1,1), Name varchar(155), Type Varchar(25), cols varchar(1000))

 If (substring(@@VERSION, 1, 25 ) = 'Microsoft SQL Server 2008')
   set @SqlVersion = '2008'
else if (substring(@@VERSION, 1, 26 ) = 'Microsoft SQL Server  2000')
   set @SqlVersion = '2000'
else
   set @SqlVersion = '2008'

Print '<html>'
Print '<head>'
Print '<title>::' + DB_name() + '::</title>'
Print '<style>'
   
Print '      body {'
Print '      font-family:verdana;'
Print '      font-size:9pt;'
Print '      }'
     
Print '      td {'
Print '      font-family:verdana;'
Print '      font-size:9pt;'
Print '      }'
     
Print '      th {'
Print '      font-family:verdana;'
Print '      font-size:9pt;'
Print '      background:#d3d3d3;'
Print '      }'
Print '      table'
Print '      {'
Print '      background:#d3d3d3;'
Print '      }'
Print '      tr'
Print '      {'
Print '      background:#ffffff;'
Print '      }'
Print '   </style>'
Print '</head>'
Print '<body>'

set nocount on
   if @SqlVersion = '2000'
      begin
      insert into #Tables (Object_id, Name, Type, [description])
         --FOR 2000
         select object_id(table_name),  '[' + table_schema + '].[' + table_name + ']', 
         case when table_type = 'BASE TABLE'  then 'Table'   else 'View' end,
         cast(p.value as varchar(4000))
         from information_schema.tables t
         left outer join sysproperties p on p.id = object_id(t.table_name) and smallid = 0 and p.name = 'MS_Description'
         order by table_type, table_schema, table_name
      end
   else if @SqlVersion = '2008'
      begin
      insert into #Tables (Object_id, Name, Type, [description])
      --FOR 2008
      Select o.object_id,  '[' + s.name + '].[' + o.name + ']',
            case when type = 'V' then 'View' when type = 'U' then 'Table' end, 
            cast(p.value as varchar(4000))
            from sys.objects o
               left outer join sys.schemas s on s.schema_id = o.schema_id
               left outer join sys.extended_properties p on p.major_id = o.object_id and minor_id = 0 and p.name = 'MS_Description'
            where type in ('U', 'V')
            order by type, s.name, o.name
      end
Set @maxi = @@rowcount
set @i = 1

print '<table border="0" cellspacing="0" cellpadding="0" width="550px" align="center"><tr><td colspan="3" style="height:50;font-size:14pt;text-align:center;"><a name="index"></a><b>Index</b></td></tr></table>'
print '<table border="0" cellspacing="1" cellpadding="0" width="550px" align="center"><tr><th>Sr</th><th>Object</th><th>Type</th></tr>'
While(@i <= @maxi)
begin
   select @Output =  '<tr><td align="center">' + Cast((@i) as varchar) + '</td><td><a href="#' + Type + ':' + name + '">' + name + '</a></td><td>' + Type + '</td></tr>'
         from #Tables where id = @i
  
   print @Output
   set @i = @i + 1
end
print '</table><br />'

set @i = 1
While(@i <= @maxi)
begin
   --table header
   select @Output =  '<tr><th align="left"><a name="' + Type + ':' + name + '"></a><b>' + Type + ':' + name + '</b></th></tr>',  @description = [description]
         from #Tables where id = @i
  
   print '<br /><br /><br /><table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td align="right"><a href="#index">Index</a></td></tr>'
   print @Output
   print '</table><br />'
   print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Description</b></td></tr><tr><td>' + isnull(@description, '') + '</td></tr></table><br />'

   --table columns
   truncate table #Columns
   if @SqlVersion = '2000'
      begin
      insert into #Columns  (Name, Type, Nullable, [description])
      --FOR 2000
      Select c.name,
               type_name(xtype) + (
               case when (type_name(xtype) = 'varchar' or type_name(xtype) = 'nvarchar' or type_name(xtype) ='char' or type_name(xtype) ='nchar')
                  then '(' + cast(length as varchar) + ')'
                when type_name(xtype) = 'decimal' 
                     then '(' + cast(prec as varchar) + ',' + cast(scale as varchar)   + ')'
               else ''
               end           
               ),
               case when isnullable = 1 then 'Y' else 'N'  end,
               cast(p.value as varchar(8000))
            from syscolumns c
               inner join #Tables t on t.object_id = c.id
               left outer join sysproperties p on p.id = c.id and p.smallid = c.colid and p.name = 'MS_Description'
            where t.id = @i
            order by c.colorder
      end
   else if @SqlVersion = '2008'
      begin
      insert into #Columns  (Name, Type, Nullable, [description])
      --FOR 2008  
      Select c.name,
               type_name(user_type_id) + (
               case when (type_name(user_type_id) = 'varchar' or type_name(user_type_id) = 'nvarchar' or type_name(user_type_id) ='char' or type_name(user_type_id) ='nchar')
                  then '(' + cast(max_length as varchar) + ')'
                when type_name(user_type_id) = 'decimal' 
                     then '(' + cast([precision] as varchar) + ',' + cast(scale as varchar)   + ')'
               else ''
               end           
               ),
               case when is_nullable = 1 then 'Y' else 'N'  end,
               cast(p.value as varchar(4000))
      from sys.columns c
            inner join #Tables t on t.object_id = c.object_id
            left outer join sys.extended_properties p on p.major_id = c.object_id and p.minor_id  = c.column_id and p.name = 'MS_Description'
      where t.id = @i
      order by c.column_id
      end
   Set @maxj =   @@rowcount
   set @j = 1

   print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Table Columns</b></td></tr></table>'
   print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Datatype</th><th>Nullable</th><th>Description</th></tr>'
  
   While(@j <= @maxj)
   begin
      select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="150px">' + isnull(name,'')  + '</td><td width="150px">' +  upper(isnull(Type,'')) + '</td><td width="50px" align="center">' + isnull(Nullable,'N') + '</td><td>' + isnull([description],'') + '</td></tr>'
         from #Columns  where id = @j
     
      print    @Output   
      Set @j = @j + 1;
   end

   print '</table><br />'

   --reference key
   truncate table #FK
   if @SqlVersion = '2000'
      begin
      insert into #FK  (Name, col, refObj, refCol)
   --      FOR 2000
      select object_name(constid), s.name,  object_name(rkeyid) ,  s1.name 
            from sysforeignkeys f
               inner join sysobjects o on o.id = f.constid
               inner join syscolumns s on s.id = f.fkeyid and s.colorder = f.fkey
               inner join syscolumns s1 on s1.id = f.rkeyid and s1.colorder = f.rkey
               inner join #Tables t on t.object_id = f.fkeyid
            where t.id = @i
            order by 1
      end  
   else if @SqlVersion = '2008'
      begin
      insert into #FK  (Name, col, refObj, refCol)
--      FOR 2008
      select f.name, COL_NAME (fc.parent_object_id, fc.parent_column_id) , object_name(fc.referenced_object_id) , COL_NAME (fc.referenced_object_id, fc.referenced_column_id)    
      from sys.foreign_keys f
         inner  join  sys.foreign_key_columns  fc  on f.object_id = fc.constraint_object_id  
         inner join #Tables t on t.object_id = f.parent_object_id
      where t.id = @i
      order by f.name
      end
  
   Set @maxj =   @@rowcount
   set @j = 1
   if (@maxj >0)
   begin

      print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Refrence Keys</b></td></tr></table>'
      print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Column</th><th>Reference To</th></tr>'

      While(@j <= @maxj)
      begin

         select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="150px">' + isnull(name,'')  + '</td><td width="150px">' +  isnull(col,'') + '</td><td>[' + isnull(refObj,'N') + '].[' +  isnull(refCol,'N') + ']</td></tr>'
            from #FK  where id = @j

         print @Output
         Set @j = @j + 1;
      end

      print '</table><br />'
   end

   --Default Constraints
   truncate table #Constraint
   if @SqlVersion = '2000'
      begin
      insert into #Constraint  (Name, col, definition)
      select object_name(c.constid), col_name(c.id, c.colid), s.text
            from sysconstraints c
               inner join #Tables t on t.object_id = c.id
               left outer join syscomments s on s.id = c.constid
            where t.id = @i
            and
            convert(varchar,+ (c.status & 1)/1)
            + convert(varchar,(c.status & 2)/2)
            + convert(varchar,(c.status & 4)/4)
            + convert(varchar,(c.status & 8)/8)
            + convert(varchar,(c.status & 16)/16)
            + convert(varchar,(c.status & 32)/32)
            + convert(varchar,(c.status & 64)/64)
            + convert(varchar,(c.status & 128)/128) = '10101000'
      end
   else if @SqlVersion = '2008'
      begin
      insert into #Constraint  (Name, col, definition)
      select c.name,  col_name(parent_object_id, parent_column_id), c.definition
      from sys.default_constraints c
         inner join #Tables t on t.object_id = c.parent_object_id
      where t.id = @i
      order by c.name
      end
   Set @maxj =   @@rowcount
   set @j = 1
   if (@maxj >0)
   begin

      print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Default Constraints</b></td></tr></table>'
      print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Column</th><th>Value</th></tr>'

      While(@j <= @maxj)
      begin

         select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="250px">' + isnull(name,'')  + '</td><td width="150px">' +  isnull(col,'') + '</td><td>' +  isnull(definition,'') + '</td></tr>'
            from #Constraint  where id = @j

         print @Output
         Set @j = @j + 1;
      end

   print '</table><br />'
   end


   --Check  Constraints
   truncate table #Constraint
   if @SqlVersion = '2000'
      begin
      insert into #Constraint  (Name, col, definition)
         select object_name(c.constid), col_name(c.id, c.colid), s.text
            from sysconstraints c
               inner join #Tables t on t.object_id = c.id
               left outer join syscomments s on s.id = c.constid
            where t.id = @i
            and ( convert(varchar,+ (c.status & 1)/1)
               + convert(varchar,(c.status & 2)/2)
               + convert(varchar,(c.status & 4)/4)
               + convert(varchar,(c.status & 8)/8)
               + convert(varchar,(c.status & 16)/16)
               + convert(varchar,(c.status & 32)/32)
               + convert(varchar,(c.status & 64)/64)
               + convert(varchar,(c.status & 128)/128) = '00101000'
            or convert(varchar,+ (c.status & 1)/1)
               + convert(varchar,(c.status & 2)/2)
               + convert(varchar,(c.status & 4)/4)
               + convert(varchar,(c.status & 8)/8)
               + convert(varchar,(c.status & 16)/16)
               + convert(varchar,(c.status & 32)/32)
               + convert(varchar,(c.status & 64)/64)
               + convert(varchar,(c.status & 128)/128) = '00100100')

      end
   else if @SqlVersion = '2008'
      begin
      insert into #Constraint  (Name, col, definition)
         select c.name,  col_name(parent_object_id, parent_column_id), definition
         from sys.check_constraints c
            inner join #Tables t on t.object_id = c.parent_object_id
         where t.id = @i
         order by c.name
      end
   Set @maxj =   @@rowcount
  
   set @j = 1
   if (@maxj >0)
   begin

      print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Check  Constraints</b></td></tr></table>'
      print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Column</th><th>Definition</th></tr>'

      While(@j <= @maxj)
      begin

         select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="250px">' + isnull(name,'')  + '</td><td width="150px">' +  isnull(col,'') + '</td><td>' +  isnull(definition,'') + '</td></tr>'
            from #Constraint  where id = @j
         print @Output
         Set @j = @j + 1;
      end

      print '</table><br />'
   end


   --Triggers
   truncate table #Constraint
   if @SqlVersion = '2000'
      begin
      insert into #Constraint  (Name)
         select tr.name
         FROM sysobjects tr
            inner join #Tables t on t.object_id = tr.parent_obj
         where t.id = @i and tr.type = 'TR'
         order by tr.name
      end
   else if @SqlVersion = '2008'
      begin
      insert into #Constraint  (Name)
         SELECT tr.name
         FROM sys.triggers tr
            inner join #Tables t on t.object_id = tr.parent_id
         where t.id = @i
         order by tr.name
      end
   Set @maxj =   @@rowcount
  
   set @j = 1
   if (@maxj >0)
   begin

      print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Triggers</b></td></tr></table>'
      print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Description</th></tr>'

      While(@j <= @maxj)
      begin
         select @Output = '<tr><td width="20px" align="center">' + Cast((@j) as varchar) + '</td><td width="150px">' + isnull(name,'')  + '</td><td></td></tr>'
            from #Constraint  where id = @j
         print @Output
         Set @j = @j + 1;
      end

      print '</table><br />'
   end

   --Indexes
   truncate table #Indexes
   if @SqlVersion = '2000'
      begin
      insert into #Indexes  (Name, type, cols)
         select i.name, case when i.indid = 0 then 'Heap' when i.indid = 1 then 'Clustered' else 'Nonclustered' end , c.name
         from sysindexes i
            inner join sysindexkeys k  on k.indid = i.indid  and k.id = i.id
            inner join syscolumns c on c.id = k.id and c.colorder = k.colid
            inner join #Tables t on t.object_id = i.id
         where t.id = @i and i.name not like '_WA%'
         order by i.name, i.keycnt
      end
   else if @SqlVersion = '2008'
      begin
      insert into #Indexes  (Name, type, cols)
         select i.name, case when i.type = 0 then 'Heap' when i.type = 1 then 'Clustered' else 'Nonclustered' end,  col_name(i.object_id, c.column_id)
            from sys.indexes i
               inner join sys.index_columns c on i.index_id = c.index_id and c.object_id = i.object_id
               inner join #Tables t on t.object_id = i.object_id
            where t.id = @i
            order by i.name, c.column_id
      end

   Set @maxj =   @@rowcount
  
   set @j = 1
   set @sr = 1
   if (@maxj >0)
   begin

      print '<table border="0" cellspacing="0" cellpadding="0" width="750px"><tr><td><b>Indexes</b></td></tr></table>'
      print '<table border="0" cellspacing="1" cellpadding="0" width="750px"><tr><th>Sr.</th><th>Name</th><th>Type</th><th>Columns</th></tr>'
      set @Output = ''
      set @last = ''
      set @current = ''
      While(@j <= @maxj)
      begin
         select @current = isnull(name,'') from #Indexes  where id = @j
               
         if @last <> @current  and @last <> ''
            begin  
            print '<tr><td width="20px" align="center">' + Cast((@sr) as varchar) + '</td><td width="150px">' + @last + '</td><td width="150px">' + @typ + '</td><td>' + @Output  + '</td></tr>'
            set @Output  = ''
            set @sr = @sr + 1
            end
        
           
         select @Output = @Output + cols + '<br />' , @typ = type
               from #Indexes  where id = @j
        
         set @last = @current   
         Set @j = @j + 1;
      end
      if @Output <> ''
            begin  
            print '<tr><td width="20px" align="center">' + Cast((@sr) as varchar) + '</td><td width="150px">' + @last + '</td><td width="150px">' + @typ + '</td><td>' + @Output  + '</td></tr>'
            end

      print '</table><br />'
   end

    Set @i = @i + 1;
   Print @Output
end


Print '</body>'
Print '</html>'

drop table #Tables
drop table #Columns
drop table #FK
drop table #Constraint
drop table #Indexes
set nocount off

----------
간단하게 보려면 아래의 쿼리 실행
SELECT TABLE_NAME, ORDINAL_POSITION, COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
ORDER BY TABLE_NAME, ORDINAL_POSITION


'삽질로그' 카테고리의 다른 글

외장 HDD FAT32로 포멧하는 방법  (0) 2010.01.04
TortoiseSVN 초보자 가이드  (0) 2010.01.03
MSSQL 테이블명세 출력용 쿼리  (0) 2009.12.28
원격지원을 위한 SW  (1) 2009.12.16
원격지원 Tool TeamViewer  (0) 2009.12.15
TOAD 한글깨질때  (0) 2009.12.06

PCAnywhere (http://www.symantec.com/region/kr/product/pcanywhere/pca11.0/) 유료
- 리눅스, 맥, 윈도우 지원

Radmin (http://www.radmin.co.kr) 유료
- 상당히 빠른 속도, 윈도우만 지원.

myDesk (http://mydesk.co.kr) 무료
원격제어 프로그램은 아니지만 파일을 공유하는 개념에서 시작되는 프로그램이며, 여러종류의 컴퓨터들안에 있는 (심지어 PDA까지도) 파일들을 공유하고 실행할 수 있다. 한번 써볼만한 프로그램.

UltraVNC (http://ultravnc.com)무료
- 상당히 깔끔하고 좋은 프로그램. 원하는 기능은 플러그인 형태로 제공되기때문에 설치를 하기만 하면 되며 무료

파란 pc원격 접속 (http://pccontrol.paran.com/new/default.jsp)
- 웹기반의 원격제어 홈페이지.

TeamViewer (http://www.teamviewer.com) 무료
- server 에 설치하기위해서는 상용버전을 써야한다
- 설치가필요없는 한글포터블버전

'삽질로그' 카테고리의 다른 글

TortoiseSVN 초보자 가이드  (0) 2010.01.03
MSSQL 테이블명세 출력용 쿼리  (0) 2009.12.28
원격지원을 위한 SW  (1) 2009.12.16
원격지원 Tool TeamViewer  (0) 2009.12.15
TOAD 한글깨질때  (0) 2009.12.06
웹폰트 적용시키기  (0) 2009.11.27
  1. Favicon of http://www.teamviewer.com BlogIcon TeamViewer 2010.07.12 15:28 신고

    안녕하세요.

    저희는 독일에 위치한 원격 제어 소프트웨어을 개발하는 TeamViewer입니다.

    팀뷰어는 윈도우뿐만 아니라 리눅스와 맥킨토시 또한 아이폰에서도 사용가능하며 소프트웨어를 한글어로 제공하고 있습니다.

    저희 홈페이지 www.teamviewer.com 를 통해 다운로드를 받으실 수 있으며 또한 개인 사용자에게는 다운로드가 무료로 제공됩니다.

    문의 사항이 있으시면 support@teamviewer.com 으로 언제든지 연락주시기 바랍니다.

    감사합니다.

    Teamviewer Germany

원격지원 도구
- 네트워크와는 거의 관계없이 지원이 가능한 프로그램을 소개한다.

장점
1. 무료
2. 네트워크 영향을 덜 받는 다.
3. 연결이 쉽다.
4. 가입이 필요없다.
5. 별도의 설치가 없다.
6. 여러 OS 지원 가능

단점
1. 기업용인 경우는 무료가 아니다.

http://www.teamviewer.com/

다운로드한 파일을 실행하면 설치 혹은 실행을 묻는 데 그냥 실행하면 된다.

아래 그림처럼 방화벽이 있는 경우는 방화벽 해제를 하면

아래 그림처럼 준비 상태가 되며

도움을 요청한 사용자는 자신의 ID와 Password를 도와줄 Assistant에게 불러 주면 자동으로 접속된다.

'삽질로그' 카테고리의 다른 글

MSSQL 테이블명세 출력용 쿼리  (0) 2009.12.28
원격지원을 위한 SW  (1) 2009.12.16
원격지원 Tool TeamViewer  (0) 2009.12.15
TOAD 한글깨질때  (0) 2009.12.06
웹폰트 적용시키기  (0) 2009.11.27
회사 svn, trac 설정  (0) 2009.11.25
1. 조회시 한글이 깨질때는 NSL_LANG을 설정해준다.

NLS_LANG = KOREAN_KOREA.KO16MSWIN949




2.엑셀로 데이터를 출력받는데 한글이 깨진다면 toad.ini 파일을 수정하거나 옵션에서 Write wide string 를 체크



8.X의 버전이라면 설치된 디렉토리안의 User Files 디렉토리에서 toad.ini 파일을 찾아 아래의 부분을 추가해준다.

[SAVEAS]
XLSWideStrings=1

'삽질로그' 카테고리의 다른 글

원격지원을 위한 SW  (1) 2009.12.16
원격지원 Tool TeamViewer  (0) 2009.12.15
TOAD 한글깨질때  (0) 2009.12.06
웹폰트 적용시키기  (0) 2009.11.27
회사 svn, trac 설정  (0) 2009.11.25
DOM XML ticker  (0) 2009.11.24
1. 웹폰트 생성프로그램을 아래에서 다운로드 받는다.
http://www.microsoft.com/typography/web/embedding/weft3/download.aspx

2. 웹폰트로 사용할 폰트를 미리 준비한다.
(네이버에서 무료배포하는 나눔고딕을 사용해서 해본다)
http://static.campaign.naver.com/nfs1/file/2008/11/hangeul2715/NanumFontSetup_Win_TTF.exe

3. 웹폰트변환을 위해서 필요한 파일을 준비한다.

이미지 순서대로 적용시킨 후 서버에 업로드하고
CSS를 생성하여 확인해본다.


'삽질로그' 카테고리의 다른 글

원격지원 Tool TeamViewer  (0) 2009.12.15
TOAD 한글깨질때  (0) 2009.12.06
웹폰트 적용시키기  (0) 2009.11.27
회사 svn, trac 설정  (0) 2009.11.25
DOM XML ticker  (0) 2009.11.24
오랜만에 find 쓸일이 생겨서..  (0) 2009.11.23
신규프로젝트를 생성하고 TRAC을 사용할수 있도록 설정하는 방법에 대한 내용이다.

프로젝트를 생성하는 과정은 2가지의 과정으로 진행된다.
우선 버전관리를 위한 SVN Repository 를 생성하고 사용자권한을 설정해 준다.

프로젝트명이 "viralapp" 인 경우

svnadmin create /opt/repo/viralapp

저장소를 생성하였으면, 권한을 조정해준다.(웹서버과 그룹사용자가 접근가능하도록 설정)
cd /opt/repo/
chown apache.abydos viralapp * -R

저장소를 읽고 쓸수 있는 설정을 한다.
vi viralapp/conf/passwd
(커밋권한이있는 사용자를 추가해준다. 모르는경우 타 프로젝트 설정 참고)



여기까지 설정했다면, svn 클라이언트를 이용해서 테스트 해본다.
svn co svn://abydos.kr/viralapp
위의 명령이 정상적으로 진행되면, svn 설정이 완료된 상태이다.

그다음 해야 할 일은 이슈관리를 위하여 TRAC 을 설정하는 일이다.
새로운 프로젝트를 생성한다.

trac-admin /opt/trac/viralapp initenv

위의 명령을 치면 여러가지 설정을 대화식으로 설정가능한 화면이 나타난다.
그 중 svn 부분을 이전에 생성한 위치 /opt/repo/viralapp 로 반드시 지정한다.
(추후 trac에서 소스보기를 이용할수 있도록 하기 위해서 필수로 해야한다)

생성이 완료되었으면, 아래의 파일을 이용해서 설정을 해준다
(잘 모른다면 이전의 프로젝트 설정을 참고)
vi /opt/trac/viralapp/conf/trac.ini

마지막으로 사용자 권한을 조정해 준다.
cd /opt/trac
chown apache.abydos viralapp * -R

서버 사용자 중 관리자로 설정하고 싶은 계정에게 관리자 권한부여
trac-admin /opt/trac/viralapp  permission add hckim TRAC_ADMIN


설정이 완료되었으면 http://abydos.kr/trac/ 으로 접속하여 프로젝트를 사용한다.

'삽질로그' 카테고리의 다른 글

TOAD 한글깨질때  (0) 2009.12.06
웹폰트 적용시키기  (0) 2009.11.27
회사 svn, trac 설정  (0) 2009.11.25
DOM XML ticker  (0) 2009.11.24
오랜만에 find 쓸일이 생겨서..  (0) 2009.11.23
HTML 테이블 CSS  (0) 2009.11.04
xml문서를 자바스크립트로 읽어와서 표현해야 할 경우

읽어올 xml의 내용
<?xml version="1.0"?>
<xmlticker>
<pause>3000</pause>
<message>This is message #1</message>
<message url="http://www.cnn.com">This is a link to CNN.com</message>
<message url="http://yahoo.com" target="_new">This is a link to Yahoo</message>
<message>This is message #3</message>
<message>This is message #4</message>
<message>This is message #5</message>
</xmlticker>

자바스크립트로 읽어오는 부분

<script language="JavaScript1.2">

/*
DOM XML ticker- © Dynamic Drive (www.dynamicdrive.com)
For full source code, 100's more DHTML scripts, and Terms Of Use, visit http://www.dynamicdrive.com
Credit MUST stay intact
*/

//Container for ticker. Modify its STYLE attribute to customize style:
var tickercontainer='<div id="container"style="background-color:#FFFFE1;width:150px;height:120px;font:normal13px Verdana;"></div>'

//Specify path to xml file
var xmlsource="ticker.xml"

////No need to edit beyond here////////////
//load xml file
if (window.ActiveXObject)
var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
else if (document.implementation && document.implementation.createDocument)
var xmlDoc= document.implementation.createDocument("","doc",null);
if (typeof xmlDoc!="undefined"){
document.write(tickercontainer)
xmlDoc.load(xmlsource)
}

//Regular expression used to match any non-whitespace character
var notWhitespace = /\S/

function init_ticker(){
//Cache "messages" element of xml file
tickerobj=xmlDoc.getElementsByTagName("xmlticker")[0]

//REMOVE white spaces in XML file. Intended mainly for NS6/Mozilla
for (i=0;i<tickerobj.childNodes.length;i++){
if ((tickerobj.childNodes[i].nodeType == 3)&&(!notWhitespace.test(tickerobj.childNodes[i].nodeValue))) {
tickerobj.removeChild(tickerobj.childNodes[i])
i--
}
}
document.getElementById("container").innerHTML=tickerobj.childNodes[1].firstChild.nodeValue
msglength=tickerobj.childNodes.length
currentmsg=2
themessage=''
setInterval("rotatemsg()",tickerobj.childNodes[0].firstChild.nodeValue)
}

function rotatemsg(){
var msgsobj=tickerobj.childNodes[currentmsg]
if (msgsobj.getAttribute("url")!=null){
themessage='<a href="'+msgsobj.getAttribute("url")+'"'
if (msgsobj.getAttribute("target")!=null)
themessage+=' target="'+msgsobj.getAttribute("target")+'"'
themessage+='>'
}
themessage+=msgsobj.firstChild.nodeValue
if (msgsobj.getAttribute("url")!=null)
themessage+='</a>'

//Rotate msg and display it in DIV:
document.getElementById("container").innerHTML=themessage
currentmsg=(currentmsg<msglength-1)? currentmsg+1 : 1
themessage=''
}

function fetchxml(){
if (xmlDoc.readyState==4)
init_ticker()
else
setTimeout("fetchxml()",10)
}

if (window.ActiveXObject)
fetchxml()
else if (typeof xmlDoc!="undefined")
xmlDoc.onload=init_ticker

</script>



'삽질로그' 카테고리의 다른 글

웹폰트 적용시키기  (0) 2009.11.27
회사 svn, trac 설정  (0) 2009.11.25
DOM XML ticker  (0) 2009.11.24
오랜만에 find 쓸일이 생겨서..  (0) 2009.11.23
HTML 테이블 CSS  (0) 2009.11.04
UI Component  (0) 2009.10.07

확장자 일괄변경
find . -name *.php -exec rename .sas .mtml {} \;

파일내용 찾기
find . -type f -print | xargs egrep -i "expression"

파일내용 바꾸기
find . -name *.* -exec perl -p -i -e 's/old/new/g' {} \;

일괄삭제
find . -name *.bak -exec rm -rf {} \; 

asdf 라는 문자가 들어간 파일 찾아서 뿌려주기

find ./ -print | xargs grep asdf $1

어떤 문자가 들어간 파일을 찾아서 특정 디렉토리에 이동시키기

# find . -exec grep -l "문자열" {} \; -exec mv {} ./temp_dir \; 


'삽질로그' 카테고리의 다른 글

회사 svn, trac 설정  (0) 2009.11.25
DOM XML ticker  (0) 2009.11.24
오랜만에 find 쓸일이 생겨서..  (0) 2009.11.23
HTML 테이블 CSS  (0) 2009.11.04
UI Component  (0) 2009.10.07
ADOBE FLEX Builder 3 CDKEY  (0) 2009.08.31

+ Recent posts