[Git] 1. Git이란?(입문)



git에 대해서는 제대로 개념을 잡기 위해 정리하는 개념으로 진행할 예정입니다.

git은 써도 계속 헷갈린다. 그래서 자주 보기위해 단계별로 정리하는 개념으로 git에 대한 포스팅을 하겠습니다. 아래의 포스팅 내용의 원글 URL이다. https://www.tuwlab.com/ece/22202


다른 블로그에 내용들



1. Git이란?


개발을 하면서 팀원들간에 소스코드의 최신판을 관리하기가 어렵다. 그래서 프로젝트에서 빈번하게 발생하는 이러한 문제를 해결하기 위해 등장한 도구가 바로 형상 관리 도구(Configuration Management Tool)인데, 리누스 토발즈가 리눅스 커널 프로젝트를 위한 버전 관리 시스템으로 개발하였으며, SVN과 같은 형상관리도구이다.

소프트웨어 공학의 프로젝트 진행 및 관리 방법에서 비중 있게 다뤄 지는 영역 중 하나이기도 합니다.

Git의 장점

  • 빠르다
  • 모든 작업자가 원본을 가지고있다
  • 분산버전관리시스템
  • Local에서 대부분의 작업을 할 수 있다.
  • branches/tags/master, 기타 revision이동시 굉장히 빠르다.
  • 혼자 사용할 경우 svn보다 관리포인트가 적다. (그리고 편하다.)



2. Git 특징


  • 소스코드 주고받기가 필요 없고, 같은 파일을 여려 명이 동시에 작업하는 등 병렬 개발이 가능해지며, 버전 관리가 용이해져 생산성이 증가합니다.

  • 소스코드의 수정 내용이 커밋 단위로 관리되고, 패치 형식으로 배포할 수 있기 때문에 프로그램의 변동 과정을 체계적으로 관리할 수 있고, 언제든지 지난 시점의 소스코드로 점프(Checkout)할 수 있습니다.

  • 새로운 기능을 추가하는 Experimental version을 개발하는 경우, 브랜치를 통해 충분히 실험을 한 뒤 본 프로그램에 합치는 방식(Merge)으로 개발을 진행할 수 있습니다.

  • '분산' 버전관리이기 때문에, 인터넷이 연결되지 않은 곳에서도 개발을 진행할 수 있으며, 중앙 저장소가 폭파되어도 다시 원상복구할 수 있습니다.

  • 비단 팀 프로젝트가 아닌, 개인 프로젝트일지라도 GIT을 통해 버전 관리를 하면 체계적인 개발이 가능해지고, 프로그램이나 패치를 배포하는 과정도 간단해집니다. (Pull을 통한 업데이트, Patch 파일 배포)



SVN과 비교

  • 전통적인 SVN 설정에서는 버전 관리를 하기 위해서는 여러분의 작성한 코드를 반드시 커밋해야 하고, 이 수정 내용이 다른 사람의 작업을 깨트리거나 문제를 일으키기도 한다.
  • 각 개발자가 작업을 진행할 수 있는 자신만의 샌드박스를 가지고 있으며, 작업을 마친 뒤에 변경내역을 마스터 저장소에 올려 보낼 수(push) 있다.

  • SVN은 모든 디렉터리에 .svn 폴더를 가지고 있어야한다.
  • Git은 프로젝트 정보를 저장하기 위해 하나의 디렉터리를 사용하기 때문에 체크아웃 한 루트 디렉터리에 하나의 .git 폴더를 사용하도록 단순화하였다. 이름을 바꾸거나 위치를 이동하는 것으로 파일 내역이 깨지는 일이 없다.

  • SVN의 경우 Trunk(주 작업 공간)와 Branch들이 있고 각 브랜치가 소스의 복사본이다.
  • Git에서는 모든 것이 브랜치다. Git에서는 새 브랜치가 아주 빠르게 만들어 지며 브랜치 간의 이동도 빠르게 수행된다. Tag를 만드는 것도 놀라울 정도로 쉽다.



