프로그래밍/개발일지

깃과 깃허브에 대해 배워보자.

구소장 2022. 10. 27. 11:22
728x90

개발자로서 협업하기 위해 필수적인 깃과 깃 허브. 우테코 사전교육에서 나오는 과제는 모두 깃허브를 통해 제출하기 때문에 여기에 대해 공부하지 않을 수가 없었다 (깃도 모르면서 사전교육에 도전하다니, 겁도 없다..). 유튜브에 올라와 있는 강의를 보면서 공부해보았다. 나는 두개의 강의를 봤는데, 둘다 유료 강의의 일부를 무료로 풀어놓은 것이었다. 두 강의 중 나는 얄팍한 코딩사전 (이하 얄코) 이라는 채널을 보고 공부했는데, 두시간 남짓의 강의로 깃과 깃허브의 개념, 각종 설정, 커밋하기, 브랜치, 깃헙에 대해 가르쳐 주는 강의(무료 강의 링크는 여기, 유료강의는 여기)였다. 

 

 

강의시간은 두시간 반 가까이 되는데, 강의자의 설명을 이해하고, 필기하고, 정리하고, 따라해보는데 그 두배 정도는 시간이 소요된것 같다. 물론 굳이 필기할 필요는 없겠지만, 나중에 기억이 가물가물할 때를 위해서 기록이 꼭 필요한 것 같기는 하다. 아마 내가 다시 혼자 해보려면 막막할 것 같은데, 그런 시간까지 포함한다면 '깃'을 익히는데 걸리는 시간은 뭐 무한대가 되겠지.. 뭐 아무튼 익히고 한번 해보는데 나같은 경우는 8시간 정도 걸린 것 같다. 처음 깃을 공부하시는 분들은 참고하면 좋을 듯 합니다:)

 

일단 무료강의부분을 배우고 활용해 본 다음 나중에 필요한 기능을 구글링 하거나, 위 강좌의 유료강의를 듣는 방식으로 학습하면 될 것 같다. 

 

깃의 각종 기능에 대한 코드는 이곳에서 확인.

 

아래 내용은 무료강의파트를 요약 정리한 내용으로, 나중에 내가 필요할 때 찾아보려는 용도로 이곳에 남겨놓는다. 

 

깃이란?

Git은 VCS (Version Control System)의 하나로 프로젝트의 시간과 차원을 관리하는 도구라고 한다. 협업을 하다보면 특정 시점의 무언가를 넣거나, 빼거나, 수정하는 작업이 자주 발생하는데 이러한 작업을 원활하게 하기 위해서 필수적이라 한다. 일반 비즈니스에서 드랍박스나 구글닥스같은 도구도 비슷한 역할을 하는데, 사실 이러한 프로그램은 내가 한 작업을 공유하기는 좋으나, 동시에 작업하기에는 충돌, 중복 과 같은 문제가 있기 때문에 신경을 많이 써야 했는데 그런 점에서 큰 차이가 있는듯 하다. 

 

깃 설치 관련

이 수업에서는 Git, Git bash (Linux 기반 Terminal), Sourcetree를 사용하였다. Git bash 는 CLI (Command Line Interface)의 하나로, 예전에 도스 사용할 때 검은 화면에 텍스트 쳐 넣는 그런 종류의 프로그램인데 윈도우나 맥에도 자체 terminal 이 있지만 왠만한 프로그램은 다 리눅스 기반으로 돌아가기 때문에 리눅스 기반 terminal인 Git bash 를 사용할 것을 추천하였다. 이에 대응되는 GUI (Graphic User Interface) 라는 것 (프로그램..?) 이 있는데, 텍스트 기반인 CLI 와는 달리 GUI는 이름에서 느껴지듯 우리에게 익숙한 (위도우 창과 같은) 화면으로 되어 있어서 친숙했다. 다만, CLI는 모든 명령어를 구현할 수 있는 반면 GUI는 이 중 일부를 그래픽으로 구현한 것이기 때문에 CLI로 기초를 다지며 GUI에 익숙해질 것을 추천하였다. Sourcetree 는 이러한 GUI 중 하나다. 

 

처음 시작할 때 설정할 것이 여러가지 있었는데, 

- 내 컴퓨터에서 Git의 이름, 연락처를 설정

- 기본 브랜치 명을 설정 (default는 master)

- 원하는 폴더를 깃에 연결시키기

