Close

Git 및 프로젝트 종속성

Nicola Paolucci 얼굴 사진
Nicola Paolucci

개발자 애드보케이트

다음 질문을 생각해 보세요. Git으로 프로젝트 종속성을 어떻게 처리합니까? 프로젝트는 여러 개의 상호 종속되는 리포지토리로 구성되어 있습니다. 현재는 svn:externals로 종속성을 관리합니다. Git으로 종속성을 처리하는 가장 좋은 방법은 무엇입니까? Git을 사용하여 매우 큰 규모의 리포지토리를 작은 구성 요소로 분할하는 방법은 무엇입니까? 이러한 질문은 최근 Getting Git Right(Git을 올바르게 사용하기) 투어의 유럽 지역에서 가장 많이 받은 질문의 일부에 해당합니다.

이 주제는 git을 채택하는 많은 소프트웨어 팀에게 큰 골칫거리인 것 같으므로 이 글에서는 그 문제에 대해 설명해 보겠습니다.

분명히 프로젝트 종속성과 빌드 인프라는 서로 얽혀 있는 두 영역이며 심지어 Atlassian 내부에서도 "빌드의 미래"에 대한 논의가 이루어졌습니다.

하나의 리포지토리가 아니라 별도의 리포지토리를 가지면 일이 더 복잡해질 수 있습니다. 하지만 적어도 두 가지 주요 이유, 즉 빌드 시간의 증가와 프로젝트 간 종속성 공유 때문에 소프트웨어 프로젝트의 개발에 있어서 비교적 자연스럽고 때로는 필수적인 단계입니다.

다음 질문을 생각해 보세요. Git으로 프로젝트 종속성을 어떻게 처리합니까? 프로젝트는 여러 개의 상호 종속되는 리포지토리로 구성되어 있습니다. 현재는 svn:externals로 종속성을 관리합니다. Git으로 종속성을 처리하는 가장 좋은 방법은 무엇입니까? Git을 사용하여 매우 큰 규모의 리포지토리를 작은 구성 요소로 분할하는 방법은 무엇입니까? 이러한 질문은 최근 Getting Git Right(Git을 올바르게 사용하기) 투어의 유럽 지역에서 가장 많이 받은 질문의 일부에 해당합니다.

이 주제는 git을 채택하는 많은 소프트웨어 팀에게 큰 골칫거리인 것 같으므로 이 글에서는 그 문제에 대해 설명해 보겠습니다.

분명히 프로젝트 종속성과 빌드 인프라는 서로 얽혀 있는 두 영역이며 심지어 Atlassian 내부에서도 "빌드의 미래"에 대한 논의가 이루어졌습니다.

하나의 리포지토리가 아니라 별도의 리포지토리를 가지면 일이 더 복잡해질 수 있습니다. 하지만 적어도 두 가지 주요 이유, 즉 빌드 시간의 증가와 프로젝트 간 종속성 공유 때문에 소프트웨어 프로젝트의 개발에 있어서 비교적 자연스럽고 때로는 필수적인 단계입니다.


전체적으로 파악하기: 가이드라인 및 최적이 아닌 솔루션


다시 질문으로 돌아가 보겠습니다. git으로 프로젝트 종속성을 어떻게 추적하고 관리합니까?

가능한 경우, 그렇게 하지 않습니다!

농담은 제쳐두고 먼저 주된 답변을 드린 다음 심층적으로 설명하겠습니다. git에는 프로젝트 종속성과 관련된 모든 문제를 쉽게 해결할 수 있는 마법 같은 해결책은 없습니다.

프로젝트가 일정 규모 이상으로 커지면 논리적 구성 요소로 나누는 것이 합리적이지만 하나의 리포지토리에 1억 줄 이상의 코드가 있을 때까지 기다리지 마세요. 따라서 다음은 자신만의 접근 방식을 고안할 수 있는 가이드라인일 뿐입니다.

Git 로고
관련 자료

Git 설치

Bitbucket 로고
솔루션 보기

Bitbucket Cloud에서 Git에 대해 알아보기

첫 번째 선택: Git 대신 적절한 빌드/종속성 도구를 사용


종속성 관리 도구는 커져가는 문제점과 대규모 프로젝트의 빌드 시간을 처리하는 데 제가 현재 권장하는 방법입니다.

모듈을 개별 리포지토리에 분리하여 보관하고 작업에 맞게 구축된 도구를 사용하여 모듈의 상호 의존성을 관리하세요. (거의) 모든 기술 스택마다 알맞은 도구가 하나씩 있습니다. 몇 가지 예는 다음과 같습니다.

  • Java를 사용하는 경우 Maven(또는 Gradle)
  • Node 앱용 Npm
  • JavaScript를 사용하는 경우 Bower, Component.io(업데이트됨!)
  • Python을 사용하는 경우 Pip 및 requirements.txt
  • Ruby를 사용하는 경우 RubyGems,Bundler
  • .NET용 NuGet
  • C++(업데이트됨!)Ivy(또는 사용자 지정 CMake 작업)
  • Cocoa iOS 앱용 CocoaPods
  • PHP(추가됨!)Composer 또는 Phing
  • Go에서는 빌드/종속성 인프라가 언어에 어느 정도 내장되어 있습니다(조금 더 완벽한 솔루션을 개발하기 위한 노력이 이루어짐, godep 참조). Atlassian의 Git 서버 Bitbucket Server의 경우 Maven과 Bower를 모두 사용합니다. 빌드 시 메인 프로젝트를 구축할 수 있도록 선택한 도구가 올바른 버전의 종속성을 풀합니다. 일부 도구에는 한계가 있으며 최적은 아니지만 입증되고 실행 가능한 가정을 합니다.

