Git Session

빡기·2020년 5월 21일
0

TIL(Today I Learned)

목록 보기
43/43

왜 Git인가?

  • 협업 프로젝트 진행 시 여러 사람들이 코드를 공유하기 위한 분산 버전 관리 시스템
  • 공유 뿐만 아니라 원하는 구간에 커밋 지점을 발생시켜 백업 및 원하는 시점으로 이동 해 작업을 원활하게 진행 가능

저장소(Git repository)

Git을 이용하기 위해 먼저 저장소를 구분할 필요가 있다
저장소의 분류는 2가지로 나뉘는데 본인의 로컬 저장소(local repository), 사람들과 공유하는 원격 저장소(remote repository)로 나뉜다

저장소 만드는 2가지 방법

이제, 본인 로컬에 Git 저장소를 만들어 보자
Git 저장소를 만드는 방법에는 또 2가지가 있다.

1. git init을 이용한 방법

1. cd ~/Desktop  // 바탕화면으로 이동
2. mkdir example // 폴더 생성
3. cd example    // 폴더로 이동
4. git init      // example 폴더를 저장소로 초기화
// 저장소로 등록을 하게 되면 폴더 안에 .git 폴더가 만들어져 저장소로 관리된다

위에 명령어로 본인 로컬의 저장소를 초기화하고 gitHub의 원격 저장소와 연동시켜줘야 한다.

  1. git remote add origin https://github.com/pparkgi/pratice.git
    본인이 gitHub에 생성한 원격 저장소와 로컬 저장소를 연결하는 명령어
  2. touch test.md or 에디터 툴로 직접 생성
    원격 저장소에 올릴 테스트 파일 생성
  3. 생성하고 테스트내용 아무거나 입력한 뒤 git add .
    .은 수정된 모든 파일을 tracked 한다는 의미
  4. git commit -m "test"
    이 파일에 대한 커밋지점 생성 및 설명(커밋 메세지) 추가
  5. git push -u origin master
    -u 옵션은 처음 한 번만 입력하면 됨
    매번 git push origin master 할 필요 없이 이전 히스토리 명령을 기억하기 떄문에 이후로 부터는 git push or git pull 명령어를 사용해도 git push origin master로 인식한다
    주의사항은 각 브랜치별로 인식하기 떄문에 새로운 피쳐브랜치를 딸 경우 그 브랜치에도 적용시켜줘야 한다.

2. git clone을 이용한 방법

위의 1번 방법보다 비교적 쉬운편이다
clone은 다른 프로젝트에 참여하거나 git 저장소를 복사하고 싶을 때 사용한다

git clone https://github.com/pparkgi/pratice.git 본인이 원하는 디렉토리명(option)
위와 같이 하면 되는데 본인이 생성한 디렉토리 경로에 가서 입력하면 뒤에 option을 빼면 되고 새로운 디렉터리에 git clone을 하고 싶으면 뒤에 디렉터리명을 붙여준다.


Git 사이클

이제 git 사이클에 대해 이야기 해보도록 하자

Working directory

본인이 코드를 수정하고 저장하는 작업공간을 이야기 한다.
Working directory에는 2가지가 존재한다
1. tracked(관리대상) - git add에 포함된 파일, 파일을 tracked(추적)해서 저장이력을 체크한다.
2. untracked(비관리대상) - git add에 포함되지 않은 파일 즉, tracked을 하지 않은 파일

index(stage area)

tracked을 시작한 단계
stage aread도 2가지가 존재한다.
1. unmodified - git add에 포함은 되었으나, 변경 되지 않은 상태
2. modified - git add에 포함 및 변경 된 상태

git add를 통해 tracked 된 파일의 저장이력을 저장하는 단계
처음에 git add를 통해 파일을 tracked해도 수정사항이 있는 경우 마지막 지점에서 다시 git add를 해줘야 마지막 수정사항을 tracked한다.
=> git add는 되도록 마지막 수정사항이 있는 지점에서 하는 것이 좋아 보인다

local repository

index 단계에서 trakced 된 파일 저장이력에 git commit을 통해 메세지를 담아 어떤 변경사항이 있는지 기록하고 로컬 저장소에 반영(저장)하는 단계
이 단계는 아직 원격 저장소에 연결 된 상태가 아니기에 마지막으로 git push를 이용해 원격 저장소로 올려야 한다