- 특정 파일을 깃에 연결하지 못하게 하기 (불필요하거나, 보안상의 이유로 엑세스가 안되도록 함 - 깃이 기본적으로 프로젝트를 공유하는 데 많이 쓰이기 때문)

 

깃의 기본적인 개념/작동원리

깃이라는 것은 일종의 타임캡슐을 만드는 것이라고 이해하면 편하다고 한다. 내가 특정 프로젝트를 만들고/수정하고, 그것을 타임캡슐에 집어넣는 과정을 구현하는 것인데, 내가 특정시점에 넣어둔 타임캡슐을 꺼내서 원하는 내용을 변경하여 그것을 현재의 세상에 반영시키는 것이다. 그래서 이를 version이라고도 설명할 수 있을 것 같다. 여러 시/공간적 버전을 갖고 있다가 필요한 버전을 꺼내서 수정하고 반영하는 과정을 깃을 통해서 수월하게 할 수 있겠다. 

 

- Working directory (타임캡슐에 넣을 파일을 만드는 영역) : 파일을 만들고/수정하고 저장하기

- Staging area (타임캡슐에 넣기 위해 working directory의 파일을 등록(?) 하는 영역): 위에서 저장한 파일을 add하기

- Git directory (타임캡슐에 집어넣기): 위에서 등록한 파일을 commit 하기

 

나는 타임캡슐의 예가 staging area를 설명하기 애매해서 다른 방식으로 이해해보려고 한다. 은행가기

프로젝트를 편지로 비유한다면, working directory 에서 하는 작업은 '편지쓰기' 정도가 될 것 같다. 내가 원하는 편지를 작성하거나 수정하는 것, 편지를 다 썼으면 편지봉투에 내가 적은 편지를 넣어야 한다. 이것이 커밋하기 위한 준비단계 (add), 마지막으로 편지봉투를 우체국으로 들고가서 편지를 발송한다 (commit). 보낸 편지를 다시 가져다가 내용을 수정하는 것은 이 비유에서 적용하기 어렵지만, working directory - staging  - git directory의 절차를 이해하기는 좀 더 쉬운 듯 하여 혼자 그냥 지껄여 보았다. 뭐 은행같은 것에 비유해도 좋을 것 같다. 

 

아무튼 위의 절차대로 생각해본다면, 파일을 생성/수정 하고 그 파일을 내 컴퓨터에 저장 - add 코드를 통해 이를 등록 -  등록한 것을 commit 코드를 통해 Git에 업로드 - 그리고 이것을 Github에 'push'하여 다른사람과 공유. 까지가 한 사이클의 working flow 가 되겠다. 기존에 github에 올렸던 파일을 가지고 작업을 하려면 맨 앞에 해당 commiit 을 github로부터 'pull' 하기부터 시작하면 되겠다. 

 

깃의 기능

무료강의에서 내가 배운 개념/기능은 크게 세가지인데, commit, branch, github 공유하기 정도 이다. 깃의 아주 일부만을 다루었는데, 일단 이것만 알아도 내가 만든 파일을 저장하고 공유할 수 있을 정도는 되서 충분한것 같다. 

 

