[패스트캠퍼스] 프론트엔드 취업 완성 과정 3기 - git사용법과 프로젝트

JYROH·2022년 9월 29일
1


학교를 다니면서 git이란 말을 들을때마다 항상 불안하고 떨리곤 했었습니다. 특히나 그냥 개인의 프로젝트, til과 같은것들을 단순하게 올리는 것이라면 모르겠지만 실제로 협업을 해야하는경우에는 너무 어려워했었고 명령어 하나 칠때마다 검색을 수도없이 하곤 했었습니다. 그러나 개발자가 되려면 언젠가는 넘어야했던 산이기에 일주일 내내 git을 배운다했을때 언능 배우고싶다는 생각이 들었었습니다. 기본적인 cli명령은 익숙하니, git의 전체적인(큰) 구조와 흐름, 항상 어려워했던 merge와 push과정, 그리고 실제 프로젝트를 진행할때 완벽하고 안전함을 부여해줄수있는 git flow에 대해서 알아보겠습니다.

Git - 일련의 add, commit, push


우선 가장 기본적인 과정인 add commit push를 알아보겠습니다. 저도 git을 사용한적이 있어서 세개의 명령어는 익숙하다고 생각했지만 제가 배운것은 완전히 다른 부분이었습니다.

제가 한건 이런거였죠

git add .
git commit -m "my first commit"
git push origin main

항상 일련의 작업을 올릴때 위와 같이 올렸었습니다. 그러나 강의를 듣고나서는 절대 해서는 안될 행동들이라는것을 알게되었죠.

git add는 전체를 올리는것이 아닌 항상 파일별로 추가해줘야합니다(파일 개수가 10개이하정도면). 또한, commit도 한번에 하는 것이 아닌 add된 파일마다(물론 중요한 경우) commit을 따로 적어주는것이 좋은 자세입니다.

git commit이라는 명령어도 항상 -m을 붙여 단축속성으로 작성했었습니다. 그러나 이 방법을 통하여 상세 설명까지 부여할수있다는것을 깨닫게되었습니다(vi까지..). 또한 제가 굉장히 배우고싶었던 것이 있는데 바로 commit convention입니다. 물론 각 회사마다 사용하는 방법이 다르겠지만 어느정도 통용되는 컨벤션이있으면 그것을 연습해보는것이 좋은기회일것 같습니다.

  • feat: 기능 개발 관련
  • fix: 오류 개선 혹은 버그 패치
  • docs: 문서화 작업
  • test: test관련
  • conf: 환경설정 관련
  • build: 빌드 관련
  • ci: Continuous Integration(회사에서 유지보수할때 쓰이는것 같습니다) 관련

위와 같은 Prefix들을 앞에다가 달고 commit 메세지를 작성하는것이 좋아보입니다. 또한 항상 메세지의 시작과 중요 내용들은 대문자로 표시해주는 습관도 중요합니다.

git push입니다. 앞에서 commit을 자주해주는것이 좋다고 설명했는데 그것과 더불어 commit들이 여러번 쌓이고 push는 최소화해서 해주는것이 효율적이고 실수없는 브랜치 관리방법이 되겠습니다.

merge와 merge conflict


개인이 기록용으로 쓰는 git은 할만하고 쉽지만, 협업이 들어가는 순간 얘기가 달라집니다. 그 이유가 바로 merge때문인것 같습니다.

Merge는 고마운 기술입니다. 저희가 복붙, 파일 끌여다쓰기 와 같은 노동을 하지 않고도 알아서 변경사항을 찾아내어서 하나의 파일로 합쳐주죠. 그러나 이렇게 합쳐줄때는 문제가 있습니다. 새로 생긴 것을 추가해서 합치는것은 문제가없지만 원본 파일과 다른 부분이 존재하면 어떻게 합쳐지는지 입니다. 그 대단한 git조차 이것은 당연히 판단할수가 없죠. 따라서 git은 이러한 난처한 상황에 처하면 merge conflict라는 오류를 발생시킵니다. 그러면 저희는 판단해야하죠.

  • 원래것을 살리던가
  • 병합되는것을 살리던가
  • 둘다 살리던가
  • 둘다 죽이던가

와 같이 말입니다. 어려운 일은 아니지만 이 상황을 해결할때는 팀원끼리의 분명한 의사소통이 필수로 보입니다. 잘못된것을 날리면 안되기 때문이죠.

