Week2 - Git

oauch·2023년 9월 11일
post-thumbnail

🧩 Git

  • 버전 관리 + 협업을 할 수 있게 도와주는 툴

📌 버전 관리 장점

  1. 지난 과정 확인 가능
  2. 이전 버전으로 되돌리기 가능

📌 commit

  • 프로젝트 디렉토리의 특정 모습을 하나의 버전으로 남기는 행위 / 결과물

📌 repository

  • 저장소
  • 커밋이 저장되는 곳
  • 프로젝트 자체를 repository라는 사람도 있지만
  • 실질적인 repository.git

📌 버전관리 시작

git init

  • 비어있는 레포지토리 생성

📌 commit 하기전 준비

  • git에게 commit한 사용자 기록
git config user.name "사용자 이름"
git config user.email "사용자 이메일"
  • 커밋을 하기 전에 일단 git add "파일" 명령어를 입력 해야된다
  • add : 커밋에 반영될 파일을 지정
git commit -m "커밋에 관련된 메시지"

🧩 git 작업 영역

  1. working directory
  2. staging area
  3. repository

📌 working directory

  • 작업을 하는 프로젝트 영역

📌 staging area

  • git add를 한 파일들이 존재하는 영역

📌 repository

  • working directory의 변경 이력들을 저장하는 영역

🔥 staging area 존재하는 이유

  • 그냥 working directory에서 바로 커밋해서 변경이력을 저장하면 더 편하지 않을까?
    • 편하긴 하겠지만 그러면 개발자가 커밋을 할때, 원하는 파일만 커밋을 하지 못하기 때문에 필수적으로 필요한 영역

예를들면 A.txt, B.txt 파일이 있다.
개발자는 A.txt에 대해서 완료하지 못한 상태 B.txt는 완료된 상태이다.
근데 지금까지 했던 거는 커밋을 하고 싶을때, 그럴때 필요해서 staging area가 필요한 것이다.


📌 git status

  • git이 인식하고 있는 프로젝트 디렉토리의 현재 상태
git status

📌 수정한 파일 모두 add 하는 법

git add .

🧩 status

  • git으로 관리하는 파일은 상태라는 것을 가짐
  1. Untracked
  2. Tracked
    2-1. Staged
    2-2. Unmodified
    2-3. Modified

📌 Untracked

  • git에 의해서 변동사항이 추적되지 않는 상태
  • 파일을 생성하고, git add를 해주지 않은 상태

📌 Tracked

  • git에 의해서 변동사항이 추적되고 있는 상태

📍 Staged

  • 파일의 내용이 수정되고, staging area에 올라와 있는 상태

    새로 생성한 파이에 내용을 쓰고 git add한 상태
    한 번이라도 커밋에 포함 되었던 파일이라도 내용을 수정하고, git add한 상태

📍 Unmodified

  • 현재 파일 내용이 최신 커밋의 모습과 비교할 때 변경 사항이 없는 상태
  • 커밋한 이후는 working direcoty 안의 모든 파일이 해당 상태

📍 Modified

  • 최신 커밋의 모습과 수정된 내용이 있는 상태



🧩 git add 취소하기

  • staging area에서 파일 제거
  • 변경된 내용은 그대로 남아 있음
git reset


🧩 git push

  • 로컬 레포지토리 -> 리모트 레포지토리 반영
git push -u origin master	# 로컬 레포지토리 내용을 처음 리모트 레포지토리에 올릴때 사용
git push

🧩 git pull

  • 로컬 레포지토리 <- 리모트 레포지토리 반영
git pull

🔥 리모트 레포지토리 기능
1. 안정성
2. 협업 가능

🧩 git clone

  • 리모트 레포지토리에 있는 프로젝트 복사하는 명령어
git clone "주소"

🧩 커밋 히스토리

  • 지금까지 커밋한 기록을 보여준다.
git log [--pretty=oneline]		# 지금까지 커밋된 기록을 보여줌
git show [id 4자리정도 입력]		# 이전과 어떤게 바뀌었는지 알려줌 

🧩 최신 커밋 수정하기

  • 최신 커밋을수정해서 다시 새로운 커밋으로 만들기
git commit --amend

🧩 commit

  1. commit을 한 사용자 아이디
  2. commit한 날짜, 시간
  3. commit 메시지

🔥 commit 메시지 작성요령
1. 제목과 상세내용 사이에 한 줄을 비운다. (그래야 가독성이 좋다)
2. 제목 뒤에 . 붙이지 않는다.
3. 제목의 첫번째 알파벳 = 대문자
4. 제목은 명령조로 작성

🧩 커맨드 별명 (alias)

커맨드 지정

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

커맨드 삭제

git config --unset alias.st

🧩 두 커밋간의 차이 보기

git diff 이전 커밋아이디 이후 커밋아이디

