LHJ

I'm a FE developer.

필요한 Git 워크 플로 - 단일 저장소에서 여러 팀을 처리하는 방법

01 Nov 2020 » git

필요한 Git 워크 플로 - 단일 저장소에서 여러 팀을 처리하는 방법

이전에 경험해 본 적이 있다면 중지하십시오.
당신은 대규모 개발자 팀의 일원이거나 현재 대규모 개발자 팀을 관리하고 있습니다.
팀이 백엔드 개발자로 구성되어 있기 때문에 모두 동일한 기술 스택을 사용하여 작업하지 않습니다.
JAVA에서는 AngularJS에서 작업하는 프런트 엔드 개발자와 Python으로 작업하는 데이터 과학자 두 명도 있습니다.

게다가 모두가 GIT 사용법을 안다고 말했지만 실제로는 그렇지 않습니다.
일반적으로 선택한 IDE를 사용하여 버전 제어를 처리하고 정확히 무엇을하는지 모르고 옵션을 클릭합니다.

일반적으로 이유는 이러한 팀이 소스 코드를 개별적으로 처리하도록 지정합니다.
즉, 각 코드베이스에 대해 서로 다른 리포지토리를 사용한다는 의미입니다.
그것은 또한 그들에게 서로 독립적인 개별 개발 흐름을 가질 수있는 능력을 제공 할 것입니다.

즉, 종종 운이 당신 편이 아니고, 하나의 저장소와 세 개의 다른 팀이 함께 작업하는 방법을 배우려고합니다.
이 특정 기사에서는 소스 제어 관점에서만이 시나리오를 다루겠습니다.
즉, 모두가 서로의 코드를 엉망으로 만들지 않고 함께 작업 할 수있는 유용한 개발 흐름을 만드는 방법입니다.

단순히 성공적인 Git 분기 모델(branching model)을 사용하지 않는 이유는 무엇입니까?

2010 년 Vincent Driessen은 개발 팀에서 GIT를 사용하여 버전 제어를 처리하는 방법을 설명하는 매우 흥미로운 기사를 게시했습니다.

기본적으로 이 기사에서 제안한 내용 (모든 세부 사항을 원하면 기사로 직접 이동)은 다음과 같습니다.

  • 작업해야하는 각 기능에 대해 하나의 브랜치를 만듭니다.
    이러한 브랜치는 모든 개발 코드가있는 기본 개발 브랜치에서 제공됩니다.
  • 각 개발자는 준비가 될 때까지 각 기능 브랜치에서 작업합니다.
  • 준비되면 소스로 다시 병합됩니다.
  • 모든 기능이 준비되면 개발에서 릴리스 브랜치를 생성합니다.
    여기서 반 완성 기능이 배포되지 않도록 버그 수정 만 허용됩니다.

이것이 흐름입니다.
간단히 말해서 태그 지정 및 핫픽스와 관련하여 몇 가지 다른 고려 사항이 있지만 이에 대한 원본 기사를 읽어 보도록하겠습니다.

그래서 다른 많은 사람들과 마찬가지로, 저는 그 접근 방식을 마음에 새겼고, 동일한 코드에서 하나의 팀으로 작업 할 때 동질적인 팀과 매우 잘 작동합니다.

더 이상 현실이 아닐 때 문제가 발생합니다.

오해하지 마세요. 팀이 도구에 능숙하다면 모델은 여전히 작동합니다.
리포지토리에서 pullfetch의 의미 또는 merge conflict를 올바르게 처리하는 방법을 알고 있다면 반드시이 모델을 사용하세요.

안타깝게도 항상 그렇지는 않습니다.
너무 많은 개발자가 GIT를 사용해야 할 때 문서를 훑어 보는 경향이 있습니다.
이로 인해 팀이 충분히 작을 때 사소한 문제가 발생하거나 모든 병합 작업을 수행 할 팀원을 선택해야합니다.

당신도 거기에 있었을 수도 있고, 당신의 팀에 도구를 아주 잘 알고 있고 그들이 그것을 사용할 때 어떤 일이 일어나는지 이해하는 몇몇 개발자가있어서 그들은 가장 복잡한 작업을 처리하는 경향이 있습니다.

예를 들어, 스프린트를 시작할 때 기능 브랜치를 생성 한 다음 다른 개발자가 코드가 준비되었다고 판단하면 병합을 처리하도록 이러한 개발자가있을 수 있습니다.

이는 경우에 따라 작동하는 설정일 수 있지만 의심 할 여지없이 특정 개인에게 많은 책임이 추가되고 개발에서 확실히 시간이 걸립니다.

그렇다면 git 흐름을 조정하지 않으면 발생할 수있는 최악의 상황은 무엇일까요?