3. GIT 트랜젝션


todo-app s1

작업한 내용을 스테이지에 올려서 로컬 저장소에 커밋하고, 이를 푸시해서 원격 저장소로 보낸다.



4. GIT 관련 주요 용어


Git을 사용하기 위해서는 필수적으로 알아야 될 용어


4-1. 저장소 (Repository)


소스코드가 저장되어 있는 여러 개의 브랜치(Branch)들이 모여 있는 디스크상의 물리적 공간을 의미합니다.

원격 저장소만 있는 SVN과 달리, GIT에서는 저장소가 로컬 저장소(Local Repository)원격 저장소(Remote Repository)로 나뉩니다.

작업을 시작할 때 원격 저장소에서 로컬 저장소로 소스코드를 복사해서 가져오고(Clone), 이후 소스코드를 변경한 다음 커밋(Commit)을 합니다. 이 때, 커밋한 소스는 로컬 저장소에 저장되며, 푸시를 하기 전에는 원격 저장소에 반영되지 않습니다.


4-2. 체크아웃 (Checkout)


특정 시점이나 브랜치의 소스코드로 이동하는 것을 의미합니다. 체크아웃 대상은 브랜치, 커밋, 그리고 태그입니다. 체크아웃을 통해 과거 여러 시점의 소스코드로 이동할 수 있습니다.

cf. SVN의 체크아웃

SVN에서는 체크아웃이 원격 저장소의 파일을 작업하기 위해 로컬로 가져오면서 동시에 다른 사람이 수정할 수 없도록 Lock을 거는 과정을 의미하며, GIT에서의 체크아웃과는 전혀 다른 의미입니다.


4-3. 스테이지 (Stage)


작업한 내용이 올라가는 임시 저장 영역입니다. 이 영역을 이용하여 작업한 내용 중 커밋에 반영할 파일만 선별하여 커밋을 수행할 수 있습니다.


4-4. 커밋 (Commit)


작업한 내용을 로컬 저장소에 저장하는 과정입니다. 각각의 커밋은 의미 있는 변경 단위이고, 변경에 대한 설명을 커밋 로그로 남깁니다. 대개 하나의 커밋은 ‘회원 가입 기능 추가’, ‘검색 버그 수정’과 같이 하나의 주제로 묶을 수 있는 변경 단위가 됩니다.

프로젝트 팀에 따라 커밋을 하는 단위가 서로 다르고, 커밋 로그를 작성하는 형식(Format)도 정해져 있습니다. 특히, Continuous Build System과 같이 원격 저장소와 연동된 자동화 시스템을 사용하고 있는 경우, 이 자동화 시스템이 인식할 수 있도록 엄격한 형식에 맞춰서 커밋 로그를 작성해야 할 수도 있습니다.


4-5. 태그 (Tag)


커밋의 임의 위치에 쉽게 찾아갈 수 있도록 붙여놓은 이정표를 태그라 합니다. 태그가 붙여진 커밋은 Commit ID 대신 태그명을 입력하여 쉽게 체크아웃 할 수 있습니다.


4-6. 푸시 (Push)


로컬 저장소의 내용 중 원격 저장소에 반영되지 않은 커밋을 원격 저장소로 보내는 과정입니다.

cf. SVN의 커밋과 푸시

SVN에서의 커밋은 변경 사항을 원격 저장소로 저장하는 과정을 의미합니다. GIT에서의 커밋은 로컬 저장소로 변경 사항을 반영하는 것을 의미하며, 원격 저장소로 변경사항을 보내는 과정은 푸시입니다.

즉, ‘SVN의 커밋 = GIT의 커밋 + GIT의 푸시’ 라고 할 수 있습니다.


4-7. 풀 (Pull)


푸시와 반대로 원격 저장소에 있는 내용 중 로컬 저장소에 반영되지 않은 내용을 가져와서 로컬 저장소에 저장하는 과정을 의미합니다. 이를 통해 다른 팀원이 변경하고 푸시한 내용을 로컬 저장소로 가져올 수 있습니다.

