10월 12일 화요일 TIL

김병훈·2021년 10월 12일
0

til

목록 보기
83/89

1. github desktop download

  • github desktop의 활용
    • Local repo, Remote repo 간의 동기화를 위해 간단히 사용
    • Pull, modification and Push
    • Commit의 수정, Branch의 세세한 조정 등은 실제 개발자가 수행할 필요가 거의 없음
      • 프로젝트 매니저, Repo 및 코드 관리자가 수행한다
    • 많은 IDE에서 github desktop을 대체할 수 있는 github 연동 기능을 제공하고 있어서, 그러한 경우에는 아예 불필요하다.
      • vscode, eclipse등 널리 사용되는 IDE는 거의 모두 지원한다.
      • 차후 배우게 될 source insight는 지원하지 않는다.
      • 이러한 경우, source code directory를 git repo로 설정해두고, source insight(혹은 다른 에디터)로 수정하고, github desktop으로 push한다.

2. Git Branch 관리

목표: 브랜치를 갈라서 두개로 만들고 , 브랜치사이에서 왔다갔다하면서 내용확인
, 브랜치 두개를 다시 merge하면서 충돌관리.

Branch

VCS의 한계

  • 충돌이 나는 파일은 수동으로 해결할 수 밖에 없다.
  • 따라서 최대한 분리하여 작업하도록 구성
    • 단위: 함수, 클래스, 파일, 폴더, 기능 등
  • 그러나 협업 구조에서 동시 작업의 필요성은 여전히 존재한다.
    • 기능 추가 팀, 버그 수정 팀이 동시에 작업

Branch

  • 같은 코드를 공유하되, 작업을 독립적으로 분리해서 수행할 수 있다.
    • 독립적인 개발 및 테스팅, 커밋 이력 관리, 저장소 관리
    • Git은 가볍고 빠른 브랜치 동작을 제공한다.
  • 분리는 쉽지만, 나중에 다시 합칠 때에는?
    • Merge 담당 전문가, 테스트 과정이 필요하다.
    • 돌려야할 프로그램은 하나이기 때문에 브랜치가 많아도 결국 하나로 합쳐야함

Branch 이용 예

  • 예를 들어서 브랜치를 이용해서 이력을 관리하는데도 사용할 수 있다.
      1. 릴리즈 버전마다 따로 커밋을 하면서 진행을 하는 브랜치가 있고, 이 브랜치는 각 커밋들이 각각 하나의 버전이 되는 것이다. 예를 들어 오피스 같은 것도 년도별로 따로 나오듯이, 그때 마다 커밋을 만들어주는 브랜치가 있다.
      1. 좀 더 상세하게 기능이 추가 될 때마다 따로따로 커밋을 남겨서 히스토리를 남겨 놓는 브랜치가 되는 것이다. 이것은 코드를 관리하기 위해서 기능들이 어떻게 추가되어 왔는지를 추적하기 위해서 만드는 브랜치이다. 마찬가지로 버그수정이력도 남겨놓을수 있다.
  • 그리고 앞에 말했듯이, 작업을 위해서 현재 이 커밋 상태에서 기능 추가 팀은 커밋 상태를 그대로 가져와서 새로 브랜치를 만든 다음에 어떤 기능을 추가하고 있다고 가정.
    또한 버그 수정팀도 같은 브랜치를 가져다가 자기가 작업해야할 부분에서 버그수정을 하고 끝난 다음에 기존 브랜치와 통합을 하였다고 가정.
  • 다른 팀들이 아직까지 통합을 안한 상태이기 때문에 충돌 발생은 하지 않음
  • 사이드바를 추가하는 팀도 존재한다.
  • 이렇게 각자가 맡은 영역이 다르기 때문에 충돌이 일어나지 않고 서로가 따로따로 작업을 한 다음에 하나의 줄기로 잘 합쳐지는 구도이다.
    • 만약에 각각의 팀이 수정한 내용들이 부딪힌다면?
      • merge를 진행할 때 충돌 관리를 해야한다.
      • 충돌들이 관리가 된 후에 하나로 merge가 되고 다시한번 완전한 버전이 만들어진다.
  • 이런식으로 브랜치를 따서 새로 만든 다음에 작업하고 다시 원래 브랜치로 합치는 방법을 사용한다.

Branch 생성 및 HEAD의 이동

  • 브랜치를 생성 하고 브랜치의 HEAD를 이동해 나가는 내용
  • 명령어를 이해해야한다.
    • git bash에서 진행할 필요는 없고, desktop에서 진행