피해야 할 일반적인 문제

이 접근 방식을 생각해 낸 몇 가지 사례를 공유해 보겠습니다.

Chaining branches (브랜치 연결)

흐름은 모든 새로운 브랜치가 메인 개발 브랜치에서 나와야한다고 지시합니다.
이것은 다른 반 완성 브랜치에서 불완전한 코드를 가져 오는 것을 방지하기위한 것입니다.
여기서 문제는 브랜치를 만들고 다른 브랜치를 사용할 때주의를 기울이지 않는 개발자, 실수로 이전 브랜치를 소스로 사용할 수 있다는 것입니다.

이제 그들은 전체 코드를 개발에 병합하려고 시도하고 있으며 당연히 많은 병합 충돌을 겪고 있습니다.
개발자가 자신의 작업이 최신 버전이므로 문제를 해결하기 위해 코드 버전을 수락하면 더욱 악화됩니다.

이 모든 것을 말하고 완료하면 코드를 업로드했지만 그 과정에서 다른 팀 코드의 최신 버전을 완성되지 않은 이전 버전으로 덮어 썼습니다.

매우 간단한 다이어그램을 사용하여 살펴 보겠습니다.

결국 F2 지점에서 병합 된 코드에는 F1에서 완성되지 않은 코드가 있습니다.
그리고 모든 팀이 동일한 저장소를 공유하기 때문에 F1은 프런트 엔드 특정 브랜치 일 수 있고 F2는 백엔드 팀 용일 수 있습니다.
백엔드의 누군가가 프론트 엔드의 코드를 엉망으로 만드는 데서 오는 혼란을 상상할 수 있습니까?
예쁘지 않다고 말할 수 있습니다.

Premature merges (조기 병합)

이전 문제와 유사하게, 미완성 기능 브랜치를 개발에 병합하여 작동 방식을 확인하거나 (더 나쁜 경우) 충돌이 없는지 확인하기 위해 본질적으로 미완성 코드로 메인 브랜치를 중독시키는 것입니다. .

다음 개발자가 기본 브랜치에서 새로운 브랜치를 생성하여 (예상대로) 코드를 전달합니다.
그리고 그들이 그것을 다시 병합하기로 결정할 때, 당신이 이미 코드를 완성하고 그것들을 병합했다고 가정하면, 그들은 당신의 코드가 아니라 당신의 코드에 대한 병합 충돌을 해결해야 할 것입니다! #WTF

이 정확한 경우를 보여주는 다음 흐름도를 확인하십시오.

결국 결과는 이전과 같고, 자신도 모르게 다른 사람의 작업에 영향을 미치고 있습니다.
실제로 이러한 문제는 프로덕션에 도달 할 때까지 보이지 않을 수 있으므로 코드를 처리하는 방법에 특히주의해야합니다.

동료의 코드를 망칠 수있는 다른 방법이 있지만,이 두 가지 예와 어느 정도 관련이 있습니다.
지금 쯤 추측 하겠지만 실제 문제는 흐름 자체가 아니라 팀과 관련된 것입니다.

이것에 대한 궁극적인 수정은 관련된 개발자를 교육하여 그들이 같은 실수를 계속하지 않도록하는 것입니다.
그러나 만약 당신이 할 수 없거나 그들이 당신이 가진 다른 옵션을 배우지 못하거나 (결국, 실수하는 것은 인간입니다) 피해를 최소화 할 수있는 방식으로 흐름을 조정하는 것입니다.

A new flow

이 흐름을 통해 달성하고자하는 것은 실수로 인해 발생할 수있는 효과 영역을 좁히는 것입니다.
코드를 매우 분리 된 브랜치로 분류하여 누군가가 무언가를 잊었거나 단순히 규칙에 따라 플레이하고 싶지 않은 경우 나머지 팀이 아닌 직계 팀원에게만 영향을 미칩니다.

문제는 피할 수 없습니다.
여기서 핵심은 문제를 다른 팀으로 퍼 뜨리지 않는 것입니다.
왜냐하면 문제를 해결하는 것은 프로젝트 전체의 작업이되며, 프론트 엔드 또는 백엔드 문제라면 해당 팀이 처리 할 수 있기 때문입니다. 그들 자신의.

이제 이 흐름이 두 팀 구성을 찾는 방법을 살펴 보겠습니다 (프로젝트 내 하위 팀 수에 관계없이 쉽게 추정 할 수 있음).

많은 대사입니다. 알아요.하지만 잠시만 참아주세요.

이 흐름은 두 팀(T1 및 T2)이 스프린트의 시간 내에 두 가지 다른 기능 (F1 및 F2)에서 어떻게 작동하는지 보여줍니다.