remote repository

local repository 단계에서 git push를 통해 원격 저장소로 올리는 단계, 최종적으로 원격 저장소에 올림으로써 다른 팀원들과 branch 및 파일들을 공유할 수 있게 된다.


Git 명령어

1. git status, diff, log

git status : 파일의 상태의 변화를 알려주는 행위

git diff : Unstaged 상태 파일의 변경이력을 확인
두 커밋간이나 HEAD와 워킹 디렉토리의 차이점을 보여주는 명령어

  • 빨간색 줄 : 변경 전 이력
  • 노란색 줄 : 변경 후 이력

  1. git diff --color-words : 변경된 라인 대신 단어(공백을 구분자로)로 표시가 된다.

  2. git diff --word-diff : 변경 된 사항은 지워지고 추가된 단어를 좀 더 명시적으로 표시한다.

  3. git diff HEAD : 마지막 커밋과 현재 수정사항 확인
    3-1. git diff HEAD HEAD^ : 마지막 커밋과 그 전 상황의 커밋 비교

  4. git diff --cached 또는 git diff --staged : 현재 stage 된 수정사항만 따로 확인

git log : 저장소의 커밋 히스토리를 시간순으로 보여 줌
커밋 히스토리를 시간순으로 보여준다. 즉, 가장 최근의 커밋이 가장 먼저 나온다. 그리고 이어서 각 커밋의 SHA-1 체크섬, 저자 이름, 저자 이메일, 커밋한 날짜, 커밋 메시지를 보여준다.

  1. git log --graph : log 기록을 그래프처럼 표현

  2. git log --oneline : log 기록을 한 줄로 표현, git log --online --graph 같이 사용 가능

  3. git log -p -[number] : git diff와 같은 기능이지만 동료들의 커밋을 빨리 보고 파악하기 편리함
    number에다가 원하는 숫자를 기입하면 그 숫자만큼의 최근 기록을 보여준다

  4. git log --stat : 각 커밋의 어떤 파일이 수정되고 수정된 파일의 변경사항(줄 추가 및 삭제 사항)을 요약정보를 알려 줌

2. git add, commit, checkout, reset

git add : index 영역에 새로운 파일을 tracked 하거나 tracked 된 파일의 변경사항을 알리는 행위

  1. git add tesd.md : 특정 파일에 대한 변경 내역을 index 영역에 올림
  2. git add . : 모든 변경 내역을 index 영역에 올림

git 1.x ver

git 2.x ver

git commit : git add 명령어는 git flow의 첫 단계에 해당되며 인덱스에 새로운 파일이 생겼다는 것을 알리는 행위이다. 이 상태는 저장소에는 반영이 되지 않은 상태이며 git commit 명령을 통해 비로소 저장소에 변경내역이 반영된다.

  1. git commit -m "message" : index에 등록된 파일의 변경 이력을 message와 함께 로컬 저장소에 올림
  2. git commit -am "message" : a 옵션에 의해 git add 단계를 생략하고 모든 변경이력에 대한 커밋메세지 작성
  3. git commit -av : 위와 같은 형식이지만 vim을 켜서 변경사항도 같이 확인하면서 메세지 등록 가능

git checkout : 다른 브랜치로 이동할 때 사용하는 명령어

  1. git checkout -t [origin/원격branchname] : 원격 브랜치를 로컬 저장소로 가져온다
  2. git checkout -b [branchname] : 브랜치 생성과 동시에 해당 브랜치로 이동
  3. git checkout -- [filename] : git add 전 상태에서 working directory에서 작업한 내용을 작업 전 상태로 되돌려 줌

git reset : Stage 영역을 초기화 시킴
git reset HEAD [filename] : git add 이후에 상태를 되돌리고 싶을 때 하는 명령어, git add 전 단계로 돌아감, (코드는 그대로 남아 있음)

  1. git reset --hard [HEAD or 특정commit지점] : 위와 같이 git add 전 단계로 돌아가는데 변경 된 코드까지 완벽하게 되돌리게 해주는 명령어

3. git push, pull, branch

