Contents
주절
2003년 말 부터 쓰기 시작. 어느정도 안정화는 된것 같은데, 몇몇 잡스런 오류가 자주 보인다. 소스 관리에는 지장이 없어보여서 cvs 대신 이걸 쓰기로 했다.
2004년 7월 현재, subversion 에 아주 만족한다. cvs 나 소스세이프 쓰자고 하면 아주 짜증을 낼거다. 누군가 cvs 쓰자고 하면 버전관리툴비교를 보여주자
2005년 7월 현재, 가벼운 프로젝트에는 darcs도 사용중이다. Subversion 과 darcs 의 투톱!!
linux kernel
기존 BitKeeper 를 쓰던 리눅스 커널이, BitKeeper 가 리눅스쪽 라이센스를 변경하면서, 토발즈가 차기 소스 컨트롤 툴로 뭘 쓸지 고민하는 기사 가 있었다. 차기툴로 subversion 이 될가능성은 매우 낮지만, 이는 성능문제가 아니라 리눅스 커널 개발팀이 바라는 모델은 분산된 저장소를 가지는 것인데, subversion 은 cvs 형태의 중앙집중형 저장소를 가지기 때문이다.참고
위 링크를 읽다보면 monotone 이란놈이 나오는데 이것도 언제 한번 봐둬야겠다. 1 GnuArch 는 왠지 정이 안가서...
관련 페이지
Perforce 흠 상용인데.. 좋다는군.
http://winmerge.sourceforge.net/ 윈도에서 쓸만한 diff 프로그램
http://www.araxis.com/merge/ 좋다. 하지만 상용.. vim 의 diff 가 더 깔끔하다.
http://ankhsvn.tigris.org/ VS.NET 의 플러그인
http://www.edgewall.com/products/trac/ cvstrack 같은놈. issue tracker
http://www.uncc.org/svntools/clients/ 몇가지 OS 별로 static 컴파일된 바이너리들을 구할수 있다.
SubversionRevisionInSource 소스내에 revision 을 박는 방법, 즉 --version 때 리비전을 보여주는 방법
http://developer.berlios.de/ 소스포지와 같은 곳인데 subversion 을 지원해준다.
http://better-scm.berlios.de/comparison/comparison.html 버전관리툴 비교
설치와 간단한 사용
http://doc.kldp.org/wiki.php/DocbookSgml/Subversion-HOWTO
윈도에서 subversion 의 설정
subversion 에 딸려오는 메뉴얼에 보면 나와있듯이 레지스트리를 고쳐서 할수도 있고, Documents ans Setting 아래 자신의 Application Data 폴더 의 Subversion 안의 설정들을 고쳐도 된다. editor 를 지정하기 위해서 설치후 한번은 설정을 손봐야 한다.
Property
프라퍼티가 무엇인지는 영문 메뉴얼 참고.(Subversion provides interfaces for adding, modifying, and removing versioned metadata on each of your versioned directories and files. We refer to this metadata as properties, and they can be thought of as two-column tables that map property names to arbitrary values attached to each item in your working copy.)
Manipulating Properties
속성추가하기
$ svn propset copyright '(c) 2003 Red-Bean Software' calc/button.c property `copyright' set on 'calc/button.c' $
속성을 파일로 추가하기
$ svn propset license -F /path/to/LICENSE calc/button.c property `license' set on 'calc/button.c' $
property 수정하기( 지정된 에디터를 이용한다. )
$ svn propedit copyright calc/button.c ### exit the editor without changes No changes to property `copyright' on `calc/button.c' $
다수의 파일에 적용시킬수도 있다.
$ svn propset copyright '(c) 2002 Red-Bean Software' calc/* property `copyright' set on 'calc/Makefile' property `copyright' set on 'calc/button.c' property `copyright' set on 'calc/integer.c' … $
어떤 파일이나 디렉토리의 property 를 보고 싶다면,
$ svn proplist calc/button.c Properties on 'calc/button.c': copyright license $ svn propget copyright calc/button.c (c) 2003 Red-Bean Software
값까지 보고 싶다면, -v(--verbose)
$ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software license : ================================================================ Copyright (c) 2003 Red-Bean Software. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions, and the recipe for Fitz's famous red-beans-and-rice. …
지우려면,
$ svn propset license '' calc/button.c property `license' set on 'calc/button.c' $ svn proplist --verbose calc/button.c Properties on 'calc/button.c': copyright : (c) 2003 Red-Bean Software license : $
Special Properties
property 는 어떠한 이름으로도 만들수 있지만, svn: 으로 시작하는 property 들은 예약되어 있다. 미리 지정된 몇개의 special property 들은 다음과 같다.
svn:executable
파일의 실행 퍼미션 저장한다. 셸 스크립트 같은경우, cvs 를 이용하면 x 퍼미션이 날아가버리는데, 이런 문제를 해결할때 쓰면 된다.
svn:mime-type
파일이 바이너리인지 아닌지 판단, 또 아파치에 물렸을때 mime 값에도 영향 등등
svn:ignore
cvs 에서의 ignore 와 같은것으로, global config 에서도 세팅이 가능하지만 디렉토리 별로도 세팅을 해줄수 있다.
.cvsignore 파일을 그대로 옮겨올수도 있다.
$ svn propset svn:ignore -F .cvsignore . property `svn:ignore' set on '.' $
실제로 내경우, 이놈을 제일 자주 쓰게 되는데,
$ svn propedit svn:ignore .
이런식으로 ignore 할 파일들을 적당히 편집해주는 식으로 쓰게 되더라.
이쪽은 영문 메뉴얼을 더 읽어볼것
svn:keywords
파일내의 키워드를 찾아서 value 로 치환하는 기능을 쓸수 있다. 가능한 키워드는 5개( log 가 없다는게 낭패 )
$LastChangedDate$ 또는 $Date: 2005/01/26 05:31:22 $
$LastChangedRevision$ 또는 $Rev$
$LastChangedBy$ 또는 $Author: root $
$HeadURL$ 또는 $URL$
- $Id$
이런 키워드들이 파일내에 있더라도, 치환을 하라고 지정을 하지 않으면 치환이 되지 않는다.
예를 들어 이런 파일 weather.txt 이 있을때
Here is the latest report from the front lines. $LastChangedDate$ $Rev$ Cumulus clouds are appearing more frequently as summer approaches.
치환을 시켜주려면,
$ svn propset svn:keywords "LastChangedDate Author" weather.txt property `svn:keywords' set on 'weather.txt' $
를 해주면 된다.
내가 주로 쓰는 방법은
svn pe svn:keywords weather.txt
를 실행하고, 에디터가 뜨면 거기에 Id URL 등등을 적어준다.
svn:eol-style
end of line 지정. 영문 메뉴얼 참고
svn:externals
아래쪽의 챕터를 참고
Externals Definitions
어떤 솔루션이 크게 n개의 프로젝트로 구분되어 있어서 n개의 리파지토리를 쓸때, 하나의 프로젝트를 checkout 하면서 다른 프로젝트들도 자동적으로 checkout 을 할수 있게 할수 있다.
예를 들어
$ svn propget svn:externals calc third-party/sounds http://sounds.red-bean.com/repos third-party/skins http://skins.red-bean.com/repositories/skinproj third-party/skins/toolkit http://svn.red-bean.com/repos/skin-maker
이렇게 정의된 경우, calc 를 checkout 하면 외부 프로젝트들도 checkout 된다.
$ svn checkout http://svn.example.com/repos/calc A calc A calc/Makefile A calc/integer.c A calc/button.c Checked out revision 148. Fetching external item into calc/third-party/sounds A calc/third-party/sounds/ding.ogg A calc/third-party/sounds/dong.ogg A calc/third-party/sounds/clang.ogg … A calc/third-party/sounds/bang.ogg A calc/third-party/sounds/twang.ogg Checked out revision 14. Fetching external item into calc/third-party/skins …
Vendor Branches
소스 코드내에 revision 넣기
즉, a.out 이라는 파일의 도움말에 어떤 revision 에서 컴파일되었는지 보여주는 방법. SubversionRevisionInSource 에 정리해 놓았다.
1.1 에서 달라진점
http://subversion.tigris.org/svn_1.1_releasenotes.html
아무래도 얼마간 1.0 을 쓸테니까, 1.1 의 새기능들을 적어둔다. 후에 1.1로 올렸을때 한번 읽어보자. 가장 인상적인것은 fsfs 와 심볼릭 링크 지원.
Non-database repositories |
fsfs 를 지원. 버클리는 자주 깨진다는 말이 있던데, 아직 경험해보지 못했으니 바꿀 생각은 없다. |
Symlink versioning |
svn:special 를 이용해서 심볼릭 링크를 지원한다는데, 유닉스/윈도우 가 약간 다른방식으로 돈다 |
Client follows renames |
|
Commandline auto-escaping of URI and IRIs |
svn checkout "http://host/path with space/project/españa" 이런식으로 쓸수 있게 됐다. |
Localized messages |
버클리 DB 깨지는 경우와 해결 방법
- svn에서 DB가 깨지는 현상은 보통 다음 중 하나입니다.
- 다른 사람이 작업하는 도중에 또 다른 사람이 접근했을 때: 이 경우에는 아마도 svn의 버그로 보여지는데, lock이 완전하지 못해서 거의 여러명이 접근하면 항상 깨집니다. viewcvs를 올려놓고 돌아다니면서 커밋해보면 금방금방 깨지는 것을 알 수 있습니다.
- svn이 죽어버렸을 때: svn이 여전히 버그가 많은지 리비전이 500이 넘으면 log, blame등의 명령에 옵션을 좀 복잡하게 주면 10번에 1번 정도는 랜덤하게 실행하다가 죽어버립니다. 이때 DB를 닫고 죽지 못하기 ㅤㄸㅒㅤ문에 DB가 깨진 걸로 표시가 됩니다. 이 때에는 공동작업할 때 그룹 퍼미션까지도 날아가기 때문에 상당히 골치가 아픕니다.
그래서 저는 복구 스크립트를 만들어서 깨먹은 사람이 복구할 수 있도록 하고 있습니다.
#!/bin/sh if [ ! "$1" ]; then exit 0; fi svnadmin recover $1 if [ "$?" != "0" ]; then echo "============================================================" echo "The other person seems to have broken the repository." BREAKER=`ls -l $1/db | grep -v -- '-rw-rw-r--' | awk '{print $3}'|sort|uniq|xargs echo -n` echo "Please tell [$BREAKER] to recover by himself." exit 0; fi find $1 -type f|xargs -n20 chmod 664 find $1 -type d|xargs -n20 chmod 775 chown -R $USER:devel $1
client 쪽에서 global-ignore 설정하기
cedet 가 만드는 semantic.cache 나, 또는 *.py 에서 나온 *.pyc 등을 매번 ignore 해주는것은 귀찮으니까 클라이언트의 설정중 global-ignore 에 등록해두자. 윈도의 경우, 이 설정을 바꾸는 방법이 몇가지가 있는데(레지스트리,파일수정등) 내가 쓰는 방법은 ~/Application Data/Subversion/config 파일을 수정하는방법.
[miscellany] global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store semantic.cache *.pyc
만약 msvc 작업을 주로 한다면 이놈들도 ignore 해두면 편하다
Debug Release *.ncb *.plg *.opt *.suo *.user
그외 이렇게 쓰는 사람도 있더라 이건 .cvsignore 의 경우이고, http://www.wxwidgets.org/wiki/index.php/Bakefile_Tips 가 출처
* .a * .lib * .pdb * .dll * .exp * .so* * .obj * .o * .log * .manifest* * .pch * .opt * .ncb * .plg * .ncb * .aps * .suo * .user * .il? * .tds * .idb * .map
나는 이걸 쓰는중인데 문제가 생기면 수정하자
global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store semantic.cache *.pyc *.pyo cscope.files cscope.out *.pdb *.exp *.manifest* *.pch *.opt *.ncb *.aps *.suo *.user *.il? GPATH GTAGS GRTAGS GSYMS
config 의 주석을 잘 읽어보자.
소스파일의 EOL(end-of-line) 세팅
sun 과 windows 사이에서 코드교환이 별 문제 없길래 이거 안해놓고 있었는데, FreeBSD 와 windows 간에는 문제가 생기더라.(이건 버전을 타는건지.. 예전엔 별문제 없었는데..)
~/Application Data/Subversion/config 의 다음부분의 주석을 풀어주자.
[miscellany] enable-auto-props = yes [auto-props] *.c = svn:eol-style=native *.cpp = svn:eol-style=native *.cxx = svn:eol-style=native *.cc = svn:eol-style=native *.h = svn:eol-style=native *.hh = svn:eol-style=native *.hpp = svn:eol-style=native *.dsp = svn:eol-style=CRLF *.dsw = svn:eol-style=CRLF *.sh = svn:eol-style=native;svn:executable *.txt = svn:eol-style=native *.png = svn:mime-type=image/png *.jpg = svn:mime-type=image/jpeg Makefile = svn:eol-style=native
auto-props 섹션의 .cxx .cc 등은 내가 추가해넣은것이다. 그외에도 필요한 파일들이 있으면 추가해두자.
만약 global 하게 세팅이 필요 없다면, 아래처럼...
svn propset svn:eol-style native *.cpp *.h
백업
불편한점
Subversion 은 매 프로젝트마다 리파지토리를 만들어야 하는 귀찮은점이 있는데 나홀로쓸 프로젝트에 이걸한다는건 좀 오버다. darcs 도 살펴보도록 하자.
out of date
이거 자주 보여서 짜증나는데 FAQ 의 일부를 적어둔다. 세가지 경우가 있다는데, 내가 경험한것은 모두 두번째 mixed revisions 였고 svn update 한방으로 문제가 해결.
Three kinds of situation that can cause this: 1. Debris from a failed commit is littering your working copy. You may have had a commit that went sour between the time the new revision was added in the server and the time your client performed its post-commit admin tasks (including refreshing your local text-base copy). This might happen for various reasons including (rarely) problems in the database back end or (more commonly) network dropouts at exactly the wrong time. If this happens, it's possible that you have already committed the very changes you are trying now to commit. You can use 'svn log -rHEAD' to see if your supposed-failed commit actually succeeded. If it did, run 'svn revert' to revert your local changes, then run 'svn update' to your own changes back from the server. (Note that only 'svn update' brings your local copies up-to-date; revert doesn't do that.) 2. Mixed revisions. When Subversion commits, the client only bumps the revision numbers of the nodes the commit touches, not all nodes in the working copy. This means that in a single working copy, the files and subdirectories might be at different revisions, depending on when you last committed them. In certain operations (for example, directory property modifications), if the repository has a more recent version of the node, the commit will be rejected, to prevent data loss. See The Limitations of Mixed Revisions in the Version Control with Subversion for details. You can fix the problem by running 'svn update' in the working copy. 3. You might be genuinely out of date — that is, you're trying to commit a change to a file that has been changed by someone else since you last updated your copy of that file. Again, 'svn update' is the way to fix this.
1 잠깐 둘러봤는데 역시 정이 안간다 분산 버전 컨트롤은 내가 쓸일이 없을듯
