OS X, Case Sensitive 볼륨을 Case Insensitive 볼륨으로 변경하기

최근 들어온 정보에 따르면 El Capitan 에서는 HFS+ 의 Case Sensitive 볼륨을 만들 수 없게 되었다고 합니다. 자세한 사항은 정식버전 출시 후 업데이트 하겠습니다.

OS X 디스크 볼륨은 파일의 대소문자를 구분하지 않는(Case Insensitive) 것이 기본값이다.

하지만 주 업무가 리눅스 서버에 설치되는 프로그램들을 만들다보니 가끔 파일 이름에서의 실수가 발생하는 경우가 있었다. 예를들어 파일이름은 foo.json 인데 프로그램에선 Foo.json 을 로드한다던지 하는 문제가 발생했다. 이런 문제는 서버에 설치되기 전까지는 알아챌 수 없는 문제이다. 그래서 Yosemite 을 설치하면서 대소문자를 구분하는 포맷으로 사용하기 시작했다.

헌데 OS X에서는 Case Sensitive 를 사용하면 각종 애로사항이 발생한다. 구글에서 검색해보면 절규가 들려온다. 특히 어도비 제품들은 최신판인 CC 에서도 주 볼륨이 Case Sensitive 로 포맷되어 있으면 인스톨러가 실행조차 되지 않는다.

추정하기로는 OS X 기반 개발자들이 파일의 대소문자를 민감하게 따지지 않아 애플리케이션에 잠재적인 오류 가능성이 있어 설치를 막는 것으로 보인다. 내 경우에도 포토샵 등은 CS6 에서의 Workaround 를 찾아 어찌어찌 해결했지만 Adobe Extension Manager 가 동작하지 않아 플러그인들을 설치할 수 없었다. 참고:CS6 에서의 Workaround

그런데 Adobe Extension Manager 를 사용해야만 하는 이슈가 발생해서 Case Insensitive 로 변경해야만 했다.

검색해보니 iPartition 이라는 앱이 이런 일을 편하게 해준다고 하는데, 가격이 너무 비싸 수동으로 작업했다. 이 작업으로 컴퓨터를 사용하지 못하는 상황은 원하지 않아 2일에 걸쳐 작업했다.

백업은 Carbon Copy Cloner 라는 앱을 트라이얼 상태로 사용했다. 이 앱은 Rsync 를 사용해 하드디스크를 증분 백업해준다. 그래서 첫번째 백업 이후에는 굉장이 빠르다. 자기 전에 하루 저녁동안 백업해두고, 그 다음날 저녁에는 한번 더 백업한 다음 디스크 유틸리티로 복사해놓고 잠들었다. 다음날 아침에 보니 정상적으로 동작하는 것을 확인할 수 있었다.

(350GB 정도 사용한 500GB SSD 와 USB 2.0 외장 500GB HDD 을 사용함.) * Day 1: Carbon Copy Cloner 로 백업 (4시간 소요된 것으로 추정) * Day 2: Carbon Copy Cloner 로 증분 백업 (30분 소요), Yosemite 설치 디스크로 Disk Utilities 실행, 백업한 것을 리스토어 (6시간 소요된 것으로 추정)

Case Insensitive 볼륨에서 Case Sensitive 사용하기

공교롭게도 위 과정을 거친 바로 다음날 Case Sensitive 관련 문제가 발생했다. git 에서 어떤 파일을 수정한 일이 없는데 계속 수정된 상태로 나오는 것이다.

리모트 리파지토리를 살펴보니 동일한 이름에 대소문자만 다른 두 파일이 있었다. 예를들어 foo.csv 와 Foo.csv 파일 두개가 동시에 존재하는데 대소문자를 따지지 않는 파일시스템을 사용하니 문제가 생긴 것이다.

이 문제는 OS X 의 기본기능인 디스크 이미지를 만들어 해결했다. 디스크 이미지는 겉으로 보기에는 파일 형태이지만 실행(마운트)하면 별도의 디스크 처럼 동작하는 기능이다.

볼륨과 별도로 Sparse Bundle 을 Case Sensitive 로 포맷해 이 쪽에서 내용을 살펴보았더니 파일이 두 개 존재하는 것이 보였다.

Screen Shot 2015-06-01 at 9.20.05 PM

그래서 내용을 잘 처리하고 하나의 파일로 다시 만들어 해결했다.

대소문자를 구분하는 디스크 이미지를 만드는 방법