II. 깃- 기본. 커밋

  1. 변화를 타임캡슐에 담아 묻기
    1. git add tigers.yaml : tigers.yaml파일만 커밋할 준비 하기
    2. git add . : 전체 다 커밋 할 준비 하기
    3. git commit: 커밋하기. 새로 열리는 창에 message를 남기고 저장하면 됨. e.g., FIRST COMMIT
    4. git commit -m “FIRST COMMIT”
      1. 제목까지 붙여서 저장완료
    5. git log: 깃의 커밋 상태 등 확인
    6. git diff : 변경사항을 더 구체적으로 저장
      1. terminal 에서
        1. j: 아래로 스크롤
        2. k: 위로 스크롤
        3. q: 닫기
    7. git commit -am “메시지”
      1. add와 commit을 한번에 하고 메시지도 입력
      2. 다만, 언트랙된 파일이 있을 땐 사용할 수 없음.
  2. 과거로 돌아가는 두가지 방법 (시간여행)
    1. reset: 시간을 과거로 되돌리고 그 이후는 삭제
      1. git reset —hard “commit number”
        1. 이때 commit number는 내가 가고싶은 버전의 no.를 git log를 통해 확인하여 기입.
      2. git reset —hard 뒤에 아무것도 넣지 않으면?
        1. 현재의 타임캡슐로 돌아감?
    2. revert: 원하는 과거 이후의 수정들을 반대되는 내용으로 commit에서 없애는 방식
      1. git revert 뒤에 내가 취소하고싶은 커밋 해쉬 붙이기
        1. revert 는 reset과 다르게 내가 되돌릴 (취소할) 커밋의 해쉬를 찾아야 함.
      2. a를 만들었던 과거를 없애고 싶은데, 만든 후에 a를 수정한 기록이 있다. 그럴 때
        1. git revert a 를 하면 conflict이 발생: 삭제 한 이후에 a관련 자료가 있기 때문,
        2. git add 또는 rm a 이후
          1. git revert —continue를 하면 해당 a를 삭제하고, 그 이후의 기록도 모두 삭제함.
        3. revert 를 했다가, 다시 revert하기 전으로 되돌리고 싶으면, reset 기능을 활용
      3. 커밋 없이 revert 하고싶을 때
        1. git revert —no-commit 원하는 commit number
        2. 해당 내용이 변경은 되는데 커밋은 안됨. 다른 변경사항을 추가해서 함께 커밋하고 싶은 경우 사용.
        3. !!질문: 수정을 했는데, 그 내용을 다시 되돌리고 싶으면 어떻게 해야 함?
          1. git restore —staged 파일이름 : unstaging the file
          2. git restore 파일이름 : discard changes in working directory
      4. 추가했다가 다시 지운 내용 자체도 기록에 남기는 것.
      5. 혹은, 과거 특정시점의 내용만 지우고 싶을 때..
      6. 한번 github을 통해 공유가 된 commit은 reset을 할 수 없고 revert를 해야 충돌을 피할 수 있다.
    3. 위 내용을 SourceTree로 진행해보기

III. Branch - 멀티버스를 넘나들기

  1. 여러 branch (차원) 만들어보기: 특정 시점의 버전을 기준으로 새로운 프로젝트를 만들 때 유용
    1. 프로젝트를 하나 이상의 모습으로 관리해야 할 때 (실배포용, 테스트서버용, 새로운 시도용)
    2. 여러사람이 역할을 분담해서 일할 때
      1. 브랜치를 사용해서 수정 하다가 수정이 끝나면, 메인 브런치에 최종 업뎃
  2. 브랜치 생성
    1. git branch add-coach : add-coach라는 branch 만들기
    2. git branch : branch 목록 보기
    3. git switch add-coach : add-coach로 이동하기
    4. git switch -c new-teams : 브랜치를 생성하고 동시에 이동하기
    5. git branch -m 기존브랜치명 새브랜치명 : 기존브랜치명 을 새브랜치명 으로 이름 바꾸기
    6. git log --all --decorate --oneline --graph
      1. branch 현황 terminal 에서 보기
      2. 하지만 그래픽은 sourcetree에서 확인하는 걸 추천
  3. 브랜치 합치는 두가지 방법
    1. merge vs. rebase
      1. merge: 브랜치 흔적을 남겨 큰 프로젝트에서는 복잡해보일 수 있음. but 기록을 남길 수 있음
      2. rebase: 깔끔.. 하지만 히스토리가 남지 않음
    2. Merge : 커밋을 통해 두 개를 병합
      1. git merge add-coach
      2. main으로 간 후 위 내용을 입력: main에 add-coach를 merge하겠다.
      3. reset으로 merge 하기 전상태로 되돌릴 수 있음.
      4. merge를 한 다음에는 해당 branch (add-coach)를 지워주자!
        1. git brand -d add-coach
    3. Rebase : 만들었던 브랜치를 main브랜치에 이식(?) 하는 것
      1. merge와 다르게 rebase 는 잘라 붙일 (그리고 나서 없어질) 곳으로 이동해서 아래 명령을 실행해야 함.
      2. git rebase main
      3. rebase 후 main으로 이동해서 다시한번 rebase를 merge 해 줘야 함
        1. git merge rebase
        2. 내용은 가져다 붙였지만 ID는 아직 안갖다 붙인 느낌인가?
      4. 다 했으면 삭제
        1. git branch -d new-teams
  4. 충돌해결
    1. git merge —abort
      1. merge 에서 충돌이 발생했을 때 merge 명령을 되돌리기.
    2. 한 브랜치에 두개의 커밋이 있고 각각 conflict이 있을 경우
      1. merge로 합칠경우 한큐에 충돌을 확인하고 고칠 수 있다.
      2. rebase로 할경우 충돌을 따로따로 확인/수정 해야 함.
        1. git rebase —abort (수정을 일일이 할 수 없을 때 rebase 되돌리기)
        2. 수정 했으면
          1. git add .
            1. 수정 한 부분 staging
          2. git rebase —continue
            1. 다음 꺼 오류나면 또 수정
              1. 두번째 꺼 수정 후
                1. git add . 로 또 저장
                2. git rebase —continue
                3. rebase 된 것 확인 후
                4. main 으로 가서
                  1. git merge branch 이름
                  2. 이후 브랜치 지우기
  5. Sourcetree에서 수정하기
    1. merge 충돌해결하기
    2. rebase는 충돌 발생 시 CLI로 진행 권장

