개발도구/기타

[개발도구] GIT 사용자를 위한 SVN

쓴웃음 2021. 12. 13. 21:25

개요

svn을 버전 관리 도구로 사용하는 프로젝트에 참여하게 되어 사용법을 정리해보았습니다. git에 대한 지식이 있으므로 이와 비교해 내용을 정리했으며, 더불어 svn명령어를 시험해 볼 수 있는 환경을 구성하고 결과도 확인해 보았습니다.

본문

명령어

svn에서 사용되는 용어/명령은 git과 차이가 있습니다. 동일한 명령을 사용하여도 결과와 의도가 git 과는 다르기 때문에 이를 미리 알아두어야 합니다.

GIT SVN 비고
git clone svn checkout
git commit -m "message" svn commit -m "message"
git show svn cat
git status svn status
git diff svn diff
git log svn log
git add [file] svn add [file]
git checkout svn switch
git checkout -- [file] svn revert [file] 주1
git reset -- HEAD [flle] svn revert 주1
git branch svn copy 주2
git merge svn merge
git tag svn copy 주2
git pull svn update
git fetch svn update
git push svn commit 주3
gitignore .svnignore

주 1) : SVN에서 Revert는 변경사항을 취소하는 것을 의미합니다. 반면 GIT에서는 반대로 커밋하는 것입니다.
주 2) : SVN의 tag 와 branch는 동일합니다.
주 3) : SVN 에는 local 저장소/ 원격 저장소 개념이 없습니다. 따라서 commit 명령을 사용하면 그 즉시 원격 저장소에 내용이 반영됩니다.

  • revision : 각 Commit을 구별하기 위해 사용하는 숫자입니다. git의 commit ID (commit hash)에 대응됩니다.

도구(client) 설치

※ Windows 10에 Docker Desktop을 설치한 후, WSL2 (Ubuntu 20.04) 환경에서 작업하였습니다.

sudo apt-get install subversion

※ 참고로 이 상태에서 추가 작업을 온프레미스 형태의 svn server 도 구축할 수 있습니다.

서버 설치

※ 아래 나열한 명령의 동작을 시험해보기 위해서 간단히 svn server도 설정해 보도록 합니다.

SVN 컨테이너 실행

참고 : 만약 Docker Desktop 설치 후 동작확인(docker --version)에서 command not found: docker라고 나온다면, Docker Desktop설정의 Resources -> WSL INTEGRATION 으로 이동하여 이용하고자 하는 distros를 활성화합니다. [출처]

# container의 80, 3690 포트를 host의 7443, 6994 포트로 연결
docker run -d --name svn-server -p 7443:80 -p 6994:3690 -w /home/svn elleflorio/svn-server

# 확인, 'No repository found` 라고 표시되면 동작하는 것임
# 잘못된 포트인 경우 Connection Refused 가 표시됨
svn info svn://localhost:6994/
svn: E170013: Unable to connect to a repository at URL 'svn://localhost:6994'
svn: E210005: No repository found in 'svn://localhost:6994'

저장소 만들기

docker exec -it svn-server svnadmin create test-repo

# 생성된 저장소 정보 확인 1
docker exec -it svn-server svnadmin info test-repo
Path: test-repo
UUID: 9daa6e97-b751-463c-8fb7-168595c01cc9
Repository Format: 5
Compatible With Version: 1.9.0
Repository Capability: mergeinfo
Filesystem Type: fsfs
Filesystem Format: 7
FSFS Sharded: yes
FSFS Shard Size: 1000
FSFS Shards Packed: 0/0
FSFS Logical Addressing: yes
Configuration File: test-repo/db/fsfs.conf

# 생성된 저장소 접속 확인 2
svn info svn://localhost:6994/test-repo
Path: test-repo
URL: svn://localhost:6994/test-repo
Relative URL: ^/
Repository Root: svn://localhost:6994/test-repo
Repository UUID: e15f03bc-8a98-4d74-8e96-b8ecad071a78
Revision: 0
Node Kind: directory
Last Changed Rev: 0
Last Changed Date: 2021-12-07 17:45:55 +0900 (Tue, 07 Dec 2021)

사용자 추가

# 컨테이너 shell 실행
docker exec -it svn-server sh
/home/svn # vi test-repo/conf/passwd
### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.

[users]
# harry = harryssecret
# sally = sallyssecret
user = 1234

사용자명 user, 암호 1234로 추가하였습니다.

사용자 그룹 지정 및 저장소 접근 권한 설정

docker exec -it svn-server sh
vi test-repo/conf/authz
[groups]
users = user

... 생략 ...

[/]
@users = rw

저장소 동작 설정

docker exec -it svn-server sh
vi test-repo/conf/svnserve.conf

# 아래의 항목의 주석(#)을 제거, anon-access = none로 변경 (E220001 오류 발생)
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz

SVN 명령 시험하기

체크아웃 (저장소 복제)

cd ~
mkdir workspace
# 서버설정시 정한 사용자명(user)과 암호(1234)
svn checkout --username user svn://localhost:6994/test-repo
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Checked out revision 0.
cd test-repo