merge conflict가 발생한 상황입니다. 원본이 바뀌어서 pull을 했는데, 제 local과 다른 상황이 발생한 경우입니다. 이때, Merge conflict in README.md라는 오류메세지를 발생시키고 눈여겨 볼만한것은 현재 브랜치가 main|MERGING으로 변경된것입니다. 이 상태를 확인하면 지금 merge conflict가 발생하였고 이것을 해결해야한다는것을 알 수 있습니다.

또한 merge conflict는 굉장히 친절합니다. 잘못된 부분을 모두 찾아내어 띄워주고 저는 거기서 선택만하면 되기 때문이죠(vi normal mode에서 dd를 누르면 줄들을 금방금방 지워낼수있습니다). 따라서 이렇게 conflict해결후 add해주고 commit을 하면 merge가 완료되게 됩니다.

branch의 개념과 git flow


협업에서 가장 중요한 git의 기능을 꼽으라하면 그것은 무조건 branch입니다. 코드를 날려먹지 않게 도와줄 뿐더러(main branch의 유지), 기능 개발과정을 쾌적하게 해주고 경우에 맞는 branch관리를 통하여 전체 프로젝트의 유지보수가 가능합니다.
저희는 앞으로 협업에서 git flow라는 전략을 적용시키겠지만, 기본적으로 git branch ~~로의 브랜치 생성, git switch로 브랜치 변경, git branch -D ~~로 브랜치 삭제가 가능하다는것 정도는 알고 넘어가야합니다.

git flow

git flow는 실제 실무에서 자주 사용되는 branch 관리 기능입니다. 기본적으로 기능 개발- 배포 - 핫픽스 - 다음 버전 관리 와 같은 브랜치들을 자동으로 생성, 병합까지 알아서 처리해주는 고마운 기능입니다.
아래는 git flow를 설명해주는 굉장히 유명한 그림으로 이것을 참고하면 도움이 될것입니다.

실제로 제품 출시를 담단하는 master브랜치는 몇번의 병합 과정이 별로 없는것을 볼 수 있고 대부분의 과정은 develop, feature, 그리고 release에서 일어나는 것을 볼 수 있습니다. 따라서, 저희 정도 레벨에서는 이정도의 git flow를 사용해보는것을 목표로 삼는것이 좋습니다.

master - (release) - develop - feature

위의 flow를 꼭기억해둡시다. git flow는 초기 설치를 해두면 굉장히 간편하게 사용이 가능합니다.

git flow init : git init은 사용을 자제하고, git flow init은 사용을 장려해야합니다. 해당 기능을 사용하여 main branch에서 git flow개념을 적용시켜 나갈 수 있습니다. 기본적으로 이 명령어를 통하여 develop브랜치가 생성이 됩니다.

이제 각 기능 개발을 해야합니다. develop 브랜치가 이름이 develop이라고 여기서 개발하는 것이 아닙니다. develop브랜치는 개발이된것을 합치는 브랜치로 생각해야하고 저희는 feature브랜치를 사용할 것입니다.
git flow feature start ~~의 명령어를 통하여 feature개발이 시작되고 브랜치가 생성이 됩니다.
해당 브랜치에서는 만들고 싶은 기능들을 열심히 만들어주면 됩니다. 그리고 기능 개발이 완료되면 당연히 commit을 작성후 merge를 develop에 시켜줘야합니다. 이때, 저희가 배웠던 git merge명령어를 사용하는것이 아닌, git flow feature finish를 통하여 꼭!!! 종료 시켜줘야합니다. 이러면 자동으로 develop에 병합을 시켜줍니다.

위의 과정을 여러번 반복하여 기능 개발이 종료가 되면, 이제 배포를 해야겠죠. 이때 release브랜치를 사용하게 됩니다. 여기서 release를 하게 되면 github상에서도 release와 tag가 뜨게 됩니다. 버젼관리에서 굉장히 중요하기 때문에 release note같은 부분들도 상세히 적어주면 좋습니다.
git flow release start ~~ 의 명령어로 release시작이 가능합니다. 이때, release명은 v0.1과 같이 버젼명으로 해주는것이 좋습니다.

곧바로 git flow release finish ~~로 릴리스를 종료시킵니다. 여기서 끝이 아닙니다. Tag를 작성해줘야합니다. commit 메세지 중 하나가 tag 메세지인데(나머지는 merge), 이것을 적어준후, git push --tags로 꼭 넘겨줘야합니다.