IV. Github 

  1. github이란? 코드 공유 및 협업 서비스. 사실 Git 이라는 건 위에서 언급했던 version - 타임캡슐을 다양한 방식으로 기록하는 용도이고, Github을 통해서 해당 버전들을 다른사람과 공유하고 함께 작업할 수 있는 것이다. 그래서 이부분까지는 알아야 (내생각에는) 최소한의 것을 배웠다고 할 수 있을 것 같다. 
  2. Github 시작하기
  3. 원격 저장소 사용하기
    1. 깃헙에서 명령어 복붙하기
      1. git remote add origin : 로컬의 git 저장소에 원격 저장소로의 연결 추가
      2. git branch -M main : github 권장 / 기본 브랜치명을 main으로 함
      3. git push -u origin main :
        1. 푸시: 로컬에서 원격으로 업로드
        2. 어느 원격, 어느 브랜치에 할지 정함 (한 로컬에서 여러 원격 리포지토리로 연결할 수 도 있음). 여기서는 default값으로 origin, main 이 설정됨.
          1. 질문. 설정 없이 그때그때 입력하려면 어떻게?
      4. git remote : 어느 원격에 연결했는지 연결
      5. git remove -v : 원격 상세 정보
      6. 원격에서 로컬로 다운받기
        1. 깃헙 리파지토리에서 코드 클릭, 주소 복사, 내컴퓨터 원하는 폴더위치에서 마우스 우클릭, git bash 열기
          1. git clone 뒤에 주소붙여넣기
    2. Push: git push
    3. pull: git pull
    4. Conflict 발생하는 경우
      1. 내 로컬에서 커밋을 했지만, 원격에 동료가 변경사항을 이미 push 한 경우 - 내 로컬이 outdated
        1. git pull —no-rebase : 내가 만든 커밋을 branch로 만들어서 수정 후 다시 합침.
        2. git pull —rebase: 내 로컬 커밋을 원격에 붙임.
          1. 그 다음에 git push로 원격에 올려줌.
    5. Conflict1: 같은 위치에 다른 내용이 각각 들어가서 충돌이 일어날때
      1. git pull —no-rebase : merge 방식으로 정리
      2. git pull —rebase : rebase 방식으로 branch 내용을 main에 갖다 붙임.
        1. 수정 후 git add .
        2. git commit -m ‘message’
        3. git push 로 github업로드까지 완료하기
    6. conflict2
      1. 로컬 (내컴퓨터)에 있는 내용이 outdated 되었지만, 원격에 있는 내용이 잘못되어 로컬 내용을 강제로 push 해야 하는 경우 - 보통 협업때는 잘 쓰이지 않고, 협업자의 동의가 필요함.
      2. 로컬의 내역 충돌 전으로: reset
      3. git push —force : 원격에 강제적용
  4. 원격 브랜치 다루기
    1. 로컬에 브랜치 만들고, 이를 푸시해보기
      1. git push
        1. 오류발생. 예전에 default push 값은 main - origin 으로 설정됐기 때문
        2. git push —set-upstream origin from-local
        3. git -u origin from-local
          1. 둘다 사용가능
          2. origin 과 from-local 폴더를 연결
        4. terminal 에서 local 과 remote의 브랜치를 모두 살펴보기
          1. git branch -a
          2. git branch —all
    2. 원격에서 브랜치 만들고 로컬로 가져오기
      1. git fetch : 복사하기
    3. 원격과 로컬의 브랜치를 연결하기
      1. git switch -t origin/from-remote
        1. 로컬로 from-remote란 브랜드를 복사하고 이후로 로컬의 from-remote를 원격의 from-remote와 연결한다!
    4. branch 만든거 삭제하기
      1. local branch
        1. git branch -d branch이름
      2. remote branch
        1. git push 원격이름 -d branch이름