수정한 사항 확인하고, Commit 하기

# hello world 작성
vim hello.c

svn status
?    hello.c
svn add hello.c
A    hello.c
svn commit -m "Initial Commit"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Adding         hello.c
Transmitting file data .done
Committing transaction...
Committed revision 1.

변경한 파일이 성공적으로 저장소에 추가되면 revision 번호가 하나 증가합니다. (0 -> 1)

되돌리기

취소하기

revert : 로컬 환경에서 수정한 내용을 되돌리고 싶은 경우 사용합니다.

# 코드를 수정합니다. (hello, world -> Hi, world)
vim hello.c

svn status
M    hello.c
svn revert hello.c
# 코드가 원상태로 돌아갑니다.

※ 원상 복구하려는 단위가 큰 경우, svn revert -R trunk를 사용합니다.

서버 내용 되돌리기

만약, 기존 revision으로 되돌리고 싶은 경우라면 revert rollback merge를 수행합니다.

# 코드를 수정합니다. (hello, world -> Good Morning, world)
vim hello.c
svn commit -m "Morning"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
Committed revision 2.

# 코드를 수정합니다. (hello, world -> Good Afternoon, world)
vim hello.c
svn commit -m "Afternoon"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
Committed revision 3.

# 코드를 수정합니다. (hello, world -> Good Afternoon, world)
vim hello.c
svn commit -m "Evening"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
Committed revision 4.

svn log
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

------------------------------------------------------------------------
r4 | user | 2021-12-07 18:40:51 +0900 (Tue, 07 Dec 2021) | 1 line

Evening
------------------------------------------------------------------------
r3 | user | 2021-12-07 18:40:10 +0900 (Tue, 07 Dec 2021) | 1 line

Afternoon
------------------------------------------------------------------------
r2 | user | 2021-12-07 18:39:23 +0900 (Tue, 07 Dec 2021) | 1 line

Morning
------------------------------------------------------------------------
r1 | user | 2021-12-07 18:28:49 +0900 (Tue, 07 Dec 2021) | 1 line

Initial Commit
------------------------------------------------------------------------

되돌리기

svn update
svn merge -r HEAD:3 hello.c
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

--- Reverse-merging r4 into '.':
U    hello.c
--- Recording mergeinfo for reverse merge of r4 into '.':
 U   .
--- Eliding mergeinfo from '.':
 U
svn commit -m "Rolled back to revision 3 (Afternoon)"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
Committed revision 5.

충돌 해결

여러 사용자가 동일한 파일에 대해 작업할 경우, 충돌이 발생할 수 있습니다.

충돌 발생시키기 (동일한 파일의 동일한 라인을 각각 수정합니다.)

사용자 1의 작업 예시

# hello.c (Afternoon, world -> Hi, world) 변경
vim hello.c

사용자 2의 작업 및 서버에 반영

mkdir ~/workspace2 && cd ~/workspace2
svn checkout --username user svn://localhost:6994/test-repo
cd test-repo
# hello.c (Afternoon, world -> Hello, world) 변경
vim hello.c
svn commit -m "Hello"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
Committed revision 6.

사용자 1의 작업 서버에 반영

cd ~/workspace/test-repo
svn commit -m "Hi"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
svn: E160028: Commit failed (details follow):
svn: E160028: File '/hello.c' is out of date

svn up .
Updating '.':
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

C    hello.c
Updated to revision 7.
Summary of conflicts:
  Text conflicts: 1
Merge conflict discovered in file 'hello.c'.
Select: (p) Postpone, (df) Show diff, (e) Edit file, (m) Merge,
        (s) Show all options: p
Summary of conflicts:
  Text conflicts: 1

각 옵션의 의미

`e` : 병합된 파일을 편집기로 열기
`mc` : (충돌부분)다른 사람의 작업은 버리고, 내 작업 내용을 반영한다.
`tc` : (충돌부분)다른 사람의 작업을 반영하고, 내 작업 내용은 버린다.
`s` : 위 메뉴 외의 선택지를 보여준다.
`mf` :  내가 가진 파일을 반영한다.
`tc` : 서버의 파일을 반영한다.
`p` : 나중에 해결할 것으로 표시

작업 순서

# `p` 를 선택하여 넘깁니다.

vim hello.c
# `<<<<<<<<`, `>>>>>>>>` 등으로 검색하여, 충돌 부분을 확인 후, 수정합니다.

svn status
C       hello.c
?       hello.c.mine
?       hello.c.r6
?       hello.c.r7
Summary of conflicts:
  Text conflicts: 1

# 충돌 해소 표시합니다. (resolve 가 아닌 resolved 임에 주의)
svn resolved hello.c
Resolved conflicted state of 'hello.c'

svn status
M    hello.c

svn commit -m "Resolve Conflict"
svn commit -m "Resolve Conflict"
Authentication realm: <svn://localhost:6994> e15f03bc-8a98-4d74-8e96-b8ecad071a78
Password for 'user': ****

Sending        hello.c
Transmitting file data .done
Committing transaction...
Committed revision 8.

참고