모든 것이 명확하므로 세부 정보는 다음과 같습니다.

  • 점선 화살표는 자동으로 발생하는 병합입니다.
  • T1Dev 및 T2Dev는 각 팀의 개별 개발 브랜치입니다.
    그 안에있는 코드가 혼합되어서는 안됩니다.
    그게 요점입니다.
    이것은 프런트 엔드 코드와 데이터 과학 코드를 혼합하는 것과 같습니다.
  • T1Stable 및 T2Stable은 해당 T1Dev 및 T2Dev의 복사본이지만 안정적인 코드 만 포함합니다.
    이러한 분기로의 병합은 해당 기능이 닫혀있을 때만 발생하기 때문에 보장됩니다 (QA 팀이 이를 승인했음을 의미).
  • 각 스프린트가 시작될 때 해당 안정적인 브랜치에서 각 팀에 대한 태그가 생성됩니다.
  • 현재 스프린트의 태그에서 새로운 기능 브랜치가 생성됩니다.
  • 기본 개발 브랜치에 병합되는 모든 항목이 개발자에 의해 테스트되고 예상대로 작동하는 경우 병합 명령이 실행되므로 코드가 QA 브랜치에 병합되고 이후 해당 팀이 테스트 할 수 있도록 해당 환경에 배포됩니다.
  • 스프린트가 끝나면 안정적인 코드가 프로덕션에 배포됩니다 (PROD 브랜치에 병합하여).

많은 것 같고 처리하기에 너무 많아 보일 수 있지만 많은 재난을 예방하는 데 도움이됩니다.

설명하겠습니다.

태그는 스프린트 내에서 생성 된 모든 브랜치가 동일한 오리진 코드를 포함하는지 확인합니다.
이것은 매우 중요합니다.
그렇지 않은 경우 잠재적으로 1 주일 동안 부분 테스트의 내용으로 스프린트에 새 브랜치를 생성 할 수 있습니다.
다른 팀원이 팀의 개발 브랜치에 병합되었을 수 있습니다.
이것은 기본적으로 당신의 코드를 병합하는 동안 다른 사람의 완성되지 않은 코드를 마지 못해 홍보하는 것을 방지합니다.

안정적인 브랜치는 코드를 프로덕션으로 승격하는 과정 (또는 그 이전 단계 인 UAT)에 도움이됩니다.
이상적인 세상에서는 QA 지점을 다음 환경으로 홍보하는 것뿐입니다.
그러나 실제로는 미완성 된 기능이나 버그가있는 기능으로 인해 항상 이월 될 수 있습니다.
어떤 경우이든 이러한 코드는 QA를 끝내고 프로덕션으로 전환하기에 충분하지 않으므로 다음 배포를 설정할 때 브랜치를 직접 선택해야하며 승인 된 브랜치 만 선택해야합니다.
이렇게하면 이미 사전 승인 된 각 팀에 대한 분기가 이미 있으므로 이러한 분기를 프로덕션에 병합하기 만하면 준비가 완료됩니다.

개별 개발 분기 (위 예의 T1Dev 및 T2Dev)는 코드를 분리하는 데 도움이됩니다.
이 브랜치에 코드를 병합하는 것은 개발자가 직접 수행해야하며이 문서의 시작 부분에서 논의했듯이 올바르게 수행 할 수있는 능력을 항상 신뢰할 수는 없습니다.

개별 개발 지점을 보유함으로써 실수를하면 전체 프로젝트가 아닌 팀에만 영향을 미치게됩니다.

기능의 크기에 따라 기능 브랜치에서 여러 개의 개별 브랜치를 생성해야 할 수 있습니다.
로컬 개발 워크 플로를 구성 할 수 있지만 적절하다고 생각되면 한 가지만 기억하십시오.
기능 브랜치에서 가져 와서 이동해야하는 모든 작업입니다.

흐름 외부의 몇 가지 추가 권장 사항

흐름 자체가 팀이나 팀원이 의도하지 않은 실수를 저지를 수있는 범위를 제한하는 데 도움이되지만 이와 함께 진행되고 더 많이 예방할 수있는 다른 권장 사항이 있습니다.

흐름 문서화

개발 흐름, 특히 복잡한 흐름을 문서화해야합니다.
모든 사람은 언제 어떤 일이 일어나야하는지 정확히 이해할 수 있어야하며 더 중요한 것은 어떻게해야하는지에 대한 것입니다.

즉, 개발자를 직접 이끌 수있는 안전한 문서를 작성하는 것을 두려워하지 마십시오.
많이 들릴지 모르지만 한 번 작성하면 특히 프로젝트를 시작할 때 그리고 나중에 모든 새로운 개발자가 참여할 때 자주 사용하게됩니다.