프로젝트 분할의 어려움

간단히 말해서 프로젝트를 시작할 때는 모든 것이 하나의 빌드에 담겨 있습니다. 하지만 프로젝트가 커질수록 빌드가 너무 느려질 수도 있습니다. 바로 이때 "캐싱"이 필요하며 종속성 관리가 등장합니다. 참고로 이는 하위 모듈(아래 참조)이 예를 들어 동적 언어에 매우 적합함을 의미합니다. 기본적으로 대부분은 어떤 시점에서는 빌드 시간에 대해 걱정해야 할 것이므로 종속성 관리 도구를 사용해야 합니다.

구성 요소를 별도의 리포지토리로 분할하는 데는 상당한 어려움이 따릅니다. 아래 내용에 특별한 순서는 없습니다.

  • 구성 요소를 변경하려면 릴리스가 필요합니다
  • 시간이 걸리고 별별 이유로 실패할 수 있습니다
  • 작은 변경 사항에 대해서는 합리적이지 않아 보입니다
  • 각 구성 요소마다 새 빌드를 수동으로 설정해야 합니다
  • 리포지토리 검색 기능에 방해가 됩니다
  • 단일 리포지토리의 모든 소스를 사용할 수 없을 때 리팩토링합니다
  • (Atlassian과 같은) 일부 설정에서 API를 업데이트하려면 제품의 마일스톤 릴리스가 필요하고 플러그인 및 다시 제품의 마일스톤 릴리스가 필요합니다. 놓친 것도 몇 가지 있겠지만 무슨 말인지 잘 아실 것입니다. 문제를 위한 완벽한 솔루션은 여기와는 거리가 멉니다.

두 번째 선택: git submodule 사용


종속성 도구를 사용할 수 없거나 사용하고 싶지 않다면, git에는 submodules를 처리할 수 있는 기능이 있습니다. 하위 모듈은 특히 동적 언어의 경우 편리할 수 있습니다. 그렇다고 해서 꼭 빌드 시간이 느려지는 것을 막아주지는 않습니다. 이 부분에 대한 가이드라인과 팁을 작성해 두었으며 대안도 살펴봤습니다. 인터넷 전반에서는 하위 모듈에 대한 반대 논쟁도 이루어지고 있습니다.

svn:external 및 git의 1:1 일치

하지만 svn:externalsgit 사이의 1:1 일치를 찾고 있는 경우 submodules릴리스 브랜치만 추적하고 임의의 커밋은 추적하지 않도록 하는 submodules를 사용해야 합니다.

세 번째 선택: 다른 빌드 및 교차 스택 종속성 도구 사용


항상 하나의 도구로 완전히 일관된 프로젝트를 구축하고 구성할 수 있는 것은 아닙니다. 예를 들어, 어떤 모바일 프로젝트는 Java와 C++ 종속성을 모두 다루거나 자산을 생성하기 위해 전용 도구를 사용해야 합니다. 더 복잡한 상황에서는 위에 추가 계층을 만들어 git을 향상할 수 있습니다. 여기서 좋은 예는 Android의 리포지토리입니다.

살펴볼 만한 다른 빌드 도구는 다음과 같습니다.

결론 및 더 읽어볼 자료


Charles O'Farrell은 빌드 인프라(및 Maven) 주제에 대해 생각해볼 수 있는 더 많은 읽기 자료를 제시합니다.

위의 마지막 글에서 나온 훌륭한 인용문으로 이 글을 마무리하고 싶습니다. Maven에 관한 이야기지만 다른 빌드 및 종속성 도구에도 동일하게 적용될 수 있습니다.

"캐시는 속도를 높이는 것 외에는 아무 것도 하지 않습니다. 캐시를 완전히 제거하면 주변 시스템이 똑같이 작동하지만 좀 더 느려질 것입니다. 캐시는 부작용도 없습니다. 과거에 캐시로 무엇을 했든지 상관없이 캐시에 대한 특정 쿼리는 나중에 같은 쿼리에 같은 값을 반환합니다.

Maven 경험은 제가 설명하는 것과 완전히 다릅니다! Maven 리포지토리는 캐시처럼 사용되지만 캐시 속성은 없습니다. Maven 리포지토리에서 무언가를 요청할 때는 과거에 수행한 작업이 매우 중요합니다. 요청은 최근에 입력한 항목을 반환합니다. 입력하기 전에 무언가를 요청하면 실패할 수도 있습니다."

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


이 문서 공유

여러분께 도움을 드릴 자료를 추천합니다.

이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.

도구로 가득한 벽을 사용하여 협업하는 사람들

Bitbucket 블로그

DevOps 일러스트레이션

DevOps 학습 경로

Atlassian 전문가와 함께 하는 Demo Den 기능 데모

Bitbucket Cloud가 Atlassian Open DevOps와 작동하는 방법

DevOps 뉴스레터 신청

Thank you for signing up