[P1_S1] Git

보리·2024년 3월 14일
0

codeit-sprint

목록 보기
6/22

✨버전 관리 프로그램

  • 빠른 속도
  • 단순한 디자인
  • 비선형적 개발 지원(많은 브랜치 생성 가능)
  • 분산형 시스템
  • 리눅스와 같은 거대한 프로젝트도 속도 저하의 문제없이 관리 가능.

✨Git(global information tracker)

  • Git은 버전 관리를 할 때 사용하는 소프트웨어 자체
  • Github는 Git으로 관리하는 프로젝트의 복사본을 저장하는 서버를 제공해주고 협업을 위한 편의 기능을 제공해주는 서비스

❓git 의미, 사용법을 알고싶다면

git help
또는
man git-

📕working directory

  • 작업하는 프로젝트 디렉토리

📕staging area

  • gir add한 파일들이 존재하는 영역.
  • 커밋 하면 staging area에 있는 파일들만 커밋함

📕repository

  • working directory의 변경 이력들이 저장되어 있는 영역

❓staging area가 필요한이유

예를 들어, 두 파일을 수정했을 때 한 파일을 커밋에 반영하고 싶지 않을 수 있다. 만약 staging area가 없다면 원하는 것들만 선별적으로 커밋에 반영할 수 없다.

📘파일의 4가지 상태

  • Untracked 파일을 새로 생성하고 그 파일을 한 번도 git add 해주지 않았다면 이 상태
  • Tracked 파일이 Git에 의해 그 변동사항이 추적되고 있는 상태
    • Staged 파일의 내용이 수정되고나서, staging area에 올라와있는 상태

      새로 생성한 파일에 내용을 쓰고 git add를 해주거나

      한 번이라도 커밋에 포함됐었던 파일이라도 내용을 수정하고 git add를 해주면 이 상태

    • Unmodified 현재 파일의 내용이 최신 커밋의 모습과 비교했을 때 전혀 바뀐 게 없는 상태 커밋을 하고 난 직후에는 working directory 안의 모든 파일들이 이 상태
    • Modified 최신 커밋의 모습과 비교했을 때 조금이라도 바뀐 내용이 있는 상태

✨오픈 소스 프로젝트

  • 무료로 사용할 수 있다.
  • 여러 개발자들이 참여하기 때문에 폐쇄적으로 코드를 관리할 때보다 코드의 신뢰도가 더 높다.(케바케)
  • 오픈 소스 프로젝트에 참여 중인 다른 개발자들에게 질문을 할 수 있다.
  • 어떤 프로그램을 개발할 때 특정 분야에서 사실상 표준처럼 사용되는 오픈 소스 프로그램을 많이 활용할수록 전체 개발 속도를 단축시킬 수 있다.
  • 참여자 수가 많지 않거나, 참여자의 실력이 좋지 않으면 소스 코드의 신뢰성을 보장하기 어렵다.
  • 해당 오픈 소스를 사용해서 문제가 생겼을 때 보상을 해주거나, 책임을 질 주체가 없다.

⚠️커밋 메시지 작성 팁

(1) 커밋 메시지의 제목과 상세 설명 사이에는 한 줄을 비워두기

(2) 커밋 메시지의 제목 뒤에 온점(.)을 붙이지 말기

(3) 커밋 메시지의 제목의 첫 번째 알파벳은 대문자로

(4) 커밋 메시지의 제목은 명령조로

(5) 커밋의 상세 내용에는

  • 왜 커밋을 했는지
  • 어떤 문제가 있었고
  • 적용한 해결책이 어떤 효과를 가지는지

(6) 다른 사람들이 자신의 코드를 바로 이해할 수 있다고 가정하지 말고 최대한 친절하게 작성하기


(1) 하나의 커밋에는 하나의 수정사항, 하나의 이슈(issue)를 해결한 내용만 남기기

(2) 현재 프로젝트 디렉토리의 상태가 그 내부의 전체 코드를 실행했을 때 에러가 발생하지 않는 상태인 경우에만 커밋하기