단계별 설명이 있으면 끌어 오기 또는 병합을 수행하는 방법을 추측하지 않고 해당 작업을 처리하는 표준화 된 방법을 제공하므로 의심이가는 경우 누구든지 대답 할 수 있습니다.

흐름에 대해 토론

또 다른 형태의 문서는 가능한 경우 직접 대면 Q & A를하는 것입니다.
또는 적어도 행 아웃이나 다른 모든 유형의 회원 라이브 모임을 통해 모든 사람이 의심을 표할 수 있습니다.

때로는 그러한 의심이 계획의 결함을 강조하므로 반대로 변경 사항에 대해 개방적입니다.

그들이 당신의 리드를 따르도록 열려 있어야하는 것처럼 (당신이 흐름을 만드는 사람이라면) 당신은 당신이 간과하거나 놓친 개선점에 대해 열려 있어야합니다.
이러한 일이 발생할 수 있음을 인식하고 모든 사람에게 공개하기 전에 GIT에 더 정통한 팀 구성원과 함께 계획을 검토하십시오.
그들이 괜찮다면 아주 좋은 기회가 있고 다른 사람들도 그렇게 될 것입니다.

일부 표준을 시행하는 것을 두려워하지 마십시오.

다시 말하지만 때때로 문제는 행동의 자유에서 비롯됩니다.
GIT로 작업하는 개발자가 작동 방식을 제대로 이해하지 못하지만 외부 도구를 사용하여 이를 보완하려고하면 도구가 없었을 때보 다 더 많은 문제가 발생할 수 있습니다.

따라서 이를 방지하기 위해 사용해야하는 GIT 클라이언트, 작업해야하는 환경, 폴더 구조 또는 소스 제어 처리와 관련하여 작업을 단순화 할 수 있다고 생각하는 모든 것을 자유롭게 적용 할 수 있습니다.
이 주제에 대해 더 많이 알고 싶은 경우 구현으로 얻을 수있는 표준 유형에 대한 기사).

여기에서해야 할 일 중 하나는 GIT와 함께 제공되는 CLI 클라이언트의 사용을 적용한 다음 입력해야하는 모든 명령을 단계별 문서에 나열하는 것입니다.
이런 식으로 작업은 누구나 쉽게 이해할 수 있습니다 (개발자가 GIT 줄이 아닌 코드 줄에 대해 걱정하게하는 이상적인 시나리오).

마지막 단어

여기까지 읽어 주셔서 감사합니다. 다음을 기억하세요.

  • 모든 사람이 GIT에 대해 충분히 알고있는 것은 아닙니다.
  • 모두가 그것을 인정하지는 않을 것입니다
  • 표준 git 흐름이 항상 팀에 적합한 선택은 아닙니다.
    문제가 발생할 때 부수적 인 피해를 최소화하는 흐름을 목표로해야합니다.
  • 또한 GIT 사용에 대해 팀을 교육하는 것을 목표로해야합니다.
    처음에는 그렇게 보이지 않을 수도 있지만 잘못 수행 된 병합으로 인해 배송 날짜가 누락되는 것을 방지 할 수있는 투자입니다.
  • 마지막으로, 프로세스에 대한 문서를 가능한 한 많이 제공하고, 지속적으로 증가하고 변화하는 라이브 문서임을 공개하십시오.

읽어 주셔서 다시 한 번 감사 드리며 원하신다면 GIT를 잘못 사용하여 과거에 어떤 문제를 겪었는지 비슷한 이야기를 남겨 주시거나이를 피하기 위해 사용한 다른 흐름을 남겨주세요!

LogRocket : 웹 앱에 대한 완전한 가시성

logRocket

LogRocket은 마치 자신의 브라우저에서 발생한 것처럼 문제를 재생할 수있는 프런트 엔드 애플리케이션 모니터링 솔루션입니다.
오류가 발생한 이유를 추측하거나 사용자에게 스크린 샷 및 로그 덤프를 요청하는 대신 LogRocket을 사용하면 세션을 재생하여 무엇이 잘못되었는지 빠르게 이해할 수 있습니다.
프레임 워크에 관계없이 모든 앱에서 완벽하게 작동하며 Redux, Vuex 및 @ ngrx / store에서 추가 컨텍스트를 기록하는 플러그인이 있습니다.

Redux 작업 및 상태 로깅 외에도 LogRocket은 콘솔 로그, JavaScript 오류, 스택 추적, 헤더 + 본문이있는 네트워크 요청 / 응답, 브라우저 메타 데이터 및 사용자 지정 로그를 기록합니다.
또한 DOM을 계측하여 페이지에 HTML 및 CSS를 기록하여 가장 복잡한 단일 페이지 앱에서도 픽셀 단위의 완벽한 비디오를 재현합니다.