git 활용 step 2nd / 작업과정 분리하기 - branch
Introduction
이번 포스팅부터는 최근에 공부하고 적용해본 내용이다. 물론 혼자 코딩할때 사용할 수 있는 방법이다.
한 프로젝트를 진행하면서 레포지토리에 백업하고 다시 갖다쓰는 방법은 이전 포스팅에서 다뤘다.
그럼 이제 한 프로젝트를 기능별로, 작업별로 구분해서 관리하고 싶다면 어떻게해야할까?
이번 포스팅에서 다룰 내용이다.
branch, switch, merge에 대해서 araboza
상황을 만들어보자
muzzi project라는 디렉토리를 만들고 깃으로 관리하게 해줬다.
세가지 기능을 각각 파일로 분리해줬음. user기능, board기능, error기능 등 코딩을 할거다.
각각의 파일은 저런 코드가 담겨있음
이미 디렉토리 별로 코딩을 알아서 하면된다. 작업을 파일, 디렉토리별로 구분하는건 뭐 다들 사용해본 규칙같은거고 이러면 관리가 쉬운건 다 본능적으로 알고있다.
기능별로 파일이나 디렉토리로 나눴으니 걍 그 기능에대해서 커밋만 제대로 해주면 뭐.. 문제될건 없을거임
근데 어느날 코드를 보니까 매우 맘에안드는거임.
난 코드를 전부다 함수로 감싸고싶다.
이렇게 저 코드들을 전부다 함수로 감싸는 작업을 하고싶음. 이건 세 파일 모두 건들여야 하는 작업이지만, 디렉토리로 따로 분리도 안되어있고.. 근데 이 작업자체를 난 분리하고 싶은데?
이럴떄 branch를 사용하면 된다.
# 초기환경 만들자~
git init
git remote add muzzi-repo https://github.com/nurdworker/git-step2-posting.git
당연히 디렉토리를 깃으로 관리하게 해줬고 난 좀따 push도 해줄거라 remote도 만들어줬다
git add .
git commit -m 'first commit
이렇게 첫 커밋 한번 해주자
이에 해당하는 함수들이 저런코드들이 들어있다.
그래프도 first commit이 생겨나있음.
# branch만들기
git branch <브랜치 이름>
이렇게 쓰면 된다.
git branch makeFuncs
난 함수로 감쌀 작업을 만들거라 makeFuncs라는 브랜치를 만들어줬따.
git switch <만든 브랜치이름>
switch는 해당 브랜치로 옮겨주겠다는거다. 브랜치로 switch하고나서 수정한 코드는 앞으로 이 branch에서 작업한 내용이 된다.
바꾸면
bash쓰고있는데 저렇게 커맨드 입력창 오른쪽에 현재 브랜치를 표시해준다.
switch로 makeFuncs브랜치로 옮겼으니 현재는 makeFuncs라는 브랜치다.
그리고 코드를 함수로 감싸려던 작업을 코드에서 해주자
암튼 함수로 다 감쌌다.
그리고 add, commit
git add .
git commit -m 'finish from makeFuncs'
이렇게 커밋을 해주자
뭐가 바꼈는지 대충 정리해줌.
그럼 아까 git graph가 main branch에서 first commit밖에 없었는데,
이렇게 커밋이 생겼다.
# main브랜치로 다시 돌아가볼까?
git switch main
어라? 열심히 함수로 감싸놓은게 ㅅㅂ 없어졌노
다시 그럼 makeFuncs 브랜치로 돌아가보면?
엥? 다시생겼네?
그림으로 보면 이렇다.
main branch에서 처음 콘솔로만 되어있는 코드를 쳐놓고 commit을 해놨다. 즉 main브랜치에 switch인 상태에서는 저 최종 commit한 first commit의 코드가 보이는것.
반대로 아까 makeFuncs 브랜치를 만들고 makeFuncs브랜치로 switch후 함수형 코드로 바꿨다. 그리고 finish commit을 해줬다. 때문에 makeFuncs브랜치에서는 코드가 함수형으로 바꾼 상태의 코드가 보이는것이다.
switch로 이동을 하면서 코드를 별개로 관리할 수 있는것이다.
바꾼 코드가 너무 맘에드는데? - merge
한 2년전에 멍청한짓중 하나가 branch개념이 잘 안잡혀서 switch로 브랜치를 옮긴 후, 계속 그 브랜치에서 코딩을 했었다.
그런데 main브랜치로 해야하는 작업이 있어서 switch를 하고 나니까 코드가 다 없어져서 울뻔한적있음.
이러한 사태를 방지하기위해 merge를 해줘야한다.
두 브랜치를 합치는 작업인데, merge는 반드시 부모 branch에서 해줘야한다.
main브랜치에서 MakeFunc브랜치를 생성했었다.
즉 부모브랜치는 main브랜치다
git switch main
이렇게 main브랜치로 옮겨주자.
git merge <합칠 브랜치 이름>
이제 합칠 브랜치를 merge하는 명령어로 적어주자.
git merge makeFuncs
뭔가 코드가 추가되고 빠진게 떴다.
이제 main브랜치에서 makeFuncs에서 수정했던 사항이 반영된걸 볼 수 있다.
즉 main 브랜치의 최종 commit내용과, makeFuncs브랜치의 최종 commit내용이 같아졌다는 얘기임.
그림은 이렇다.
main브랜치에서 makeFuncs브랜치를 merge한 후, 이제부터 두 branch는 함수형으로 바뀐 저 코드 상태를 시작점으로 다시 시작한다. 즉 두 브랜치의 코드가 걍 일치하게 된다는거임.
다만 나도 헷갈렸던건데 merge를 한다고 해서 자식 branch가 없어지는게 아니다. commit한 상태의 코드가 같다는거지 또다시 makeFunc브랜치에서 코드 다시 수정하고 commit하면 두 브랜치의 코드는 서로 다른 상태가 된다.
git branch -v
merge 후에도 makeFuncs브랜치는 여전히 남아있다. 최종 commit을 보면 둘 다 같은걸 볼 수있음.
즉 같은 commit상태에서 다시시작한다는 거임.
이런 상황은 어떨까?
이렇게 각 브랜치가 merge한 후 같은 코드인 상태에서 시작한다.
main 브랜치는 user.js코드를 수정하고 commit,
makeFuncs브랜치는 error.js코드를 수정하고 commit한다.
그리고 두 브랜치를 merge해주면 어떨까?
먼저 main브랜치에서 code freom main이라는 코드를 user.js에 추가해줬다.
add, commit해주자
이제 makeFuncs브랜치로 가서 error.js를 수정해줬다.
git switch makeFuncs
commit하샘
이제 main브랜치로 돌아와서 makeFuncs브랜치를 merge해주자
git merge makeFuncs
뭐 그냥 잘된거같다.
근데? git graph가 좀 달라졌음.
마우스를 올려보면
저 노란색 줄나온거 마우스올리면 브랜치가 makeFuncs라는곳에서 commit했다는게 잘 뜬다.
즉 두 브랜치에서 각각 commit했을떄 merge하면 저렇게 깃그래프가 이쁘게 갈라지는게 표현된다.
# 그럼 아까는 왜 그래프가 안갈라졌던거야?
아까는 main브랜치에서 commit을 한 상태에서 makeFuncs 브랜치를를 만들어줬다.
그리고 makeFuncs브랜치에서 코드를 수정한 후, main브랜치에서 merge를 한것이기 때문에 커밋 그래프를 그냥 합쳐준거임.
근데 이번에선 각 브랜치에서 commit이 있으니 두 커밋을 합쳐야하기때문에 저렇게 그래프가 갈라진거다.
한 파일을 두 브랜치가 수정 후, merge - conflict
이제 board.js를 두 브랜치에서 수정을 할거다.
일단 main브랜치에서
main에서 code from main이라는 코드 넣고 commit
makeFuncs브랜치에서 code from makeFuncs 코드 넣고 commit
이제 main 브랜치에서 makeFuncs브랜치를 merge해보면?
어라 뭔가 빨갛다
코드도 못나게 변했다.
바로 충돌이 난것이다.
깃은 한 파일을 기준으로 두 브랜치가 서로 다른 수정을 하였는데 merge를 할경우 이렇게 충돌이 난다.
여기서 중요한점은 한 파일 기준이라는거다.
아까도 두 브랜치에서 각각 코드를 수정하고 commit을 한 상태에서 merge를 했는데 충돌이 안난 이유는 각브랜치가 user.js랑 error.js파일을 각각 건들였기 때문이다.
# 충돌을 해결해보자.
이코드에서 맘에드는걸 빼고 지우고 해보자.
이번에도 둘다 맘에들어서 두개 다 남겨줬다.
그리고 add와 commit을 해주면?
잘 commit이 됐다.
중요한건 바로 깃 그래프다.
나도 사실 그래프는 잘 볼줄모르는데 뭔가 문제가 생겼다가 해결된것같은 느낌임.
참고로 git add를 했을떄
이렇게 merging한상태라는걸 표현해준다.
이전 step1포스팅에서도 충돌이 났었는데, 그 경우는 서로 다른 디렉토리에서 한 레포지토리를 참조하였기 때문이다. 거기선 github레포지토리를 기준으로 같은 파일을 서로 다른 로컬 디렉토리에서 각각 수정을 하고 push와 pull을 해대서 충돌이 난것임.
그냥 각 디렉토리가 각각의 브랜치라고 생각해도 된다.
사실 혼자서 코딩을 할떄는, 여러개의 브랜치를 병렬로 할 필요없이 현재 기능개발중인 브랜치 다 끝나면 merge하고 해줘서 충돌날일이 거의 없을것같다. 하지만 협업을 할 시에는 이런 경우가 발생하겠지?
이번 포스팅에서는 개인이 깃을 사용할때 작업을 분리하는 방법으로 branch를 사용한거라 협업시에 브랜치는 다음 포스팅에서 다룰것이다.
github에 서로다른 branch로 push를 한다면 어떻게될까?
git push <remote이름> <branch이름>
저기 branch이름을 이전 포스팅에선 main으로 했었다.
이젠 브랜치가 두개니까 각각 다르게 해서 push 해보자.
먼저 main에서 push했다.
이제 makeFuncs에서 push했다.
깃헙을 가보면?
잘 push된걸 확인 가능한데..
branch를 공부하는 입장에서 저기 누르고 싶어진 버튼이 있다.
눌러보니 내가 만든 makeFuncs브랜치도 잘 등록이 되었다.
난 두 코드를 merging해서 conflict를 해결한 상태에서 push한거라 두 코드상태가 같지만, 만약 서로 다른 commit상태에서 각각 다른 branch로 push하면 깃허브 코드도 변한다.
또 어떻게 활용합니까?
이건 꿀팁이라고 하기 그런데, 최근데 git을 취직목적으로 공부를 하고 나서, 코딩할때마다 연습겸 써보기로 했다.
코딩애플로 type script를 공부했었는데, 저렇게 몇강, 몇강 등을 공부할때마다 git branch를 만들어주고 생성해서 옮기고 해줬다.
그래서 switch로 branch를 옮기면 해당 강의내용에서 짰었던 코드들상태로 go.ts파일이 바뀐다.
예전에 어떤 코딩강의를 봤을떄는 강의 챕터별로 파일과 디렉토리를 만들어서 관리하는데, 이렇게 브랜치를 만들어서 관리하는것도 나쁘지 않은 방법같다. github에 push할때 귀찮긴 하겠지만..
암튼 뭐 이런식으로 활용해봤음.
나도 최근에 배운 git branch라서 잘은 모른다.
++ branch 작명
gpt한테 물어봤는데 저런식으로 한단다.
이번 포스팅에 예시로 사용했던 함수로 바꾸는건 예를들어 feature로 해도될듯?
만약 협업시에 활용할거면, 어떤 엔지니어가 했는지 이런걸 넣을수도 있다고 함.
Conclusion
브랜치는 사실 남자답게 코딩하는 나로써는 좀 귀찮긴 할것같은데 체계적으로 코딩하기에는 좋을것같다.
이번 포스팅에서 중요한 내용을 정리하면 이렇다.
1. 브랜치는 부모브랜치에서 만들 수 있다. 이번 포스팅에선 main-makeFuncs브랜치 두개의 관계로만 포스팅 했지만 main에서 생성한 makeFuncs브랜치로 switch한 후, makeFuncs브랜치에서 또 다른 자식 branch를 만들 수 있음. 즉 브랜치로 더 작은 하위작업들을 분리 가능하다는거임. 브랜치의 부모와 자식관계를 꼭 알고 있어야한다.
2. merge시에 같은 commit상태에서 시작한다는 점.
3. 충돌이 나는 경우는 두 브랜치의 commit이 같은 파일을 수정했을 경우이다.
4. 충돌 해결하는법