1. Git에 대하여

 

1-1. git이란?

  - vcs(version control system) 프로그램 중 하나

  - 즉 버전을 관리하는 시스템

  - 여기서 버전관리란 크게 두가지로 나눠서 code의 "시간"과 "차원"을 관리하는 느낌으로 받아들이면 됨

  - 비유적으로 표현하면 깃은 타임캡슐이라고 할 수 있음, 안에 코드를 넣고 묻어두는 것

  - 파일의 변경내역을 계속 추적할 수 있으므로 현재의 상태뿐 아니라 프로젝트의 전체 이력을 가질 수 있게 됨

 

1-2. git을 쓰는 이유

  1) 개인으로서의 이유

  - 변경 취소 기능 : 실수했을 때 구버전 파일을 복구해서 이전단계로 돌아갈 수 있음

  - 모든 변경에 대한 이력 : 하루, 일주일, 일년이든 언제든 구버전의 프로젝트를 정확히 확인할 수 있음

  - 변경한 이유 기록 : 왜 변경했는지 기억할 수 없을때가 있는데 커밋메시지를 이용해 변경한 이유를 기록할 수 있음

  - 변경에 대한 확신을 가질 수 있음(실수하면 되돌리면 되므로)

  - 여러갈래의 히스토리 : 브랜치를 만들어서 변경내용을 실험하거나 기능을 독립적으로 실험할 수 있고

                                        완료되면 마스터브랜치를 만들어 병합하거나 브랜치들을 삭제할 수 있음.

  2) 팀으로서의 이유

    - 충돌 해결 능력 : 여러 사람이 동시에 같은 파일을 작업할 수 있음.

    - 독립적인 히스토리 : 여러사람들이 다른 브랜치에서 작업이 가능하므로 독립적으로 개발하고 완료되면 병합할 수 있음

 

1-3. git 사용 환경

  - CLI(Command Line Interface) : 도스창처럼 검은 화면에 텍스트 쓰는 방식, 주로 Git Bash

  - GUI(Graphic User Interface) : 일반인들이 쓰기 쉬운 그래픽 환경, 주로 SourceTree

  - 보통 git 명령어를 그때그때 사용할때는 terminal에서 CLI방식으로 간단히 빠르게 처리하고, 프로젝트 전체를 자세히 살펴볼땐 GUI방식으로 보기 쉽게 사용

  - 즉 한쪽만 쓴다기보다는 상황에 따라 병행해서 사용한다

 

1-4. .gitignore

  - 깃의 블랙리스트 같은 것

  - 깃이 해당 파일들은 관리하지 않게 등록해두는 곳

  - 어떨때 깃이 파일을 관리하지 않게 하는가?

    1) 깃이 관리할 필요가 없을 경우(자동생성되는 중간파일이라던가, 쉽게 인터넷에서 구할 수 있는 라이브러리 같은 것)

    2) 깃이 관리하면 안되는 경우(보안상 중요한 정보를 담은 파일 같은 것, 계정 비밀번호같은게 적혀있는 xml파일처럼)

 

  - .gitignore 작성법   
    https://git-scm.com/docs/gitignore에 자세히 나와있지만 주로 쓰는 간단한 것들은 아래와 같이 사용

    #으로 주석처리

# 모든 file.c
file.c

# 최상위 폴더의 file.c
/file.c

# 모든 .c 확장자 파일
*.c

# .c 확장자지만 무시하지 않을 파일
!not_ignore_this.c

# logs란 이름의 파일 또는 폴더와 그 내용들
logs

# logs란 이름의 폴더와 그 내용들
logs/

# logs 폴더 바로 안의 debug.log와 .c 파일들
logs/debug.log
logs/*.c

# logs 폴더 바로 안, 또는 그 안의 다른 폴더(들) 안의 debug.log
logs/**/debug.log​

 