✨Git 커맨드 명령어

  • git init : 현재 디렉토리를 Git이 관리하는 프로젝트 디렉토리(=working directory)로 설정하고 그 안에 레포지토리(.git 디렉토리) 생성
  • git config user.name 'codeit' : 현재 사용자의 아이디를 'codeit'으로 설정(커밋할 때 필요한 정보)
  • git config user.email 'teacher@codeit.kr' : 현재 사용자의 이메일 주소를 'teacher@codeit.kr'로 설정(커밋할 때 필요한 정보)
  • git add [파일 이름] : 수정사항이 있는 특정 파일을 staging area에 올리기
  • git add [디렉토리명] : 해당 디렉토리 내에서 수정사항이 있는 모든 파일들을 staging area에 올리기
  • git add . : working directory 내의 수정사항이 있는 모든 파일들을 staging area에 올리기
  • git reset [파일 이름] : staging area에 올렸던 파일 다시 내리기
  • git status : Git이 현재 인식하고 있는 프로젝트 관련 내용들 출력(문제 상황이 발생했을 때 현재 상태를 파악하기 위해 활용하면 좋음)
  • git commit -m "커밋 메시지" : 현재 staging area에 있는 것들 커밋으로 남기기
  • git help [커맨드 이름] : 사용법이 궁금한 Git 커맨드의 공식 메뉴얼 내용 출력
  • git push -u origin master : 로컬 레포지토리의 내용을 처음으로 리모트 레포지토리에 올릴 때 사용합니다.(-u origin master가 무슨 뜻인지는 'Git에서 브랜치 사용하기' 챕터에서 배울 거니까 걱정마세요!)
  • git push : 로컬 레포지토리의 내용을 리모트 레포지토리에 보내기
  • git pull : 리모트 레포지토리의 내용을 로컬 레포지토리로 가져오기
  • git clone [프로젝트의 GitHub 상 주소] : GitHub에 있는 프로젝트를 내 컴퓨터로 가져오기
  • git log : 커밋 히스토리를 출력
  • git log --pretty=oneline : --pretty 옵션을 사용하면 커밋 히스토리를 다양한 방식으로 출력할 수 있다. --pretty 옵션에 oneline이라는 값을 주면 커밋 하나당 한 줄씩 출력한다.
    • 보통 git history로 별명 붙임.
    • -all: 모든 브랜치 정보 보기
    • —graph’: 각 커밋 간의 관계가 입체적으로 잘 드러나도록 함.
  • git show [커밋 아이디] : 특정 커밋에서 어떤 변경사항이 있었는지 확인
  • git commit --amend : 최신 커밋을 다시 수정해서 새로운 커밋으로 만듦
  • git config alias.[별명][커맨드] : 길이가 긴 커맨드에 별명을 붙여서 이후로 별명으로 해당 커맨드를 실행할 수 있도록 설정
  • git diff [커밋 A의 아이디][커밋 B의 아이디] : 두 커밋 간의 차이 비교(브랜치도 가능)
  • git reset [옵션][커밋 아이디] : 옵션에 따라 하는 작업이 달라짐(옵션을 생략하면 --mixed 옵션이 적용됨) (1) HEAD가 특정 커밋을 가리키도록 이동시킴(--soft는 여기까지 수행) (2) staging area도 특정 커밋처럼 리셋(--mixed는 여기까지 수행) (3) working directory도 특정 커밋처럼 리셋(--hard는 여기까지 수행) 그리고 이때 커밋 아이디 대신 HEAD의 위치를 기준으로 한 표기법(예 : HEAD^, HEAD~3)을 사용해도 됨 ‼️HEAD~x는 현재 HEAD가 가리키는 커밋보다 x단계 전에 있는 커밋
  • git tag [태그 이름][커밋 아이디] : 특정 커밋에 태그를 붙임
  • git branch [새 브랜치 이름]: 새로운 브랜치를 생성
  • git checkout -b [새 브랜치 이름]: 새로운 브랜치를 생성하고 그 브랜치로 바로 이동
  • git branch -d [기존 브랜치 이름]: 브랜치 삭제
  • git checkout [기존 브랜치 이름]: 그 브랜치로 이동
  • git merge [기존 브랜치 이름]: 현재 브랜치에 다른 브랜치를 머지
  • git merge --abort: 머지를 하다가 conflict가 발생했을 때, 일단은 머지 작업을 취소하고 이전 상태로 돌아감
  • git fetch: 로컬 레포지토리에서 현재 HEAD가 가리키는 브랜치의 업스트림(upstream) 브랜치로부터 최신 커밋들을 가져옴(가져오기만 한다는 점에서, 가져와서 머지까지 하는 git pull과는 차이가 있음)
  • git blame: 특정 파일의 내용 한줄한줄이 어떤 커밋에 의해 생긴 것인지 출력
  • git revert: 특정 커밋에서 이루어진 작업을 되돌리는(취소하는) 커밋을 새로 생성
  • git reflog: 헤드가 이때까지 가리켜왔는 커밋들 id 보여줌
  • git rebase: 새로운 커밋을 만들지 않음. merge로 만들어진 커밋 히스토리보다 깔끔함.
  • git stash: 어떤 브랜치에서 하던 작업을 아직 커밋하지 않았는데 다른 브랜치로 가야하는 상황에 씀. 작업 내용 임시 저장하기. 최근 커밋 이후로 작업했던 내용은 모두 스택에 옮겨지고 working directory 내부는 다시 최근 커밋의 상태로 초기화
    • git stash list: 작업 내용 조회(스택 보기)
    • git stash apply [작업 내용 아이디]: 작업 내용 적용 → 작업 내용 아이디 생략하면 제일 최근꺼로 적용
    • git stash drop [작업 내용 아이디]: 작업 내용 제거
    • ‼️적용한 작업내용은 제거해주는 것이 좋음. → 한번에 해주는 것 → git stash pop [작업 내용 아이디]
  • git cherry-pick: 자신이 원하는 작업이 들어있는 커밋들만 가져옴