Disk Utility 에서 새로운 이미지를 만들도록 선택하고 이 이미지의 포맷을 Case-sensitive 계열로 선택해 만들면 된다. 생성된 파일을 실행(더블클릭) 하면 디스크로 동작한다.

15DCF2DB-C1B4-403B-B8CB-FFEDACCD0CD5

skitch

Git Merging 과 Rebase 의 상황별 사용법

Git 을 사용하기 시작한지가 벌써 3년이다. 한번은 문상환님하고 Git 의 Merge branch 커밋에 대해 이야기를 한 적이 있다. 대화가 진행될 수록 Rebase 와 Merge 를 머리로만 알고 있을 뿐, 제대로 이해하지 못하단 걸 알게됐다. 일종의 산파법이랄까.

Git 에서 코드를 합치는 방법에 대해 탕수육의 뿌먹파와 찍먹파처럼 Rebase 파와 Merging 파가 있다. 나는 Merging 파였다. Rebase 에 대해서 알고는 있지만 그저 “충돌나면 머리아프니 안써” 라며 배제 했었는데 좋은 글을 찾아 요약하게 되었다.

개인적으로 중요한 내용인, 각각의 장단점과 활용방법에 대해서만 요약했다. 원문은 소스트리 블로그 에서 볼 수 있다.

각 기능의 장단점

Merging 장점

  • 이해하기 쉬움
  • 원래 브랜치의 컨텍스트를 유지함.
  • Fast-Forward Merge 를 하지 않는다면 브랜치 별로 커밋을 분리해 유지. 특히 이런 분리는 기능 브랜치에 유용.
  • 원래 브랜치의 커밋들은 변경되지 않고 계속 유지되어 다른 개발자들의 작업과 공유되는 것에 대해 신경쓸 필요가 없음.

Merging 단점

  • 단순히 모든 사람들이 같은 브랜치에서 작업하기 때문에 머지해야할 때는 merge 가 커밋 히스토리상으로 전혀 유용하지 않고 어지럽기만 하다.

Rebase 장점

  • 단순한 히스토리
  • 여러 개발자들이 같은 브랜치를 공유할 때 커밋을 합치는 가장 직관적이고 깔끔한 방법.

Rebase 단점

  • 충돌상황에서 다소 복잡. 커밋 순서대로 Rebase 를 하는데, 각 커밋마다 충돌해소를 순서대로 해주어야 한다. SourceTree 가 가이드하기는 하지만, 역시 복잡한 것은 사실이다.
  • 해당 커밋들을 다른 곳에 푸시한 적이 있다면 히스토리를 다시쓰는 것에 부작용이 발생한다. Mercurial 에서는 간단히 푸시를 할 수 없다. Git 에서는 Push 할 수 있으나 당신 혼자 쓰는 리모트 브랜치에만 가능하다. 만약 다른 사람이 그 브랜치를 체크아웃 받은 후 당신이 리베이스 한다면 꽤 혼란스럽게 될 것이다.

결론

Rebase 와 Merging 모두 나름의 가치가 있는 것으로, 논란의 대상이 아니고 상황에 따라 사용해야할 것이 다른것이다.

  1. 여러 개발자들이 같은 브랜치를 공유할 때는 Pull & Rebase 가 히스토리를 깔끔하게 유지하는데 좋음.
  2. 완료된 기능 브랜치를 다시 합칠 때는 머지를 사용.
  3. 기능 브랜치에 부모 브랜치의 변경 내용을 반영하고 싶을 때는
    1. 아래 상황에서는 리베이스가 낫다.
      • 이 브랜치를 다른 곳에 푸시한 적 없는 경우.
      • (Mercurial 이 아닌) Git을 사용하고 다른 사람이 이 기능브랜치를 체크아웃할 일이 없을 것이라 확신하는 경우.
    2. 이 외의 상황에는 머지가 낫다.

따라서 KStyleTrip 는 Git 그라운드 룰을 다음처럼 정하기로 했다.

  • Remote 와 Local 에 동시에 존재하는 브랜치를 Pull 할 때에는 Rebase 를 사용하도록 한다.
  • 기능 브랜치에 대해서는 Merge 를 사용, Rebase 와 비슷한 동작을 하게되는 Fast-Forward Merge 를 사용하지 않는다.
  • 기능 브랜치에 그 부모 브랜치의 내용을 합칠 때는 로컬 브랜치일 때만 Rebase 로 합침.

p.s. Github 클라이언트는 Pull 시 자동으로 Rebase 한다, Sourcetree 도 해당 기능을 설정할 수 있다. 설정법은 원문 참조.