1-5. 주요 개념

  1) commit : 파일에 변경 내용을 저장할 때마다 새로운 commit을 생성함

    - commit 메시지 : 왜 변경했는지에 대한 메시지를 기록

  2) 브랜치 : 테스트나 새로운 기능개발을 위해 따로 떨어진 독립적인 commit

    - 마스터브랜치 : 새로운 git프로젝트를 만들떄마다 master라고 불리는 기본브랜치가 생성됨. 모든 프로젝트가 끝나고 배포할 준비가 되면 최종적으로 마무리되는 브랜치

    - 피처 브랜치(토픽 브랜치) : 새로운 기능을 개발할때 만드는 브랜치

    - 릴리즈 브랜치 : 직접 QA(품질보증)작업을 하거나 고객의 요구를 지원해야 할 때 수정이나 업데이트를 위한 장소로 릴리즈 브랜치가 필요

    - 위에서 사실상 피처브랜치나 릴리즈브랜치는 같은 개념이지만 말할때 구분을 위해 이름을 나눔

  3) 병합 : 한 브랜치에서 완성된 작업을 가져와서 다른 브랜치에 포함하는 것. 흔히 피처브랜치를 마스터브랜치로 병합

  4) 태그 : 어떤 버전의 코드가 언제 배포되었는지 제품 배포 기록에 사용

  5) 체크아웃 : 프로젝트 history의 다른 버전으로 이동해 해당 시점의 파일을 보기 위한 것(일반적으로 브랜치에서 완료된 작업을 보기 위해 브랜치를 체크아웃)

  6) Pull request : 개발 가능한 기능에 대한 논의를 시작하는 초기작업단계에서 사용

  7) Issue : 기능에 대해 논의하거나 버그를 추적하는 기능

  8) wiki : 링크들간을 연결해 간단히 웹페이지를 만드는 방법

  9) 복제(Cloen) : 로컬에서 작업하기 위해 프로젝트 복사본을 GitHub에서 다운로드하는데 리포지토리를 로컬컴퓨터로 복사하는 과정을 복제라고 함

  10) Fork : 프로젝트를 직접 변경할 권한을 갖지 못했을 때 그러한 프로젝트를 자신의 계정으로 복사해와야 하는데 그 과정을 리포지토리를 fork한다고 함, 그 후 복제하고 변경하고 pull reauest를 이용해 원본 프로젝트에 변경 내용을 반영할 수 있음

 

 

 

2. Git으로 코드 관리하기

 

2-1. git status

  - 코드를 작성 및 수정했지만 아직 커밋하지 않은, 즉 깃에 의해 관리되고 있지 않거나 변경된 것들을 확인할 수 있음

  - git status를 입력하면 어떤 파일들이 관리 되고 있지 않다고 리스트가 뜸

 

2-2. git add

  - git이라는 타임캡슐에 파일을 넣는게 add

  - 주로 git add .  으로 모두 add하는 방식을 많이 씀

  - git add main.c 처럼 직접적으로 파일명 작성도 가능

 

2-3. git commit

  - 타임캡슐을 땅에 묻는게 commit

  - 주로 git commit -m "커밋메시지" 처럼 사용

 

2-4. 코드 작성 및 수정을 했다면?

  - 주로 코드 작성 및 수정을 하고나서 커밋하고 싶을 때 

  git add . 

  git commit -m "이런 내용 수정 및 작성~~"

  - 위 두줄로 끝나고 만약 새로 추가된 파일이 없는 경우 한정으로만 add와 commit 동시에 가능

  git commit -am "message"

  - 결국 코드 작성중에는 그냥 add commit 두개만 계속 반복한다고 생각하면 됨

 

2-5. git log

  - 커밋된 로그 확인 가능

  - 리눅스 vi환경으로 나와서 j를 눌러서 내려가고, k를 눌러서 올라가고, q를 눌러서 종료할 수 있음

  - 주로 커밋 내역을 보거나 reset이나 revert할때 해시값을 확인하기 위해 사용

 

 

 

3. Git으로 시간여행 하기

 

