TortoiseGIT와 Subversion. Local Commit의 사용!

TortoiseSVN을 이용한 Subversion의 사용은 매우 쾌적합니다. 멋진 UI가 가져다 주는 쾌적함과 Windows Explorer의 Context Menu확장을 통한 통합된 이용은 아주 매력적이죠.

하지만!!!!!!!!

도저히 참을 수 없는 단점이 있습니다. 바로 “Local Commit”의 부재입니다.

Local Commit은 중앙의 저장소에 Commit하는게 아니라, 프로그래머의 개인 저장소에 Commit하는 개인적인 Commit의 개념입니다. 작업량이 많을 경우에는 중간 중간 Commit하는게 필요한데 중앙의 저장소에 Commit했다간 동료들의 불평불만을 한꺼번에 받을 가능성이 있지요. 이런 이유로 Local Commit은 상당히 편리한 기능입니다.

하지만, Subversion에는 Local Commit이 없습니다. OTL. 이를 위해 Mercurial을 사용하기도 해보았지만, TortoiseMercurial의 (TortoiseSVN에 비해) 떨어지는 UI는 사용할 맛이 안날 뿐더러, Subversion과의 연동에도 문제가 많았습니다.

이리저리 찾아본 결과 GIT이라는 훌륭한 시스템이 있었습니다. GIT은 리눅스 커널등의 개발에 사용되는 소스형상관리 시스템인데, 분산된 소스형상관리 시스템의 개념을 사용하고 있으므로, Local Commit이 매우 자연스럽게 적용됩니다. Subversion과의 연동도 훌륭한 편이여서 내심 노리고 있었습니다. 하지만, 사용이 불편하다는 단점이 있었지요. 이런 와중에.. TortiseGIT이 발표되었습니다. 그렇습니다. CVS, SVN에 이어 GIT도 거북이를 등에 업은겁니다!

제가 사용한 방법은 매우 간단합니다. GIT를 일종의 SVN클라이언트로 사용하는거죠. 🙂

  1. git svn clone 명령을 이용해서 작업할 영역을 GIT repository로 복사해옵니다.
  2. 생성된 GIT내에서 작업을 합니다. blah blah TortoiseGIT가 있으니 세상이 아름답습니다.
  3. TortoiseGIT의 SVN rebase명령을 이용해 Subversion측의 변경내역을 가져옵니다.
  4. TortoiseGIT의 SVN dcommit명령을 이용해 GIT측의 변경내역을 Subversion으로 밀어 넣습니다.

스크린샷을 찍어가면서 열심히 쓰고 싶지만, 그건 나중에… git svn clone을 TortoiseGIT에서 하지 않은 이유는 TortoiseGIT이 svn clone을 수행할때 인증절차를 제대로 처리하지 못하는 문제가 있었기때문입니다. 🙁 clone할때 한번 인증 시키면 그 뒤에는 잘 되더군요.

이렇게 하니, 부담없이 작업기록을 로컬의 GIT에 남겨두고 완성한 뒤에 중앙의 SVN에 커밋하는 일이 가능해졌습니다. 🙂

하지만.. 로컬의 GIT에 담겨있던 코드들이 SVN에 넘어갈때 자잘한 커밋로그까지 다 넘어가는 문제가 있더군요. 🙁 GIT에서 branch하고 dcommit하는 부분을 따로 관리하면 이것도 정리해서 가능하지만, 커밋로그라는게 작업했던 당시의 상황을 담는 용도도 있는지라 무시하기로 했습니다. 🙂 Blame을 써보면, 자잘하게 적은 로그이지만, 나중에 유용할때가 있거든요.

나중에 필요하거나 시간이 되면 좀 더 자세히 정리해보도록 하겠습니다. 🙂

boost::array를 배워봅시다.

1. Old. Old. Old style

char buffer[1024];
...(기타 여러 코드들)...
sock.recv(buffer, 1024);

혹시 위와 같은 스타일의 코드를 작성하고 있지는 않으신가요? 물론, 잘 작동하고 문제가 없는 코드일겁니다. 하지만, 여기엔 문제가 하나 있습니다. buffer는 배열이지 객체가 아닙니다. iterator도 없으며, 멤버함수도 없습니다. 불편할 뿐더러 위험합니다. 한번 볼까요?

char buffer[1024];
...(기타 여러 코드들. 복잡해서 눈에 잘 안들어옴)...
sock.recv(buffer, 4096); // 뭔가의 필요에 의해 고쳐졌군요.