$ git branch testing

  • 새로운 브랜치를 생성할때에는 위의 명령어 입력, 주의할 점은 브랜치가 생성이 된다고 해서 현재 작업하고 있는 HEAD라는 포인터는 움직이지 않는다.
  • HEAD의 위치는 변경되지 않음

$ git checkout testing

  • HEAD의 위치를 변경
  • 작업 브랜치가 변경된다. 이후 커밋은 해당 브랜치에 추가된다.
  • 그래서 첫번째 명령어로 브랜치를 만든다음에 checkout 명령을 줘서 원하는 브랜치를 불러서 HEAD의 위치를 입력한 브랜치로 옮길 수 있다.

Github Desktop에서 브랜치 생성


브랜치 생성


생성 후 자동으로 적용되었다.

testing 브랜치에서 파일 수정 후 main으로 브랜치를 변경하였을 때


testing 브랜치로 변경된 상태에서 text.txt 파일을 수정해주고 github desktop에서 commit을 넣었다.


우측에 있는 Publish branch를 누르면 push가 될 것이다.


하지만 main으로 브랜치를 다시 변경하였을 때는? github desktop에서 브랜치를 변경하는 것은 vscode에서 $ git checkout branchName 명령을 수행하는 것과 동일하다.


커밋이 안되어 있는 브랜치라서 @testing 내용이 없다.

$ git log --oneline --decorate --graph --all

  • git log을 그래프로 보여주는 명령어
  • initial commitCreate test를 했던 커밋이 두 개가 있고,
  • 이 상태에서 그림이 두 개로 갈라지면서, testing 에서 만들어진 커밋과 main에서 만들어진 커밋이 분리된걸 볼 수 있다.

Branch: Merge

  • $ git checkout master/main (토대가 되는 브랜치로 HEAD를 옮겨줘야한다)
  • $ git merge 합칠branchName
  • 앞에서 main과 testing 두 개의 브랜치로 나눈 다음에 각각 커밋을 해서 서로 다른 내용으로 편집을 하였다.
  • 이렇게 갈라진 브랜치를 하나로 다시 합치는 동작이 Merge 이다.
  • merge를 할 때는 두 가지 옵션이 존재한다.
    • Fast-forward merge
      • 우연히도 이렇게 브랜치를 따서 진행을 했는데, 기존 브랜치에서 아무런 일도 일어나지 않은 상태. 그러면 y라는 커밋 상태에서 기존 커밋과 합칠려고하는데 분리된 부분이 없어서 master브랜치가 계속 이어서 진행된 것처럼 변경을 하는 것을 뜻한다.
      • 이거는 고민 되는 내용이없어서 서로 충돌이 일어날 수 가 없다.( 더 진행된 내용이 없기 때문)
      • 그래서 그냥 master branch로 병합 시켜버리면 됨.
      • 충돌이 없어서 좋긴하지만, 거의 일어나지 않음 하지만 병합 실행 시 , fast-forward merge가 가능한 경우라도, non-fast-forward merge 를 하여 브랜치를 남겨서 해당 브랜치로 실행한 작업 확인 및 브랜치 관리 면에서 더 유용할 수 있다.
    • Three-way merge
      • 일반적으로 말하는 merge를 의미한다.
      • 브랜치 줄기가 갈라진 상태에서 master, bugfix부분 그리고 이 두 갈래가 갈라질 때 커밋상태 세 가지를 한꺼번에 비교를 해서 서로 다른 부분을 검사해야한다.
      • 세 가지 상태의 달라진 점들이 정리가 되어야지 merge된 커밋을 만들어낼 수 있다.

Branch: rebase

  • merge 와는 다르지만, 비슷하게 브랜치를 통합하는 명령이다.
  • rebase 라는 이름은 , base가 되는 커밋을 바꾸겠다는 뜻이다.
    • 예를 들어 bugfix branch의 최초 커밋xmaster branch의 최종 커밋으로 rebase 를 함으로써 마치 이어서 진행된 일인 것처럼 이력을 변경해버리는 것이다. 이게 커밋 이력까지 바꾸어버린다. 그래서 최종상태에서 볼 때 bugfix라는 브랜치는 만들어졌지만, x,y 커밋이 마치 master를 기반으로해서 게속 진행된 것 처럼 보이게 된다.
    • 이 경우에도 충돌은 생길 수 있다. d를 기반으로 해서 x로 가기 때문에, 만약에 d와 x가 부딪히는 경우가 생기면 관리를 해줘야한다. 그래서 x'가 나온다. 사실 x는 d를 기반으로 한 것이 아니기 때문.
    • 정확하게는 b와 d사이에 달라진 부분이 x'로 반영이 되어야 한다.