3-1. git으로 시간되돌리기

  - git에서 과거로 돌아가는 방식은 reset과 revert가 있음

  - 이미 공유가 된 협업하는 상황에서는 reset이 아니라 revert를 써야 함

  - reset은 과거 내용을 다 날려버리지만, revert는 해당 내용만 취소한 캡슐을 새로 추가하는 개념이므로

  1) reset : 말 그대로 시간을 되돌리는 것

               즉 과거 시점의 코드로 되돌아가고, 해당시점부터 현재까지의 모든 히스토리를 다 지워버림

  2) revert : 해당 타임캡슐에서 일어난 일만 되돌림

                만약 첫번째 커밋을 1번, 최근의 커밋을 5번이라고 해서 1, 2, 3, 4, 5번의 타임캡슐이 있을 때

                3, 4, 5번에서의 코드들은 다 문제가 없는데 하필 2번에서 작성했던 코드에 문제가 발생해서

                해당 부분만 되돌리고 싶다면 revert로 2번만 되돌려주면 3, 4, 5번에서의 코드수정은 유지하고 2번만 되돌림

                되돌리는 방식은 추가된 내용은 삭제하고, 삭제한 내용은 추가하고 하는 방식으로 반대의 기능을 수행

 

3-2. git reset

  - reset을 하려면 reset하려는 시점의 타임캡슐의 해쉬값이 필요함

  - 해쉬값은 git log를 사용하면 얻을 수 있고 해쉬값 전체를 사용하거나, 앞의 6글자정도만 사용해도 됨

  - 해쉬값이 이상하게 전체를 쓰면 오류가 뜰때도 있고 잘 될때도 있는데 6글자 쓰면 잘 되는 듯

  - git reset --hard 294e63 처럼 git reset --hard 해쉬값 을 입력하면 됨

  - 만약 해쉬값을 입력하지 않고 git reset --hard 까지만 입력하면 가장 최근의 커밋으로 돌아감

    - 코드 변경들 이것저것 하다가 도저히 아니다 싶어서 바로 직전 커밋으로 되돌릴때 좋을 듯

  - --hard 말고 다른 옵션들도 있으니 나중에 알아보기

 

3-3. git revert

  - 되돌리고 싶은 부분만 딱 되돌릴 수 있음

  - git revert 해쉬값 => 입력하면 vi로 넘어가지고 커밋메시지도 자동작성되니 그냥 :wq하면 됨

  - revert가 잘 되면 되돌리고 나서 저절로 commit까지 해주게 됨

    - 만약 commit을 원하지 않는다면 git revert --no-commit

    - revert뿐 아니라 다른 수정사항을 다 수정한 다음에 타임캡슐에 넣고 싶을 수도 있으므로

  - revert에서의 충돌 해결

    - 만약 어떤 파일을 생성하던 시점으로 revert를 한다면 git은 해당 파일을 삭제하는 방식으로 되돌림

    - 근데 만약 바로 직전 커밋때 해당 파일을 수정하는 내용같은게 있었다면 충돌이 발생하게 됨

    - 충돌이 발생했을때는 branch가 main이 아니라 main : reverting으로 출력됨

    - 이때는 안내에 따라, 개발자의 능력껏 충돌을 해결하고나서 git revert --continue 해주면서 충돌이 없어질때까지 반복

    - 모든 충돌이 해결되고 나면 commit

    - reset은 한방에 되돌려 버리니 continue 할 일 없지만 revert는 만약 1, 2, 3, 4, 5 커밋 중 2번을 revert했을 때

      3번에서도 충돌, 4번에서도 충돌, 5번에서도 충돌 생길 수 있으니 한번에 끝내는게 아니라 continue 하면서 

      여러번 해결해 주는 것

 

 

 

4. SourceTree로 해보기

 