❓긴 커맨드에 alias 설정하기

git log: 커밋 히스토리 보기

—pretty=oneline: 커밋 하나당 한 줄씩 보기

→ 별명 붙일 수 있음 (alias)

git log --pretty=onelinegit history라는 별명으로 바꾸기

git config alias.history 'log --pretty=oneline'

✔️origin이란

Git에서는 리모트 레포지토리를 최초로 추가할 때 origin이라는 이름으로 가리키는 것이 관례화되어있다. origin은 ‘근원’, ‘기원’이라는 뜻. 아마도 다른 사람의 리모트 레포지토리를 자신의 컴퓨터로 가져와서 작업을 하는 사람의 입장에서는 리모트 레포지토리가 프로젝트의 근원이 되는 존재이기 때문에 그런 관습이 생긴 것으로 추측된다.

✔️Remote Repositoy에 있는 브랜치

git push -u origin master

이 커맨드의 뜻은

  • 현재 로컬 레포지토리에 있는 master 브랜치의 내용(=master 브랜치와 관계된 모든 커밋들)을 origin이라는 리모트 레포지토리로 보낸다는 뜻.

이때 같은 이름의 브랜치로 전송하게 되는데 만약 origin이라는 리모트 레포지토리에 master 브랜치가 없으면 master 브랜치를 새로 생성하고 푸시한다.

❓옵션 -u

  • -u--set-upstream이라는 옵션의 약자

--set-upstream(-u) 옵션을 주면 로컬 레포지토리에 있는 master 브랜치가 origin에 있는 master 브랜치를 tracking(추적)하는 걸로 설정된다.

tracking이라는 건 로컬 레포지토리의 한 브랜치가 리모트 레포지토리의 한 브랜치와 연결되어 그것을 계속 바라보는 상태가 되는 것. 이렇게 맺어진 연결 상태를 tracking connection이라고 함.

로컬 레포지토리에 A라는 브랜치가 있고,

리모트 레포지토리에 B라는 브랜치가 있을 때

tracking connection이 서로 맺어진 경우,

B 브랜치를 A 브랜치의 upstream branch라고 함.

이렇게 tracking connection이 한번 설정되고 나면,
사용자가 현재 master 브랜치에 위치해있을 때,


git push

라고만 써도 자동으로 리모트 레포지토리의 master 브랜치를 대상으로 git push가 동작하고,


git pull

라고만 써도 리모트 레포지토리의 master 브랜치를 대상으로 git pull이 동작한다.

처음에 이 옵션을 주지 않으면 tracking connection이 없기 때문에 나중에 git push를 하고 싶을 때


git push origin master:master
  • origin은 리모트 레포지토리를 나타내고,
  • master:master에서 더 먼저 나오는 master는 로컬 레포지토리의 master 브랜치(~에서)/더 뒤에 나오는 master는 리모트 레포지토리의 master 브랜치(~으로)를 나타낸다.

✔️origin/master의 의미

  • master: 로컬 레포지토리의 master 브랜치
  • origin/master: 리모트 레포지토리의 master 브랜치

✨branch

  • 브랜치: 커밋을 카리키는 존재
  • HEAD: 브랜치를 통해 커밋을 간접적으로 가리키는 존재

merge 이전의 상태로 돌아갈때 그냥 머지 자체를 취소하는 명령어

git merge --abort