merge와 rebase의 차이점

  • merge
    • 변경 내용의 이력이 모두 그대로 남아 있기 때문에 이력이 복잡해진다.
      • 그렇지만 이력을 남기는 원래 의미가 작업을 한 내용 (커밋을 한 내용) 들이 어떻게 수행되어 왔는 가를 보려고 하는 것이기 때문에 이력이 복잡해진다고해서 단점이 되지는 않는다.
  • rebase
    • 이력은 단순해지지만, 원래의 커밋 이력이 변경된다.
      정확한 이력을 남겨야 할 필요가 있을 경우에는 사용하면 안된다.
    • Local repo에서 브랜치를 만들어 작업하다가 push를 해야 하는 경우, 굳이 브랜치의 흔적을 남길 필요가 없는 경우가 많다.
      • rebase는 이력이 단순해진다는 장점이 있지만, 그런데 원래 커밋 이력이 변경이 되기 때문에 정확하게 어떻게 작업이 이루어졌다라는 이력을 남겨야할 필요가 있을 때는 사용해서는 안된다.
      • rebase를 사용하는 실제적인 상황은 많지 않다.
      • 예를 들어 커밋들을 만들면서 작업을 했는데 다시 되돌아서 보니까 굳이 각각의 작업들이 큰 의미가 있지않아서 그냥 커밋이 하나만 있어도 되겠다 괜히 복잡해지기만하고 불편하겠다 하면 여러 커밋들을 하나로 합칠 수 있다. (유일한 경우)
      • Local repo에서 혼자 브랜치를 만들어서 작업하다가 push해야되는 경우에 굳이 브랜치를 남겨야할까? 라는 경우가 생길 수 있다. 그런 경우에는 rebase를 통해서 master로 옮겨가는 것도 괜찮다.

Branch: 충돌관리 -three-way merge 실습

git bash에서 commit checkout 후 확인

  • main을 토대로 merge 시도.

  • 충돌 발생 에러

  • 충돌 상황
  • in VSCode

  • 충돌 수정 후

  • 수정된 내용 push 하면 merge끝

  • $ git log --oneline --decorate --graph --all 명령어로 통해 merge 된 것 확인.

Branch: 기타

  • $ git branch --d "branch name"
    • Delete: 작업 중인 branch는 삭제 불가.
      먼저 다른 branch로 HEAD를 옮기고 (checkout) 수행
  • $ git branch
    • 현재 브랜치 확인
  • $ git show-branch
    • 브랜치 확인

rebase를 이용한 commit 정리

많이 발생하는 상황

  • local에서 작업 중 여러 Commit이 발생하였으나, remote repo에는 하나의 commit으로 통합해서 push하려는 경우
    • 여러 커밋들을 여러 일을 한 것처럼 remote에 할 필요없는 경우
  • rebase : 여러 commit을 하나로 merge
  • $ git rebase -i HEAD~3
    • HEAD에서부터 최근 3개의 커밋을 표시하며, (HEAD포함)
      vi를 기반으로 interactive하게 commit을 수정, 통합한다.
    • ex) 메모장으로 변경하려면, $ git config --global core.editor notepad
  • Squash(s)를 입력하면 Git은 해당 커밋과 바로 이전 커밋을 합치고 커밋 메시지도 Merge한다.
  • 저장하고 나서 편집기를 종료하면, Git은 3개의 커밋 메시지를 Merge할 수 있도록 에디터를 바로 실행해준다.

    $ git rebase -i HEAD~3

  • 2,3을 update #1로 rebase
    • Squash(s)를 입력하면 Git은 해당 커밋과 바로 이전 커밋을 합치고 커밋 메시지도 Merge한다.


  • commit message 수정 후 :wq


  • 결과

만약 rebase하다가 실수하면?

  • $ git rebase --edit-todo
    • 계속해서 중단된 작업 수행
  • $ git rebase --abort
    • Rebase 중단 및 원상복귀
profile
블록체인 개발자의 꿈을 위하여

0개의 댓글