본문 바로가기
git

<16> 생활코딩 - GIT

by ChaeLOTUS 2022. 12. 5.
728x90
Git을 이용한 프로젝트 흐름(Git Flow) 1

위의 그림이 git에서 폭넓게 받아들여지고 있는 기술을 잘 사용하는 방법 중 하나인 git flow를 처음 고안한 사람이 만든 이미지이다.

여기서 가장 중요한 브랜치가 master 브랜치와 develop 브랜치가 있다. 이 두가지가 중심되는 축이다.

이 두개의 역할분담을 해놓고 있는게 가장 중요한 의미이다.

여기서 첫번째, 실제로 개발이 진행되는 것은 우리가 깃을 처음 사용할 때는 마스터에서 개발을 한다.

하지만 git flow에서는 마스터에서 개발을 하지 않고 마스터에서 파생된 브랜치 develop이라고 하는 브랜치에서 실질적인 개발이 이루어진다. 여기서 개발을 쭉 해나가다가 어떤 특정한 기능을 개발해야 되는 그런 경우가 생겼을 때 git flow에서는 별도의 feature(기능) 라는 브랜치를 만든다. 개발이 끝나면 feature에서 작업했던 내용은 develop 브랜치로 병합한다.

그리고 어떤 특정한 기능에 속하지 않은 애매한 변경사항들 또는 버그에 대한 처리나 그런것들은 계속 develop을 통해서 해나간다.

그렇게 작업을 쭉 해나가다보면 이제 작업을 마무리하고 사용자들에게 그 작업한 결과를 배포하는 시점이 온다.

그러한 순간에 이제 새로운 브랜치를 만드는데 release라는 이름으로 시작하는 브랜치를 만든다.

release브랜치 이후에 발생하는 여러가지 버그의 수정이나 문서를 업데이트하는 이런 작업들은 release브랜치 안에서 작업을 해나간다. 

그런한 작업이 끝날 때마다 develop브랜치에 병합을 해서 (나중에 한꺼번에 병합을 하면 충돌이 일어나기 쉬우니까) 나중에 일을 많이 해야되는 상황을 없앤다.

그렇게 해서 release브랜치의 작업이 끝나서 테스트까지 다 마치면 실제로 서버에 release를 해야할 것이다.

바로 그 release하는 순간에 마스터브랜치로 release브랜치의 변경사항을 병합한다.

그리고 깃의 tag라는 기능을 통해서 1.0버전의 release는  마스터 브랜치의 이 커밋이다 라는 것을 어딘가에 기록해 놓는다.

tag라는 형식과 기능을 통해서 기록을 하고 서버에다가 업로드를 한다거나 사용자가 다운로드 할 수 있게 제공한다거나 그런것을 하는 것이다. 그렇게 되면 마스터 브랜치는 release와 관련된 사용자에게 제공되었던 버전들만을 모아놓은 브랜치가 되는 것이다. 

그리고 동시에 release에서 작업했던 내용은 계속 개발도 해야되기 때문에 develop브랜치로 병합하는 것이다.

즉, release브랜치는 마스터 브랜치로도 가고 develop브랜치로도 간다. 

이런식으로 쭉 작업을 진행해 나가면서 프로젝트가 성숙해진다라고 하는 모델이 git flow라고 하는 모델이다.

이중에서 설명하지 않은  hotfix는 우리가 사용자에게 어떤 버전을 제공을 하는데 긴급하게 버그가 생길 가능성은 항상 있다. 그런 경우에는 아주 짧은 시간에 일을 처리 해야 하기 때문에 hotfix라고 시작하는 이름의 브랜치를 생성하고 그 브랜치에서 긴급하게 문제를 해결한 다음에 마스터로 병합을 한 다음 그 마스터 브랜치의 버전을 tag로 버전명을 적고 기록하여 사용자에게 제공한다. 

그리고 hotfix의 내용은 역시나 마찬가지로 develop브랜치로 병합을 하는 것이 gitflow의 기본적인 흐름이라고 할 수 있다.

 

 

Git - Git을 이용한 프로젝트의 흐름 (Git Flow) 2

github에 gitflow이름으로 저장소를 만들고 ssh주소를 복사해 git의 저장소와 연결시켜주었다.

git remote add origin [ssh 주소]

파일을 만들어 내용을 입력하고 커밋을 생성함.

위에도 언급했듯이 gitflow에서는 master와 develop브랜치가 축인데

master 브랜치는 사용자에게 노출되는 버전들이 마스터만 있고,