이제 release가 완료되었습니다. 해당 release와 tag들은 github 레포지토리에서 확인이 가능합니다. 이제 최종 단계, main을 다뤄주면 됩니다.
git push origin main으로 develop브랜치에서 넘겨주면 끝입니다.

앞으로 개인 프로젝트여도 위의 과정을 거쳐서 git flow방법론에 익숙해지는것이 좋을 것 같습니다.

pull과 pull request


이제 협업에서 필요한 마지막 도구입니다. pull과 관련한 것들이죠.

git pull

굉장히 중요한 도구입니다. pull은 git의 fetchmerge과정을 같이 진행해주는 명령어입니다. 즉, remote repo에서 파일들을 가져오고 병합까지 시켜주죠. 여기서 저희는 이 pull을 언제쓰는지 생각해보아야합니다. 제가 아까 말했던 merge conflict상황을 예방하려면 develop브랜치가 변경되었을때 pull을 통하여 자신의 코드를 최신화해주어야 push나 pull request를 보냈을때 충돌이 나지 않을것입니다.

이때, 이러한 생각이 들어야합니다. 내가 열심히 기능을 만들고 있는데 develop 브랜치가 변경이 되면, 배운대로라면 pull을 해주어야하는데 이러면 다 날라가는거 아니야?
날라가진 않습니다. 단지 앞서 보았던 merge conflict상황이 제 컴퓨터에서 난다는 것이죠. 이왕이면 pull request과정에서 발생하는것보다는 그게 낫습니다. 따라서 지속적으로 pull을 통하여 최신화를 진행하고, merge conflict는 내가 직접해결하는것이 깔끔합니다.

pull을 해주려면 팀 레포와 연결이 되어있어야합니다(당연하겠죠. 물론 이것은 협업을 진행할때 fork를 통하여 내 레포로 가져온 경우입니다). 따라서 pull 이전에 우리의 remote에 팀 레포를 등록해주는게 필요합니다.
git remote add upstream (레포주소)를 통하여 우리의 remote에 팀을 등록시켜줍니다. 그리고 나서 git pull upstream develop명령어를 통하여 팀 레포의 develop을 가져올수 있게 됩니다. merge conflict가 발생하면, 해결하고 안 발생하면 그대로 진행하면 됩니다.

pull request

이제 팀장님의 차례네요. pull request는 말그대로 "당겨줄것을 요청한다"입니다. 내(팀원)가 열심히 git flow를 사용하여 기능개발을 하여 나의 develop에 만들어놨으니, 너가 확인하고 가져가라 정도가 되겠네요. 이때 팀장은 files changed를 통하여 변경사항들을 확인하고, 잘못된게 있는지, 있으면 반려하고 없으면 approve시키면 됩니다. 이렇게 pull request를 통과한 코드는 팀장의 권한 아래 팀 레포의 develop브랜치로 합쳐지게 됩니다.

팀원의 develop -> 팀의 develop 브랜치로 가야한다는것을 명심해야합니다.

이때 당연히 develop으로 요청을 보내야합니다. 안그러면 git flow를 사용한 의미가 없겠죠. 이 과정이 모두 완료가 되면 앞서 언급한 release과정을 거쳐 develop -> main 을 진행해주면 됩니다.

저희팀의 pull request항목들입니다. convention을 최대한 지켰으며 request도 여러번 반려시키기도 하였습니다. 여러번의 과정끝에 모두 잘 합쳐졌습니다.

마치며


이번 일주일간의 git특강을 통하여 정말 많은것을 배웠습니다. CLI에서 명령어 하나하나 헷갈리며 구글링해 검색을 하던 과거와는 달리 이제 대부분을 머리와 손에 익혀두었습니다. 협업은 여전히 쉽지 않지만, 저부터 스스로 연습을 열심히 해두어야 미래에 협업도 잘 진행하지 않을까 싶습니다. 곧 진행할 클론코딩 프로젝트에서도 혼자서 열심히 git을 적용시켜볼 예정입니다!

profile
안녕하세요 노준영입니다.

2개의 댓글

comment-user-thumbnail
2022년 10월 6일

와 준영님 포스팅 진짜 잘쓰셨네요!!!
git 너무 어려운데 이것만 잘 읽으면 되겠어요🤭

1개의 답글