🧩 HEAD

  • 어떤 커밋 하나를 가르킨다
  • HEAD가 가르키는 커밋에 따라 working directory 구성


🧩 git reset

  • HEAD가 과거의 커밋을 가르키게 할 수 있다.
  • working directory의 내용도 과거 커밋의 모습으로 돌아간다.
git reset --[옵션] 커밋아이디
git reset --[옵션] HEAD^
git reset --[옵션] HEAD~x			# x단계 전으로

계속 git add를 할 때마다 staging area에서는 새로운 파일이 추가되거나 원래 있던 파일이 더 새로운 버전의 것으로 교체
🔥 원래 있던게 사라지는게 아님
🔥 staging area에 있던 것들은 커밋을 하더라도 그것과 상관없이 계속 남아 있음

git reset [옵션] zxc working directory staging area repository
--soft x x HEAD -> zxc
--mixed x HEAD -> zxc HEAD -> zxc
--hard HEAD -> zxc HEAD -> zxc HEAD -> zxc

🔥 hard 옵션은 조심!

🧩 git tag

  • 커밋에 태그를 달 때 사용하는 커맨드
git tag [태그이름] [커밋아이디]
git tag		# 프로젝트 디렉토리에 있는 모든 태그 조회
git show [태그이름]		# 태그에 연결된 커밋정보 보는법

🧩 branch

  • [코드를 관리하는 하나의 흐름] -> 어떤 커밋을 가르키는 존재

📌 branch

git branch

📌 branch 생성

git branch [브랜치 이름]

📌 branch 변경

git checkout [브랜치 이름]

📌 branch 삭제

git branch -d [브랜치 이름]

📌 branch 생성과 동시에 이동

git checkout -b [브랜치 이름]

🧩 merge

  • 다른 브렌치에서 했던 커밋을 가져오고 싶을 때 사용
git merge [브랜치 이름]

🧩 conflict

  • conflict가 발생한 파일 열기
  • merge의 결과가 되었으면 하는 모습대로 코드 수정
  • 커밋

🧩 merge 취소

  • merge를 하다 conflict가 생긴 것을 자체적으로 수정하는거 말고
  • merge 자체를 취소하는 방법
git merge --abort

🔥 Conflict 발생한 파일이 너무 많을때만 사용한다.


🧩 origin

git remote add origin [리모트 레포지토리]
  • remote : 리모트 레포지토리에 관한 작업을 할 때 사용하는 커맨드
  • add : 새로운 리모트 레포지토리를 등록
  • origin [리모트 레포지토리] : 리모트 레포지토리를 origin 이라는 이름으로 등록

    리모트 레포지토리 -> origin 으로 표현하는 것


🧩 Remote Repositoy에 있는 브랜치

git push -u origin master
  • 현재 로컬 레포지토리에 있는 master 브랜치 내용
  • origin이라는 리모트 레포지토리로 보낸다.
    🔥 만약 origin이라는 리모트 레포지토리에 master 브랜치가 없으면 maste 브랜치를 새로 생성하고 푸시
  • -u : --set-upstream의 약자
    • 로컬 레포지토리에 있는 master 브랜치가
    • origin에 있는 master 브랜치를 tracking 하는걸로 설정

📌 tracking

  • 로컬 레포지토리의 한 브랜치가 리모트 레포지토리의 한 브랜치와 연결되어 그것을 계속 바라보고 있는 상태
  • 로컬 레포지토리에 있는 master 브렌치와 리모트 레포지토리에 있는 master 브렌치가 연결되어 있는 상태를 tracking connection이라고 한다.
  • 리모트 레포지토리의 master 브렌치가 로컬 레포지토리의 master의 upstream branch 라고 한다.

  1. main -> 로컬 레포지토리의 main 브렌치를 나타냄
  2. origin/main -> 리모트 레포지토리의 main 브렌치를 나타냄

🧩 HEAD와 branch의 관계

  • HEAD는 어떤 커밋을 가르키는 존재 (포인터)
  • 하지만 HEAD가 커밋을 직접 가르키는 것은 아니다.

    HEAD -> branch -> commit

이런식으로 branch을 통해서 커밋을 가르킨다.

📌 merge

  1. HEAD가 가르키는 커밋에
  2. 다른 branch가 가르키던 커밋을
  3. 합쳐서 새로운 commit을 만든다.

다시 정리하면
branch = 커밋을 가르키는 존재 (포인터)
HEAD = branch를 통해 커밋을 간접적으로 가르키는 존재 (포인터)

🧩 git reset 비밀 1

  • git reset 사용시
  1. HEAD는 같은 브랜치를 가르킴
  2. HEAD가 가르키는 브랜치가 다른 특정 commit을 가르킴
  3. 이거 때문에 HEAD가 간접적으로 가르키던 commit도 바뀌게 됨