와우. 망했습니다. 스택이 깨지면서 어떤 문제가 발생할지 감도 잡기 힘듭니다. 주로 보안사고가 이런 코드에서 많이 발생합니다. buffer overflow죠. 이런 류의 “실수”를 하지 않는다고 보장할 수 있을까요? 네. 이런걸 막기 위해 사람들은 이렇게 작업하기도 합니다.

#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];
...(기타 여러 코드들. 복잡해서 진짜 눈에 잘 안들어옴)...
sock.recv(buffer, BUFFER_SIZE);

별 문제 없어보입니다. 하지만, 버퍼의 크기가 각 위치마다 달라져야 한다면.. 그 수만큼 #define도 늘어날겁니다. enum을 쓰더라도 이건 매한가지죠.

그렇다면, 이런건 어떨까요.

std::vector<char> buffer;
buffer.resize(1024);
sock.recv(&buffer[0], buffer.size());

훌륭하죠. 이제 C++답습니다. 하지만, buffer는 여전히 stack변수이며 이 부분이 실행될때마다 매번 새로 만들어질겁니다. 그리고, 매번 새로 만들어진다는건… 매번 할당자를 호출해야한다는 겁니다. (쉽게말해 new/malloc이 매번 호출됩니다. 재앙이죠.)

이걸 막기 위해선, 그렇죠. buffer를 재사용하면 됩니다. 하지만, 재사용시에는 언제나 멀티쓰레드 환경을 고민해야하는 상황이 다가옵니다. 후.

좀 더 C++다우면서, 배열과 같은 효과를 내는건 불가능할까요?


2. olleh! array!

boost::array<char, 1024> buffer;
sock.recv(&buffer[0], buffer.size());

네. 완벽하게 C++ container스러우면서, 배열의 역할을 수행하는 자료구조입니다. boost::array이죠! 이녀석의 내부구조는 다음과 같습니다.

template<class T, int N>
class array
{
    ...(생략)...
    T elems[N];
};

유일하게 갖고 있는 멤버변수는 elems. 배열입니다! 결국 배열을 선언한 것과 동일한 효과를 갖습니다. 여기까지 왔으면, 파직 하고 뭔가 옵니다.

array는 iterator, const_iterator, size(), begin(), end(), front(), back(), empty()등의 STL컨테이너라면, 다들 갖고 있는 형식과 함수들을 갖추고 있습니다. 그러면서도 []연산자를 지원하여 기존의 배열과 흡사하게 사용할 수 있지요. 이것이 시사하는 바는 생각보다 큽니다.

기존의 배열에 알고리즘을 적용해봅시다.

char buffer[1024];
...(생략)...
char* found = std::find(buffer, buffer+1024, 'c');

위와 같은 알고리즘을 적용할 경우, 1024라는 크기상수가 지속적으로 따라다닙니다. 또한, buffer를 vector나 다른 자료구조로 바꾸기라도 하면, 꽤 많은 수정을 가해야하지요. 하지만, boost::array를 사용한다면 다음과 같이 바뀝니다.

// 편의를 위한 typedef. C++ 프로그래머의 친구죠. :)
typedef boost::array<char, 1024> buffer_type;
buffer_type buffer;
buffer_type::iterator found =
    std::find(buffer.begin(), buffer.end(), 'c');

3. 정리

사실, boost::array(TR1에 들어갔으니 이젠 tr1::array려나요.)는 굉장히 간단하고, 의미없게 느껴질 수 도 있습니다. 하지만, 과거의 배열은 원소들을 담는 컨테이너의 역할을 함에도 불구하고 STL스럽지 않다는 단점이 있었습니다. 자료구조를 다루는데 있어서, STL 컨테이너들과 굉장히 동떨어진 사용법은 코드의 일관성을 해치게 됩니다.

이런 면에서 볼 때, 배열과 동일한 구조/성능을 가지고 있으면서 STL 컨테이너와 유사한 인터페이스를 갖춘 array는 C++내에서 C의 유산에 의해 코드가 망가지는 것을 피할 수 있도록 해주는 상당히 중요한 도구입니다. 🙂 그리고, 200줄이 안되는 이 코드는 좋은 참고자료이기도 합니다. 시간 나시면 꼭 한번 읽어보시길. 🙂


A. References
boost::array의 문서

WordPress+Open ID

myid.net 서비스를 사용하고 있었다. 하지만, 오픈아이디 주소를 myid.net측 주소를 사용하는 건 아니기 때문에 위임(delegate)형태로 활용하고 있었는데, 문제는 블로그 스킨을 바꾸면 설정해놓은 delegate가 날아가버린 다는 점… 난감하지 아니할수가 없다. 간만에 스프링노트를 들어가려 했더니.. 헉;