git push : 로컬 저장소의 등록된 사항을 원격 저장소에 등록하는 행위

  1. git push origin [branchname] : git commit을 통해 로컬에 저장 되어 있는 내용을 해당 브랜치를 [branchname]으로 원격 저장소에 올리는 행위

  2. git push -u origin [branchname] : 이 행위를 안 하면 git 위의 명령어 처럼 매번 git push origin [branchname] 해줘야 하지만 -u 옵션을 사용하면 push 때 이전 히스토리를 기억하기 때문에 추후에는 git push만 해줘도 됨 (-u 옵션은 처음에 한 번만 실행)

git pull : 원격 저장소의 등록된 사항을 로컬 저장소로 가져오는 행위, 다른 동료가 올린 branch는 원격 저장소에 push 되기 전까지는 접근할 수가 없음

  1. git pull origin [원격branchname] : 원격에 있는 브랜치를 현재 위치하는 브랜치에 가져와 merge까지 하는 작업

git branch [branchname] : 새로운 브랜치를 생성한다.

  1. git branch --set-upstream-to=origin/[원격에 존재하는 branchname] [로컬에 존재하는 branchname] : 협업 시 원격 저장소에 있는 branch 내용을 로컬에 반영하지 않았다면 원격 저장소에 있는 브랜치를 추적(연결) 한 후 git pull을 통해 merge 한다
    [로컬에 존재하는 branchname]을 생략하면 지금 현재 위치하는 브랜치에 원격 브랜치를 연결한다

  2. git branch -a : 로컬, 원격 브랜치 리스트 모두 조회

4. git merge, rebase 비교

merge

  • branch 병합 시 기본적으로 사용되는 명령어
  • 장점
    commit 지점을 원하는 곳 마다 생성 함으로써 백업이나 실수를 방지 할 수 있다
    단순한 매커니즘이기에 입문자들이 이해하기 쉽다
    보통 하나의 기준을 가지는 브랜치(마스터 브랜치)를 공유해 feature 브랜치를 생성 해 각각 다른 브랜치에서 여러 사람들이 작업한다. 때문에 원래 브랜치의 커밋들은 변경되지 않고 계속 유지되어 다른 개발자들의 작업과 공유되는 것에 대해 신경쓸 필요가 없다
  • 단점
    다른 브랜치에서 master로 merge를 하는 경우 master와 다른 브랜치가 merge되는 지점에 merge commit이 생겨 큰 프로젝트를 하는 경우 merge commit이 많아지게 됨으로 굉장히 지저분하게 보인다


merge 실습 예제


rebase

  • branch의 base는 기본적으로 master인데 base를 다시 설정한다는 의미
  • 장점
    merge commit을 하나로 만들어 굉장히 깔끔해 보인다(직관적인 히스토리) => 커밋 히스토리가 굉장히 깔끔함
  • 단점
    충돌상황을 단계별로 계속 해결해줘야 해서 -i옵션(--squash 역할)을 사용 시 굉장히 복잡하다


rebase 실습 예제

conflict 없는 rebase

1. 예제 브랜치 생성 및 commit 여러개 생성

2. rebase 시작

3. rebase 기준 commit 및 -i옵션(squash) 할 커밋 설정

  • 파란색 옵션 설명문대로 첫 번째 커밋을 기준점으로 삼고(p로 설정)
  • 2, 3번째 커밋은 squash 대상으로 설정

4. 커밋 메세지 정리하기

아래와 같이 여러개의 커밋 메세지를 정리해서 한 문장으로 표현한다

5. git push origin branchname으로 push를 하고 원격 저장소에 올린다

6. github에서 PR을 날리고 merge를 시킨다

7. master branch에서 pull을 받아 rebase를 적용시킨다

conflict 발생 시 rebase 실습 예제

  • 마스터 브랜치와 같은 지점에서 피쳐브랜치를 생성한 뒤, 마스터 브랜치에 누군가 머지를 했을 경우 내가 진행하는 브랜치의 커밋과 겹치는 부분이 발생할 수 있고 이에 따라 conflict가 발생한다.
  • 한 커밋 한 커밋 단계별로 squash를 진행하기 한다, 이 과정에서 conflict가 발생하는 경우 아래 과정을 따른다.