🧩 git reset 비밀 2

  • git reset을 한다고 그 이후의 commit이 사라지는 것은 아니다.
  • git reset은 과거의 commit만 갈 수 있는 것은 아니다.
    • 과거의 commit으로 갔으면 git reset으로 다시 원래 있던 commit으로 돌아갈 수 있다.

🔥 과거의 commit으로 reset한다고 해서 그 이후의 commit들이 삭제되는 것은 아니다.
🔥 git reset은 과거의 commit뿐만 아니라 현재의 HEAD가 가르키는 commit 이후의 commit으로도 할 수 있다.

다시 한번 정리하자면
git reset = HEAD, branch 동시에 같은 commit을 가르키는 것을 지정
git checkout = HEAD가 commit을 가르키는걸 지정 (HEAD가 branch를 가르키도록 할 수 있음)

🧩 git merge 종류

  • merge는 항상 새로운 커밋을 만드는 것은 아니다.
  • merge를 사용하면 똑같은 커밋을 가르키게 되는 경우도 있다.
  • commit 히스토리 상에서 같은 line에 있는 branch를 머지할 때 이루어지는데
  • 이를 Fast-forward merge라고 부른다. (forward = 빨리감기)

  • 이런 경우도 있는데, 이를 3-way merge라고 부른다.
  • branch의 값이 변화가 있는 값을 가져와 merge 하는 것이다.
  • case4 같은 경우는 변화가 모두 다르기 때문에 conflict가 발생하는 것이다.

🧩 git pull

  • 리모트 레포지토리의 branch를 가져와서 merge 하는 동작
  • 그래서 conflict가 날 수 있다.
  • 리모트 레포지토리의 브랜치를 검토 없이 바로 합치고 싶을 때 사용

🧩 git fetch

git fetch
  • 리모트 레포지토리에서 가져온 브랜치의 내용을 머지하기 전에 점검해야할 필요가 있을 때 사용
  • 리모트 레포지토리에 있는 브랜치의 내용과 내가 작성한 코드를 비교해서 잘못된 부분이 없는지 검토해야할 때
  • 가져오기만 하고, merge는 하지 않음 (git pull과의 차이점)
  • 리모트 레포지토리의 브랜치를 검토할때 사용
  • git diff로 비교

📌 리모트 레포지토리의 브랜치에 문제가 있을 때

  • 잘못된 코드를 추가한 개발자에게 코드를 지우고 다시 리모트 레포지토리에 올려달라고함
  • 잘못된 부분을 직접 수정하고 git push

🔥 git pull = git fetch + merge

🧩 git blame

git blame [파일명]
  • 파일의 특정 코드를 누가 작성했는지 찾아내기 위한 커맨드

🧩 git revert

  • 이미 리모트 레포지토리에 올린 커밋을 되돌리는 커맨드
git revert [커밋 아이디]

📌 여러 커밋 취소하기

git revert [커밋 아이디1]...[커밋 아이디2]
  • 커밋 아이디1은 포함되지 않고, Reset이 진행된다.

🧩 git reflog(reference log)

  • HEAD가 이때까지 가르켜왔던 커밋들을 기록한 것
git reflog

🧩 git rebase

  • 커밋을 재배치
git rebase [브렌치 이름]
  • conflict가 발생하여 정상적으로 진행되지 못한 rebase를 계속 진행하는 커맨드
git rebase --continue

🔥 merge , rebase 차이
1. rebase는 새로운 커밋을 만들지 않음
2. rebase로 만들어진 커밋 히스토리는 merge로 만들어진 커밋 히스토리보다 깔끔

merge와 rebase의 결과는 같지만, 히스토리를 깔끔하게 만들기 위해서 사용


🧩 git stash (stack)

  • working directory에서 작업하던 내용을 git이 따로 보관
  • 최근 커밋 이후로 작업 했던 내용은 모두 스택에 옯겨지고, working directory 내부는 다시 최근 커밋의 상태로 초기화
git stash
  • 스택에 저장한 값 불러오기
git stash apply [아이디]
  • 스택에 저장한 값 삭제하기
git stash drop [아이디]
  • 저장한 값 보기
git stash list
  • 저장한 값 불러오면서, 스택에서 삭제
git stash pop [아이디]

📌 잘못된 브랜치에서 작업하는 실수를 할 때

  1. git stash 을 사용해 stack 내용을 저장
  2. 원하는 브랜치로 이동해서 다시 git stash apply

🔥 나중에 또 쓸 필요가 있는 작업내용이다 -> git stash apply
🔥 아니다 나중에 쓸필요 없다 -> gti stash pop


🧩 git cherry-pick

  • '좋은것만 골라 먹는다' 라는 뜻
  • 원하는 작업이 들어있는 커밋의 내용만 가져오는 커맨드
git cherry-pick [아이디]
profile
해보고 싶은거 하기

0개의 댓글