4-1. 지금까지 내용(2~3단원) SourceTree로 하는 법

  - add : 왼쪽아래에 "스테이지로 올리기" 누르면 됨. add는 스테이징의 역할을 함, 타임캡슐로 말하면 타임캡슐에 넣는 것

  - commit : 왼쪽 위에 버튼있음

  - reset : 돌아가고 싶은 커밋 우클릭해서 "이 커밋까지 현재 브랜치를 초기화"

  - revert : 되돌리고 싶은 커밋 우클릭해서 "커밋 되돌리기"

    - revert 충돌해결 : 스테이지에 올라가지지 않은 파일들이 충돌이 발생한 파일

                                  해당 파일 우클릭해서 충돌해결에 "저장소것을 사용하여 해결" 선택 후 커밋메시지 입력하고 커밋

 

 

 

5. Git으로 차원여행 하기

 

5-1. Git에서의 차원은 Branch

  - 3번단원은 reset과 revert로 시간을 관리하는 법이었다면 5단원은 branch로 차원을 관리하는 법

  - 하나의 분기에서 다른 분기를 만들어서 다른 차원에서 작업하는 방식

  - 이게 필요한 이유

    1) 프로젝트를 하나 이상의 모습으로 관리해야 할 때

      ex) 릴리즈용, 테스트용, 새로운 실험할 때

    2) 여러 작업들이 각각 독립되어 진행될 때(여러 사람이 작업할 때)

      ex) 신기능1, 신기능2, 코드개선, 긴급수정 등등

    만약 릴리즈용, 테스트용, 새로운 실험할때 등등을 다 프로젝트 복붙해서 별도로 진행한다면 용량이 3배로 필요

    하지만 브랜치를 사용하면 하나의 프로젝트에서 브랜치만 나눠서 셋 다 가능

 

5-2. git branch

  1) 브랜치 생성 : git branch 이름

    ex) git branch test1

    - 브랜치 생성을 하면 생성만 된거고 아직 main브랜치에 있음

  2) 브랜치 목록 확인 : git branch

    - 생성된 브랜치들의 목록을 확인할 수 있음

    - 만약 github에 있는 원격의 브랜치 목록도 다 확인하려면 git branch -all

  3) 브랜치 이동 : git switch 이름

    - 다른 브랜치로 이동

    - 브랜치 생성과 동시에 이동하려면 git switch -c 이름

  4) 브랜치 삭제 : git branch -d 이름

    - 단 삭제되는 브랜치에 아직 다른 브랜치로 가져오지 않은, 지워질 브랜치에만 있는 내용의 커밋이 있다면 삭제불가

    - 삭제 불가한 상황에서 강제로 삭제하려면 -d가 아닌 -D로 강제삭제 해야 함

  5) 브랜치 이름 변경 : git branch -m 기존이름 새이름

    - 브랜치의 이름 변경

  6) 브랜치의 log

    - 만약 각 브랜치에서 git log를 하면 해당 브랜치에서의 log 내역만 볼 수 있음

    - 여러 브랜치의 모든 내역을 전부 보려면 git log --all --decorate --donline --graph

    - 근데 모든 내역을 다 볼 필요가 있는 경우엔 GUI인 소스트리 사용하게 될 듯

 

 

 

6. 두 차원을 합치기

 

6-1. 여러 branch를 합치는 방법

  - 각 브랜치에서 작업을 마쳤다면 하나의 브랜치로 합쳐줘야 함

  - 합치는 방법으로는 merge와 rebase 두가지가 있음

  - 단 rebase는 여러 사람이 함께 작업하는 경우 적합하지 않음

  1) merge : 두 브랜치를 한 커밋에 이어붙임(두 가지를 이어붙인 내용을 새로운 커밋을 만들어 넣음)

    - 브랜치 사용 내역을 남길 필요가 있을 때

  2) rebase : 브랜치를 잘라서 다른 브랜치에 이어 붙임(그냥 브랜치 자체를 옮겨붙임)

    - 한줄로 깔끔하게 정리된 내역을 유지하길 원할 때

    - 단 이미 팀원과 공유된 커밋에는 사용하지 않는게 좋음

 