1. 마스터 브랜치와 동일한 커밋 지점에서 피쳐 브랜치를 생성한 뒤 conflict를 발생 시키기 위해 다시 마스터 브랜치로 돌아와서 커밋을 발생 시킨다.

2. 예제를 위해 2번째 커밋을 발생시킨다.

3. 피쳐 브랜치로 돌아와 conflict 발생 유도를 위해 피쳐 브랜치 만에 커밋을 발생시킨다.

4. 예제를 위해 2번째 커밋을 발생시킨다.

5. 피쳐 브랜치에서 rebase를 시작한다 git rebase -i master를 하고 기준점을 p로 squash를 할 커밋을 s로 설정한다.

6. 아래 사진 처럼 conflict가 발생한 내용을 보여준다. HEAD는 현재 마스터 브랜치 === 아래 내용은 rebase_point의 내용을 보여준다


7. 코드 내용을 본인의 의도대로 정리 해준다.

8. 코드를 수정해서 적용을 했으니 다음 단계 커밋을 계속 진행하기 위해 git add => git rebase --continue를 실행 해 진행한다.

9. 두 번째 커밋을 본인의 의도대로 정리 해준 뒤 다시 한 번 git add => git rebase --continue를 실행한다.

10. 마지막까지 conflict를 해결 했으면 아래와 같이 git push origin rebase_point를 실해 해 github 원격 저장소에 올려 merge 준비를 한다.

11. github에서 merge 작업을 진행한다.

12. 마스터 브랜치로 돌아와 git pull을 진행해 rebase를 완료한다.

rebase 추가사항 - gitHub에 PR날리고 다시 리팩토링을 해야 하는 경우
1. 코드 수정하고 git add
2. git commit -m "메세지"
3. git rebase -i master
4. confilct 있으면 수정하고
5. git push origin 피쳐브랜치 --force (force push는 본인 피쳐 브랜치에서만 해야 함)
commit의 history를 바꾸는 일은 중앙 저장소 입장에서 보았을 때, 또 다른 branch가 갈라졌다고 인식하기 때문이다. --f 를 하지 않은 경우, github은 다시 pull을 하고 merge를 하라고 제안한다. force push 는 내가 올리는 history를 그대로 받으라고 github에게 명령하는 것과 같다.
또, force push는 본인 브랜치에서만 진행해야 함!
master에서 진행하는 경우, 다른 사람들의 commit history 바꾸어 버리게 되기 때문이다.

merge, rebase 옵션 명령어

git merge [branchname] : 기준으로 잡고 싶은 브랜치로 git checkout한 뒤 위의 명령어를 실행하면 branchname에 해당하는 브랜치가 현 위치 브랜치에 merge(병합)된다.

  1. git merge --abort : merge 직전의 상태로 돌아간다

git rebase -i [base재지정할 branch 대부분 master] : --interactive 옵션을 사용하면, 커밋 로그를 조작할 수 있다. 즉, 불필요한 커밋 이력을 제거해서 필요한 커밋들만 남길 수 있습니다.
(커밋에서 작업했던 내용들은 그대로 유지)

5. 이외 명령어

git remote prune origin : github에서 PR을 적용하고 merge 한 뒤에 원격 브랜치를 삭제하고 나면 로컬에는 삭제된 것이 적용 되지 않는다.
그러기 때문에 삭제된 브랜치를 로컬에도 적용시켜줘야 하는데 위의 명령어를 실행하면 로컬에서도 삭제된다.

실습

1. master 브랜치에 rebase 성공한 뒤 delete branch 버튼을 두른 상황

2. git branch -a로 브랜치 확인하면 삭제된 것이 반영이 안 됨

3.git remote prune origin을 통해 원격 브랜치와 동기화 시켜 삭제를 적용

4.원격 브랜치 삭제 적용 완료!


git color settings

git config color.ui true : 콘솔에서 git output을 컬러로 출력하기
git config format.pretty oneline : 이력(log)에서 확정본 1개를 딱 한 줄로만 표시하기


참조 출처

  1. 사이클 이미지 출처 - https://www.holaxprogramming.com/2018/11/01/git-commands/
  2. merge, rebase 차이 비교 - https://cyberx.tistory.com/96
profile
Front End. Dev

0개의 댓글