develop 의무적인 구현과 관련된 것은 develop 브랜치에서 이루어진다.

 

우선 develop 브랜치를 만들자. (마스터 브랜치에서 파생시켜서)

이떄 상황을 log로 확인해보면

master 1이라는 커밋은 master브랜치와 develop브랜치 모두 체크아웃 된 상태라는 뜻.

develop브랜치에서 하나의 커밋을 만들고 log해보면

마스터 브랜치는 master1커밋에 머물러 있는 상태이고 develop브랜치는 새로운 커밋이 만들어진 상태이다.

이렇게 작업하다가 우리가 어떤 기능을 추가해야 되는 새로운 업무가 생겼다면

위의 그림에서 어디에 해당되냐면 왼쪽 사진과 같은 부분이 해당된다.

이 그림을 봤을 때는 작업을 하는 도중에 두 개의 새로운  기능을 추가 해야하는 상황에 있다라는 것을 알 수 있고 지금 실습에서는 하나만 해보도록 하겠다.

 

개발을 하려는 기능에 따라 이름을 구현하면 된다.

feature-login or feature-help ...ect

 

 

 

나는 develop2 버전에서 파생된 feature-some브랜치를 생성하였다.

여기서 파일의 내용을 추가하고 커밋하고 log를 해보면 

feature-some이라고 하는 브랜치는 새로운 버전을 갖게된다.

여기서 새로운 기능을 구현을 하다가 일단락이 됐으면 (완전하지 않더라도) develop으로 병합을 한다.

develop으로 체크아웃한다. 

그리고 git merge feature-some 을 하면 feature-some에서 작업했던 내용이 develop에 병합이 된다.

log를 해보면,

feature 3라고 하는 feature-some에서 추가된 버전이 이제 develop에 병합된 상태이다.

이렇게 병합을 하고 나면 선택사항 이지만 히스토리를 깔끔하게 정리하고 싶다면 feature-some이라고 하는 건 이제 없어져도 되기 때문에 

git branch -d feature-some 이라고 입력하면 feature-some 브랜치를 삭제해준다.

feature-some브랜치가 삭제된 것을 확인할 수 있다.

현재 위의 체크된 상황까지 온 상황

새로운 기능을 추가했고 그 기능을 이제 사용자에게 제공해야 된다 또는 실제 서버에 업로드 해야 된다라고  한다면 이제 release브랜치를 사용할 때가 되었다. 

release-1.0 (릴리즈할 버전에 대해 이름을 정할 수 있다.)

release하고자 하는 것에서 사용자에게 릴리즈 되어야 될 내용에서 발생한 수정사항 또는 문서에 갱신 이러한 작업들이 있다면 우리는 릴리즈 상태에서 작업을 해야한다.

release브랜치에서 커밋을 생성 후 log를 해보면, 밑의 사진과 같은 상황이 된다.

release가 추가된 상태이다.

이렇게 해서 릴리즈를 위한 준비가 모두 끝나면 이제 릴리즈 브랜치의 현재버전을 마스터와 develop에 모두 merge를 시킨다.

우선 master로 체크아웃하고 git merge release-1.0 입력하여 병합한다.



현재 위의 사진에 체크한 곳에 와있다.

그리고 마스터 브랜치에서 특정 버전이 release브랜치라는 것을 조금 더 명시적으로 기록할 수 있는 방법이 바로 tag를 생성하는 것이다.

-a 옵션을 쓰게 되면 어떤 버전인지 특정한 커멘트를 쓸 수 있다. 그리고 뒤에 master라고 쓰게되면 마스터 브랜치의 현재 헤드에 해당되는 버전에 대한 그 버전을 가리키는 태그가 생성된다.

git tag -a 1.0 -m "first release" master

 

마스터 브랜치는 release-1.0 4 커밋을 가리키면서 동시에 1.0이라고 하는 tag 역시도 그 커밋을 가리킨다.

여기 있는 master나 release1.0이나 develop과 같은 브랜치는 내가 버전을 생성할 때 마다 그 생성된 최신버전을 가리키는 일종의 포인터 같은 역할을 하지만 tag 1.0은 저것을 지우기 전까지는 언제나 release-1.0 4커밋을 가리키기 때문에 특정 커밋이 어떠한 의미가 있는가 라는 것을 기념할 수 있는 그런 커밋 태그이다.

