← 개발일지

SVN E155015 커밋 실패 — Tree Conflict 원인과 해결법


SVN 커밋이 갑자기 안 된다

커밋을 시도했는데 이런 에러가 뜬다.

svn: E155015: Commit failed (details follow):
svn: E155015: Aborting commit: '/project/src/main/resources/static' remains in conflict

코드를 잘못 친 것도 아니고, 파일을 빼먹은 것도 아닌데 커밋 자체가 차단된다. 원인은 tree conflict다.

Tree Conflict가 뭔가

SVN의 충돌에는 두 종류가 있다.

Text conflict는 같은 파일의 같은 줄을 두 사람이 다르게 수정했을 때 발생한다. 익숙한 <<<<<<< 마커가 나오는 그 충돌이다.

Tree conflict는 이것과 다르다. 파일이나 디렉토리의 존재 자체가 충돌하는 상황이다. 예를 들어 내가 수정하고 있던 디렉토리를 다른 사람이 삭제했거나, 같은 경로에 서로 다른 파일을 추가한 경우에 발생한다.

svn update 과정에서 이런 구조적 충돌이 생기면 SVN은 자동으로 merge하지 못하고 tree conflict 상태로 남겨둔다. 이 상태가 해소되지 않으면 E155015와 함께 커밋이 거부된다.

해결 방법

충돌 상태 확인

svn status

C 표시가 된 항목이 충돌 중인 파일 또는 디렉토리다.

resolve 명령으로 해결

# 내 로컬 상태를 최종으로 채택
svn resolve --accept working -R <충돌경로>

# 서버 버전을 최종으로 채택
svn resolve --accept theirs-full -R <충돌경로>

-R 옵션은 하위까지 재귀적으로 resolve한다. 디렉토리에 tree conflict가 걸리면 그 안의 개별 파일에도 충돌이 연쇄적으로 걸려 있을 수 있으므로 반드시 붙여야 한다.

--accept working을 선택하기 전에 svn diffsvn status로 현재 로컬 상태가 의도한 것과 맞는지 먼저 확인하는 게 안전하다. Tree conflict는 내용을 합치는 게 아니라 어느 쪽 구조를 택할지 결정하는 것이기 때문이다.

커밋

svn commit -m "resolve tree conflict"

IntelliJ에서는?

VCS → Subversion → Resolve Conflicts 메뉴에서 충돌 목록을 확인하고 해결할 수 있다.

다만 IntelliJ의 SVN UI는 tree conflict를 제대로 감지하지 못하는 경우가 있다. 목록이 비어 있거나 resolve 버튼이 동작하지 않는다면, IntelliJ 하단의 Terminal 탭을 열고 위의 svn resolve 명령을 직접 실행하는 게 가장 확실하다.

resolve 후에는 IntelliJ가 변경 상태를 바로 반영하지 못할 수 있으니, VCS → Refresh File Status로 상태를 갱신해 주면 된다.

여러 경로에 동시 충돌이 걸렸을 때

# 전체 충돌 항목 한눈에 확인
svn status | grep "^C"

# 경로별로 다른 전략 적용 가능
svn resolve --accept working -R src/main/resources/static
svn resolve --accept theirs-full -R src/main/webapp/config

전체를 한 번에 처리하고 싶다면 프로젝트 루트에서 svn resolve --accept working -R .을 쓸 수도 있지만, 모든 충돌이 로컬 기준으로 일괄 처리되므로 주의가 필요하다.

핵심 정리

Tree conflict는 텍스트 충돌과 달리 디렉토리 구조 자체의 충돌이다. 자동 merge가 안 되기 때문에 svn resolve로 명시적으로 어느 쪽을 택할지 알려줘야 한다. IntelliJ UI보다 터미널에서 직접 처리하는 게 현실적으로 빠르고 확실하다.