branch merge

1. merge

  • 많이 사용하는 일반적인 merge. 커밋 이력을 모 남길 때 사용함.
  • 모든 커밋과 분기했던 branch 히스토리가 남는다.

2. fast-forward

  • merge는 -ff옵션이 기본으로 설정되어 있다. -> base 브랜치가 이후 변경 내용이 없는 최신 브랜치일 경우 병합한다는 커밋 없이 합치고, 그렇지 않은 경우 병합 커밋을 남기고 합친다.
  • git merge --no-ff 옵션으로 base 브랜치가 최신 브랜치라 해도 커밋을 남기도록 함.

3. squash&merge

  • merge에 -squash 옵션 추가
  • 분기했던 branch에 있던 내용 a,b,c 커밋을 모두 합쳐 하나의 새로운 커밋을 만든다.
  • 지저분한 커밋 히스토리들을 하나로 합쳐서 기능상 의미있는 하나의 커밋만 남김
  • 잘못 사용해서 과도한 생략을 하게 되면 추후 변경 파악이 힘듦.

4. rebase&merge

  • 분기했던 branch의 기분으로 base를 설정하고 merge함. (git merge -ff 같은 형태)
  • rebase를 하면 커밋들의 base가 변경돼 커밋 해시 또한 변경될 수 있다. (강제 푸쉬 해야함)
  • 머지 커밋을 남길 필요가 없는 merge의 경우 사용하면 좋음.
  • 커밋 그래프가 하나의 라인으로 그려져 가독성 좋음.

-> 특정 기능 개발 후 develop branch에 merge하고자 할 때는 squash and merge가 유용
-> develop branch를 production branch로 merge하고자 할 때는 develop branch에 분기가 남아 있다면, production branch는 간결하게 유지하고자 rebase and merge가 유용

git reset vs git checkout

git resetgit checkout
HEAD가 가리키던 브랜치가 다른 커밋을 가리킴HEAD 자체가 다른 커밋이나 브랜치를 가리킴
HEAD도 결국 간접적으로 다른 커밋을 가리킴브랜치를 통하지 않고, 커밋을 직접적으로 가리키는 HEAD를 Detached HEAD라고 함

Fast-forward merge: 새로운 커밋이 생기는 게 아니라 단지 브랜치가 이동하게 되는 머지

3-way merge: 자신만의 방식을 갖고 이 3가지 커밋을 기준으로 머지 커밋을 자동으로 만듦.

git fetch: 리모트 레포지토리에서 가져온 브랜치 내용을 머지하기 전에 점검해야할 필요가 있을 때 사용.

리모트 레포지토리에 있는 브랜치 내용과 내가 작성한 코드를 비교해서 잘못된 부분이 없는지 검토할때 씀.

git diff: 커밋과 브랜치 둘 다 비교할 수 있음.

❓잘못된 브랜치에서 작업하는 실수했을 때

git stash로 stack에 작업 내용 저장하고 올바른 브랜치 이동 후에 git stash apply를 해주면 됨.

Squash and merge

브랜치에서의 모든 변경 사항을 하나의 커밋으로 압축하여 머지하는 방식

.gitignore 파일

working directory 내에 존재하는 파일들 중에서 마치 존재하지 않는 것처럼 Git이 인식해야할 파일들의 목록이 적힌 파일

git flow

  • main(master): 서비스를 직접 배포하는 역할을 하는 브랜치
  • develop: feture에서 개발된 내용이 저장되는 브랜치
  • feature: 기능 개발 브랜치
  • release: 배포 전 내용을 QA하기 위한 브랜치
  • hotfix: 출시 버전에서 발생한 버그를 수정하는 브랜치

  • master와 develop 브랜치는 필수다. (develop 브랜치는 master에서 시작된 브랜치)
  • develop 브랜치에서는 상시로 버그를 수정한 커밋들이 추가된다.
  • 개로운 기능 추가 작업이 있는 경우 develop 브랜치에서 feature 브랜치를 생성한다. (feature 브랜치는 항상 develop 브랜치에서 시작)
  • 기능 추가 작업 완료 후 feature 브랜치는 항상 develop 브랜치로 merge됨.
  • merge 후 QA 진행을 위해 release 브랜치 생성.
  • release 브랜치에서 QA에서 진행된 버그를 수정한다.
  • QA 통과 후, release 브랜치를 master와 develop 브랜치로 merge한다.
profile
정신차려 이 각박한 세상속에서

0개의 댓글