이렇게 해서 release에서 변경되 사항 까지 마스터에다가 반영하고 태그로 기록까지 했으면 이제 그것을 사용자에게 다운로드 받을 수 있도록 하거나 실제 서버에 올려서 서비스를 하거나 하면 된다. 동시에 release에 있었던 변경사항 등은 당연히 develop으로 동기화할 필요가 있기 때문에 다시 develop으로 체크아웃하고 git merge release-1.0  병합까지 해준다. 

그럼 위의 사진에 보이는 것처럼 마스터 브랜치와 develop브랜치는 똑같은 커밋을 가리키게 되니깐 두 개는 서로 같은 소스코드의 상태에있게 되는 것이다.

이렇게 작업을 진행하다가 긴급하게 수정해야 될 상황이 생기면 git flow모델에서는 hotfix라는 것을 이용한다.

현재 상황에서 hotfix를 해야된는 긴급하게 수정해야 될 상황이 발생하면 

git checkout -b hofix-some 입력하고

파일을 수정하고 커밋한다. 그리고 수정이 끝났으니 이것은 release와 마찬가지로 develop으로도 가고 master로도 간다.

r그럼 마찬가지로 master로 체크아웃해서 병합한다.

git tag -a 1.1 -m "hotfix some" master : 마스터 브랜치의 내용을 태그로 만든다.

마스터 브랜치와 tag 1.1과 hotfix-some이 같은 커밋을 가리키게 된다.

그리고 hotfix에서 변경된 내용은 develop으로도 변경을 해야되기 때문에 git checkout develop / git merge hotfix-some을 하면

 

 


여기서 원격저장소를 사용하면서 작업을 한다면 위의 작업을 하는 과정에서 언제 pull을 하고 언제 push를 해야하나 라는 것에 가장 큰 원칙은 자주 하는 것이다. 자주 할수록 다른 사람과의 충돌이 적어진다. 작업을 쭉 하다가 새로운 브랜치를 만들기 직전에 당연히 pull을 해서 다른 사람이 develop쪽에 변경한 것이 없는지를 직전에 확인 해야하고 feature브랜치에서 작업을 쭉 해나가면서 내가 작업한것을 develop으로 merge를 한다면 나중에 feature내용이 필요없어지면 develop에서 제거하는 것이 굉장히 어렵기 때문에 feature브랜치는독립된 곳에서 역사를 써나가는 것이 좋다. 그런데 그것을 하는 과정에서 feature브랜치에 있는 내용과 develop에 있는 내용이 같은 곳이 수정되고 있었다고 한다면 나중에 피처 브랜치의 내용을 디벨롭 브랜치로 병합했을 때 심각한 문제가 생길 수가 있다. 그렇기 때문에 이러한 문제를 낮추기 위해서는 develop에서 변경된 사항을 계속해서 feature브랜치로 가져와서 feature브랜치는 develop브랜치의 내용을 가지고 있어야 하고 develop브랜치는 feature브랜치의 내용을 가지고 있지 않은 상태가 유지되다가 feature브랜치의 내용이 끝나면 그 때 develop브랜치로 이동해서 feature브랜치의 내용을 merge하는 것을 통해서 이 두개를 동기화 시키면 된다.

나머지 것들은 release브랜치를 생성한 후에 release브랜치에서 변경사항은 기다리지 말고 바로바로 develop쪽에 반영을 시켜서 

develop브랜치를 사용하고 있는 다른 개발자들이 나중에 충돌이 크게 발생하는 문제를 낮추는게 좋다.

hotfix도 마찬가지로 hotfix를 만들고 바로 develop으로 merge를 한 다음에 그리고 그것을 push해서 다른 사람이 동기화 할 수 있도록 해주야 될 것이다. 마스터 브랜치도 마찬가지이다. 특히나 마스터 브랜치는 사용자에게 최종적으로 노출되는 버전을 모아놓은 것이 마스터 브랜치이기 때문에 그러한 역할을 가지고 있는 권한을 가지고 있는 사람만이 엄격하게 통제하는 형태로 진행되는 것이 협업의 맥락에서는 사고를 줄일 수 있는 좋은 방법이다.

 

 

 

 

728x90

'git' 카테고리의 다른 글

TIL - [Linux/Git]  (2) 2023.02.24
<15> 생활코딩 - GIT  (0) 2022.12.04
<14> 생활코딩 - GIT  (0) 2022.12.03
<13> 생활코딩 - GIT  (0) 2022.12.03
<12> 생활코딩 - GIT  (0) 2022.12.03

댓글