푸시 과정에서 충돌(Collision)이 일어나서 푸시가 거절된 경우, 풀을 통해 원격 저장소의 변경 내용을 반영한 뒤 다시 푸시를 시도해야 합니다.


4-8. 브랜치 (Branch)


커밋을 단위로 구분된 소스코드 타임라인에서 분기해서 새로운 커밋을 쌓을 수 있는 가지를 만드는 것, 혹은 그 가지를 브랜치라 합니다.

todo-app s1

브랜치 중에 개발의 주축이 되는 브랜치를 마스터 브랜치(Master Branch)라 하며, 모든 브랜치는 마스터 브랜치에서 분기되어 최종적으로 다시 마스터 브랜치에 병합(Merge)되며 개발이 진행됩니다.

위 그림에서 서로 다른 색상으로 구분된 선들이 각각 하나의 브랜치를 의미합니다. 가장 오른쪽에 있는 파랑색 브랜치가 마스터 브랜치이며, 작업의 흐름을 보면 이 마스터 브랜치에서 분기된 뒤 최종적으로 다시 마스터 브랜치에 병합됨을 알 수 있습니다.

cf. Fork

Branch와 유사한 용어로 Fork가 있습니다. 원격 저장소를 로컬 저장소로 복제한 뒤 새로운 원격 저장소에 푸시하는 과정이 Fork입니다.


4-9. 병합 (Merge)


브랜치와 반대되는 개념으로, 하나의 브랜치를 다른 브랜치와 합치는 과정을 의미합니다.

두 개의 브랜치를 합쳐서 하나의 브랜치로 만드는 3-Way Merge가 모든 병합 작업의 기본이 됩니다. 병합의 대상이 되는 두 브랜치는 주종관계가 성립하며, 따라서 ‘A 브랜치와 B 브랜치를 병합한다’라는 말은 모호한 표현이 됩니다. 즉, ‘A 브랜치를 B 브랜치에 병합’하는 작업과 ‘B 브랜치를 A 브랜치에 병합’하는 작업은 서로 다른 작업입니다.

병합도 엄연히 말하면 커밋의 한 종류입니다. 일반적인 커밋은 조상 커밋이 하나인 커밋인 데 반해, 병합의 조상 커밋이 둘 이상인 경우입니다. 즉, 3-Way Merge는 ‘서로 다른 두 커밋으로부터 하나의 새로운 새로운 커밋을 생성하는 작업’입니다.

병합 과정에서 두 개의 브랜치에서 파일의 같은 부분을 서로 다른게 수정한 경우 충돌(Collision)이 발생하며, 병합이 일시정지 됩니다. 이 경우, 충돌이 발생한 부분을 직접 수정하거나, Merge Tool 등을 활용하여 충돌을 해결한 뒤 병합을 계속 진행하면 됩니다.


5. GIT 관련 웹 기반 솔루션


GIT의 원격 저장소를 가장 효율적으로 관리하는 방법은 바로 웹 기반 GIT 솔루션을 사용하는 것입니다.

이들 솔루션에서는 원격 저장소 관리 기능 뿐만 아니라 위키, 이슈 관리, 머지 요청 관리, 팀원 관리 등 전반적인 프로젝트 관리 기능도 함께 제공합니다. 웹 기반으로 동작하므로 브라우저만 있으면 접근이 가능하기 때문에 코드리뷰 등의 작업도 한층 수월하게 할 수 있습니다.

이러한 솔루션의 대표적인 예로 GitHub와 GitLab을 들 수 있습니다.

이 둘의 가장 큰 차이점은 폐쇄성 여부입니다. GitHub은 오픈소스 프로젝트에서 많이 사용되고, GitLab은 기업체 등에서 인트라넷에 설치하여 많이 사용합니다.



git에 대한 개념을 다음 포스팅에서도 계속 다루기 때문에 한번 스윽~ 읽고 Skip


참고