스킨을 고칠까하다가 플러그인을 검색해보니 OpenID라는 멋진 녀석이 있어서 슥슥 깔았다. 하지만, libcurl이 설치되지 않은 관계로 작동불능. -_-; 이걸 쓰면 myid.net을 거치지 않고도 직접 Open ID를 제공할 수 있으니 여러모로 좋긴 한데… 안되는 걸 어찌하리오. (서버 관리자님께 무려 트윗으로 부탁해놨다 -ㅅ-)

좀 더 찾아보니, Extended Option이란 플러그인을 통해서 각종 메타정보를 집어넣을 수 있고, 이 메타정보에 Open ID도 있다! 만세!

혹시라도, 워드프레스 + 오픈아이디를 쓰고 싶으신 분은 OpenID를 깔거나, 저처럼 Extended Option을 써서 위임방식으로 써보셔요. =3==3

워드프레스 삽질 + 퍼엉-

사용중인 모 서버가 모 사이트에 의해 펑하고 뚫려서.. 블로그가 맛이 갔었더랩니다. -_-b
테마가 날아가서 고생이었는데, 이건 성공적으로 복구를 했고.. 관리페이지로 로그인이 안됩니다. 헉.

..

워드프레스 권한관리체계를 이리저리 따라가면서 디버깅을 하던 와중에..
관리자인 모님이 mysql인코딩을 바꿔주니 되는군요. -_-;;

확인해본결과 role이 capabilities라는 옵션으로 들어가는데 이게 DB에 저장되는데다가, 무려 string으로 저장이 되어있었드랩니다. 결국, 인코딩 문제로 권한 스트링을 분석 못한게 죄… -_-;

결국. 복구는 성공했습니다. 하악.

(주기적인 백업은 필수인듯.. T_T)

워드프레스.. 멋진데?

워드프레스로 바꾼지도 꽤나 오래되었는데.. 2006년 1월로 기억하니.. 3년이 넘었군요.
사실 설치형 블로그를 사용한다는게 상당히 귀찮긴 합니다. 업데이트도 해줘야했고 플러그인도 직접 찾아다가 깔아야했고…

그런데… 워드프레스가 언젠가부터 자동 업데이트부터 플러그인 자동설치까지 지원이 되는군요. 이건 뭐. 데비안/우분투를 쓰는 기분이랄까요. 🙂

설치형을 쓰고 있는건지, 서비스형을 쓰고 있는건지 모르겠습니다. -_-b

ps. 시험삼아 이쪽에서 export해서 wordpress.com에 import시켜봤는데 완벽하게 작동하는군요! 멋진데요. (당연한거지만!)

메모: Sonic Birth

우연히 “재발견”한 소프트웨어 Sonic Birth!!!

이걸 처음 만나게 된 계기는, 밴드 음반 작업하면서 쓸 무료 플러그인을 찾으면서였다. 깔아보고, 몇 번 써먹고는 까먹고 있었는데.. 우연히 다시 열어보고 테스트해본 결과 생각보다 가능성이 무궁무진하다는 사실을 깨닫고 기뻐하는 중.

Sonic Birth AU 디자인 화면

위의 화면을 보고 아- 하실 분들이 계실지 모르겠다. 요는 오디오 시그널 프로세싱에 사용되는 연산들을 미리 준비해두고 이 연산들을 조합해서 “회로”를 짜는거다. 진짜 전기적인 “회로”와는 다르지만, 이 정도면 어지간한 플러그인은 직접 만들 수 있다.

이 소프트웨어를 이렇게 메모에 남겨두는 이유는 흐름에 무게중심을 놓는 개발방식에 대한 예제 중 하나이기 때문이다. 🙂

ps. 첫 데모음반인 homemade#0 믹스를 1곡 남겨두고 있다. (정말 힘들었다..)

UML 클래스 다이어그램에서 아이콘 붙이는 방향에 관한 간단한 팁

이상하게 UML 다이어그램을 작성하다보면 화살표에 붙는 아이콘의 방향이 헷갈리는 경우가 많습니다.

main

너무 정치적인가.. -_-;

매번 헷갈리는 것도 짜증나고 어찌 기억할까 생각을 해보았는데.. 두가지가 나오더군요.

1. 주어법.

Citizen generalizes President and Proletariat.
Citizen owns Power.

주어쪽에 아이콘을 붙입니다.

