• TIL

[TIL] react native > .gitattributes / project.pbxproj

man_on 2022. 6. 29. 19:07
반응형

 

 

 

     


     

    .gitattributes를 들어가기 전

     

    Why? 왜 .gitattributes?

    • react native 작업 후 PR을 올리려는데 project.pbxproj라는 파일이 포함되어있었고, 많은 변경사항이 있었다. 찾아보니 project.pbxproj는 native 개발 시 자주 충돌이 일어나는 주요 파일 중 하나였고, .gitignore에 추가하려고 생각했지만 gitignore에서 관리할 수 없고, .gitattributes 파일을 따로 만들어서 관리를 해야했다.

     

    근데 project.pbxproj 파일이 뭔데?

    • Xcode에서는 프로젝트를 관리하거나 프로젝트를 빌드하는 용도의 파일 혹은 항목들이 있다. 그 중 실제 프로젝트의 설정을 담은 파일이 project.pbxproj이다.

     

     

     

     


     

     

     

    Xcode의 프로젝트 관리 파일

     

     

    Project

    An Xcode project is a repository for all the files, resources, and information required to build one or more software products

    • Application을 빌드하기 위한 파일, 리소스, 정보를 담은 repository 처음 Xcode를 켜고 project를 생성하면, 디렉토리에 프로젝트명.xcodeproj이라는 파일이 생성된다.
      • project.pbxproj 실제 프로젝트의 설정을 담은 파일 프로젝트 내부에서 생성된 파일들을 파일 유형에 따라 reference를 저장하고있다</aside>
        • xcuserdata 프로젝트의 개인 설정을 담은 디렉토리 breakpoint, UI layout, 스냅샷 설정을 담은 프로젝트 자체에 크게 영향을 주지 않는 디렉토리이다.
      • <aside> 💡 이 project.pbxproj는 git을 사용할 경우 충돌이 일어나는 주요 파일 중 하나이다. 2명의 팀원이 작업을 위해 각자 A 파일, B 파일을 생성하여 각자 커밋한 경우 한 쪽에는 B 파일의 reference, 다른 쪽은 A 파일의 reference가 없습니다. 그래서 두 작업에서 사용된 project.pbxproj 파일은 서로 다른 reference를 가지고 있어서 conflict가 일어납니다. 그리고 이 충돌이 고치기 쉽지 않은 것이 project.pbxproj가 깨지면 프로젝트 자체가 열리지 않습니다. 그러므로 이럴 때는 에디터나 소스트리 같은 형상 관리 툴로 해당 충돌을 수정해야 합니다.

     

     

    Workspace

    여러 개의 Project를 담아 관리할 수 있도록 해주는 개념

    • Workspace는 대부분 CocoaPods을 처음 사용할 때 접할 수 있는데, CocoaPods는 본래의 프로젝트와는 별도로 project를 만들어서 라이브러리 의존성을 관리할 수 있도록 해주는 도구이다.
    • Workspace도 생성하게 되면 Project.xcodeproj와 유사한 디렉토리인 project.xcworkspace가 생성된다. 해당 디렉토리에 들어가보면 contents.xcworkspacedata 파일과 xcuserdata, xcshareddata디렉토리가 있다.
      • contents.xcworkspacedata : 프로젝트들의 referce를 저장하고 있다. workspace에 포함된 프로젝트들의 reference를 저장한 xml 파일이다.
      • (그래서 workspace에 프로젝트를 추가하면 해당 파일에 referece가 추가된다.)
      • xcuserdata : workspace의 개인 설정을 담은 디렉토리
      • xcshareddata : workspace에 공유된 설정을 담은 디렉토리

     

     

     

     

     


     

    .gitattributes 사용

     

     

    • Git Attribute란?
      • 디렉토리와 파일 단위로 다른 설정을 적용할 수 있다. 이렇게 경로별로 설정하는 것을 'Git Attribute'라고 부른다. 이 설정은 .gitattributes라는 파일에 저장하고 아무 디렉토리에나 둘 수 있지만, 보통은 프로젝트 최상위 디렉토리에 둔다. 이 파일을 커밋하고 싶지 않으면 .gitattributes가 아니라 .git/info/attributes로 파일을 만든다.
      • 이 Attribute로 Merge는 어떻게 할지, 텍스트가 아닌 파일은 어떻게 Diff할지, checkin/checkout할 때 어떻게 필터링할지 정해줄 수 있다.
      • 이 Attribute로 어떤 파일이 바이너리 파일인지 Git에게 알려줄 수 있다. 기본적으로 Git은 어떤 파일이 바이너리 파일인지 알지 못한다.
      • 바이너리 파일?컴퓨터 저장과 처리목적을 위해 이진형식으로 인코딩된 데이터를 포함한다.
      • Binary file은 텍스트 파일이 아닌 컴퓨터 파일이다. (non-text file의 의미로도 사용된다.)

     

    • 바이너리 파일이라고 알려주기
      • .pbxproj 파일은 사실 텍스트이지만, 만든 목적과 의도를 보면 바이너리 파일이다. 이 파일은 IDE 설정 들을 디스크에 저장하는 파일로 JSON 포맷이다. 모든것이 텍스트파일이지만 실제로는 간단한 DB이기 때문에 텍스트 파일처럼 취급할 수 없다. 그래서 여려명이 이 파일을 동시에 수정하고 merge할 때 diff가 도움이 안 된다.
      • .gitattribute 파일을 최상단에 생성하고 *.pbxproj binary 를 추가해준다.

     

    • Merge 전략
      • 파일마다 다른 Merge 전략을 사용하도록 설정할 수 있다.
      • ex) Git Attrbute로 이 파일만 항상 타인의 코드 말고 내 코드를 사용하도록 설정할 수 있다. 이 설정은 다양한 환경에서 운영하려고 만든 환경 브랜치를 Merge할 때 좋다. 이때는 환경 설정과 관련된 파일은 Merge하지 않고 무시하는 게 편리하다.
      • 브랜치에 database.xml이라는 데이터베이스 설정파일이 있는데 이 파일은 브랜치마다 다르다. Database 설정 파일은 Merge하면 안된다. Attribute를 아래와 같이 설정하면 이 파일은 그냥 두고 Merge한다.
    database.xml merge=ours
    

    ours merge 전략을 다음과 같이 정의한다.

    $ git config --global merge.ours.driver true
    

    다른 브랜치로 이동해서 merge를 실행했을 때 database.xml파일에 대해 충돌 발생대신 아래와같은 메세지를 볼 수 있다.

    $ git merge topic
    Auto-merging database.xml
    Merge made by recursive.
    

    Merge했지만 database.xml은 원래 가지고 있던 파일 그대로다.

     

     

     

     


     

     

     

    pbxproj 파일관리

     

     

     

    (대부분의 사람들이 추천하는) pbxproj 파일관리

    • gitattributes 파일생성
    .pbxproj binary merge=union
    • Because of the custom format used in this type of file, this is exactly what we want. When a merge conflict arises for this file, git will automatically combine the changes from both sides of the conflict, applying the upstream changes first.

     

     

    다른의견

    Somehow, could be due to legacy reasons, it is popular to treat pbxproj file as binary, and to perform union merge.

    • .pbxproj binary merge=union

    While the property list is not for human to edit manually, it is human readable text. It definitely should not be treated as a binary. Being binary also make Git GUI not showing the diff!If you’re unlucky, you will end up with corrupted project in that 1%.. 🥹It is better to leave gitattributes empty than to set to the not-too-correct way.

    • Stackoverflow discussions here and here.
    • To merge both sides of the changes could also end badly. The author recognised 99% of the time the resolution is merge union. I agree. Most of pbxproj merge conflict is resolved by union of both. But when you specify auto merge in gitattributes, git will not give you the choice.
    • The popular not-too-correct way

     

     

     

     

    반응형