6-2. git merge

  - merge 사용법

    1단계) 만약 main브랜치에 A브랜치를 합치려면 main브랜치로 이동해서 시작해야 함

      - main에 새로운 내용을 받아들이는 것이므로

    2단계) 그 다음 git merge A브랜치이름 입력해서 병합

    3단계) 병합을 잘 마쳤으면 A브랜치는 더 이상 필요가 없게 되었으니 git branch -d A브랜치이 으로 삭제해주면 됨

    ★ merge는 둘을 이어붙인 내용을 새로 커밋한것이므로 reset으로 되돌릴 수 있음

 

6-3. git rebase

  - rebase 사용법

    1단계) merge와는 달리 main브랜치에 A브랜치를 옮기려면 A브랜치로 이동해서 시작해야 함

      - A브랜치를 잘라서 옮기는 것이므로

    2단계) git rebase main => main에 A브랜치를 이어붙인거니까 시점상 A브랜치가 더 빠름, 이걸 맞춰주기 위해 3, 4단계

    3단계) main브랜치로 이동

    4단계) git merge A브랜치이름 => 사용해서 해당 시점으로 fast-forward

    5단계) A브랜치 삭제

 

6-4. 브랜치간 충돌 해결법

  - 만약 A브랜치와 B브랜치에서 같은 파일에 서로 다른 수정이 있었다면?

  1) merge에서의 충돌

    - merge를 했을 때 안내문으로 conflict가 나옴

    - 그럼 git status 하면 어느 파일에 충돌이 있는지 알려줌

    - 해당 파일에 가서 A브랜치의 내용을 쓸 지 B브랜치의 내용을 쓸 지 선택해주면 됨

    - 해결 가능하다면 수정할것 다 하고 나서 add, commit 하면 됨

    - 그런데 충돌 범위가 너무 크고 많아서 감당이 안되는 경우 merge를 중단해야 할 수도 있음

      - 중단 방법 => git merge --abort

  2) rebase에서의 충돌

    - 해결 가능하다면 충돌 부분 수정 후 git add .  하고 git rebase --continue해서 충돌이 모두 해결될때까지 반복

    - 해결 다 되면 merge 후 삭제해서 마무리

    - 마찬가지로 해결 불가능할 때 git rebase --abort로 중단 가능

    ※ merge에서는 --continue 안하고 rebase에서는 하는 이유

      - merge는 브랜치의 마지막 커밋을 메인의 마지막 커밋과 합치는 것이니 한번만 해결하면 됨

      - 반면 rebase는 가지를 통으로 잘라서 옮기니까 rebase된 첫 커밋을 수정해도 다음 커밋에 또 문제가 있을 수 있음

      - 그러므로 rebase는 continue 하면서 수정 여러번 해줘야 할 수 있으니 continue 하는 것

 

 

 

7. SourceTree로 해보기

 

7-1. 지금까지 내용(5~6단원) SourceTree로 하는 법

  - 브랜치 생성 : 위쪽에 브랜치 버튼으로 가능

  - merge : CLI와 마찬가지로 merge라면 main으로 가서, 왼쪽탭의 A브랜치 우클릭 후 "현재 브랜치로 병합" 선택

                 그 다음 A브랜치는 필요 없어졌으니 왼쪽탭에서 A브랜치 우클릭해서 삭제

  - rebase : merge와 반대로 A브랜치로 가서 main을 우클릭 하고 "현재 변경사항을 main으로 재배치" 클릭

                 그 다음 메인으로 가서 A브랜치 우클릭해서 병합

                 그 다음 A브랜치는 필요 없어졌으니 왼쪽탭에서 A브랜치 우클릭해서 삭제

  - 충돌해결

    - merge의 충돌해결은 병합하면 경고문이 뜨고 해당 내용 수정 후 다시 커밋하면 됨

    - rebase의 충돌시는 CLI로 하는걸 권장

 

 

※ Note

reset보다는 revert를 사용하기

rebase보다는 merge를 사용하기

 

 

 

 

※ 출처 및 공부한 곳

https://youtu.be/1I3hMwQU6GU

https://www.yalco.kr/@git-github/