2. 관계상 상위법.

Citizen은 President와 Proletariat의 상위개념이죠. 상위개념에 아이콘!
Citizen이 Power를 소유하고 있으므로 더 큰거죠. 더 큰거니 아이콘!

ps. 와 오랜만인데 이런 날림이라니!

시간, 포스팅

사람에 따라 다르겠지만, 이 블로그는 포스트하나를 작성하고 “공개하기”버튼을 누르기까지 상당히 많은 시간이 걸립니다. 하나 작성하는데 3 Man-Day(MD)정도 걸리니까요. 집중해서 쓴다면 좀 줄어들긴 하겠지만, 조각조각난 시간테이블에서 긴 집중의 여유는 요원한듯 합니다.

사실, 연애도 끝장났고, 게임도 접은지라 시간이 남을 것만 같았는데, 이건 뭐. 집중이 잘 안되네요. 그 빈자리들을 다른 것들이 채우는… 아마 OOP revisited의 다음 주제는 ‘언어’ 혹은 ‘글쓰기’가 될 예정인데 공부가 모자란지라 좀 더 생각을 해보아야 할 것 같습니다.

너무 meta-development(?) 한 이야기만 하는 것 같아서, 필드로 돌아갈 생각도 있습니다. 몇 년간 손에서 놓고 있던 boost관련 글들도 써야할 것 같고, C++ template meta programming에 대한 내용도 어서 정리해서 다뤄야겠죠. 하악.

어느 것이 되든, 글 하나에 3MD. 그러니까 24시간은 필요한데.. 아주 글을 쓰는 시간을 정해놓고 지켜버릴 생각입니다. 연애-게임을 하던 시절처럼 불쑥 튀어나오진 않을 듯 싶군요. 🙂

– 이렇게 해놓고 밴드 데모음반 작업한다고 잠수탈지도 모르겠습니다. 흐흣. –

쉬운 글.

철학책을 읽다보면 원전과 2차저작의 엄청난 갭을 느끼게 된다. 아무래도, 자신의 생각을 직접 말하는 원전은 그 사람의 생각의 흐름에만 맞추게 되기 때문에 읽는 것이 난해한 경우가 많은 듯 하다. – 물론, 시쳇말로 ‘간지나게’ 써야 좀 쓴거 같은 것도 없지는 않을 듯. –

이런 이유로 고민을 하고 있는데, 철학은 아니지만 OOP: revisited시리즈나 Zero-configuration시리즈 같은 글들은 일종의 ‘원전’이다. 게다가, 아이디어 스케치 수준의 뼈대만 존재하는 글이기 때문에 내용도 빈약하고 여러모로 좀 안타까운 면이 많다. 살붙이기 연습 겸, 독자층 확보를 위해, 좀 쉬운 안내서를 써야하지 않을까 싶다.

‘코드 속을 여행하는 히치하이커를 위한 안내서’ 정도면 괜찮지 않을까 싶은데, 무슨 이야기를 해야할지 모르겠다. 전통적인 방식대로 나열형 소개를 하는게 나을지, 아니면 21일 완성처럼 실제 코드를 작성하는 형태로 가야할지. 그것도 아니라면, 프로그래밍 언어 서적을 읽기 위해 필요한 제반사항을 쌓는 형태로 가야할지. 모르겠다는 거다. 사실 소프트웨어 개발을 시작하려면 기본적인 하드웨어에 대한 이해가 있어야 하는 것도 사실이고, 으아악 막상 쓰려고 보니 어디서 부터 써야할지 모르겠다. 일단 생각나는 가장 유력한 방향은 언어에서 출발하는 것인데, 이건 언어학 공부가 모자란 관계로 좀 공부를 더 해야할 듯.

그래도 시작이 반이라고 이름은 정했으니 다행이려나. 🙂

글들을 정리했습니다.

이 곳에는 IT와 소프트웨어 개발에 관련된 글들만 올릴 생각입니다.
감정적인 글들은 Crow’s Transparent Mind Gallary로,
일상에 관한 것들은 까막의 미투데이로,

올라갑니다.

음악과 관련된 블로그는 만들지 안만들지, 만들면 어디에 만들지 아직 모르겠습니다. 🙂

기존의 글들은 저 혼자 보다가 마음에 든다 싶으면, 현재의 상태에 맞춰서 해당하는 곳으로 올라갈 계획입니다.
– 아마 텀블러블로그인 Crow’s Transparent Mind Gallary가 대부분일겁니다.

🙂

ps. 이름도 바꿨습니다.