Git

<Git> Git 이론, 원리, 명령어

이게왜 2024. 5. 10. 09:35

일반적인 버전관리와 Git 버전 관리 방식의 차이

  • 일반적인 버전 관리 : 파일 기반 → 중복된 내용이 계속 쌓여가기에 용량 비효율적
  • Git 버전 관리 : Diff(변경사항) 기반 → 변경된 내용만 쌓여가기에 용량 효율적


Git 시작하기 2가지 방식 : Remote에서 시작 or Local에서 시작

  • 초기 시작 : Local → Remote에 Push
  • 가져오기 : Remote → Local로 Clone


Local(Git)과 Remote(Github) 보안 통신은 SSH 사용 / 설정법

Github 은 Remote와 Local 간 보안 통신 방법으로 2가지 방식을 제시한다 : HTTPS & SSH

  • HTTPS : 명시적으로 ID/PW를 매번 작성해야 하기에, 키로거 공격 위험 및 실제 사용 시 번거로움이 있다.
  • SSH : SSH를 위한 비대칭키를 사용하여, 명시적으로 ID/PW 와 같은 키 입력이 없이 정말 간단히 통신 가능

ssh-keygen -t ed25519 -C "name@example.com" : SSH 생성기로 비공개/공개키 생성

Github Settings 설정 → SSH and GPG keys 내 SSH keys 등록 (Authentication Key 타입)

 


Local Repository에서 시작하기 : 초기 시작 - 처음 프로젝트를 시작할 때 방식

Local(Git) 내 Git 초기 설정 후 → Remote(Github)의 새 Repository로 Push

  • Local(Git) 내 작업 중인 프로젝트를 git init으로 Git 초기 설정 후
    • **git init : 현재 내 디렉터리를 Git으로 관리하겠다는 것을 선언한다**
  • Remote(Github)의 새 Repository로 Push

 

  1. git init : 현재 작업 중인 프로젝트를 Git으로 관리하겠다는 선언
  2. git branch -M main : 디폴트 브랜치 명칭 변경 ← master 가 아닌 main이라는 비차별 명칭
  3. git remote add origin git@github.com:aaron/example.git
  4. git push -u origin main 

Remote Repository에서 시작하기 : 가져오기 - 협업, 현업에서 일반적 방식

Remote(Github)에서 새 Repository 생성 후 → Local(Git)에 Clone으로 가져오기

  1. Remote(Github)에 새 Repository 생성 후
    • 이미 누군가 자신의 Local에서 git init을 통해 Git 설정한 뒤 Remote에 업로드했을 수 있다.
      • 내 로컬로 가져와서 이어서 작업을 진행하면 된다
  2. Local(Git)에서 git clone을 통해 Remote(Github)에 있는 소스 코드 가져오기
    • git clone git@github.com:aaron/example.git

로컬에서 Git Branch 및 Remote 주소 기본 설정

 

Local에서 Branch를 설정하는 방법 : CRUD

Read

  • git branch -r
  • git branch -l
  • git branch -a

Create

  • git checkout -b example-branch
  • git checkout example-branch

Delete

  • git branch --delete/-D example-branch
  • git push --delete/-D origin example-branch

remote에서 가져오는 방법 : git fetch -p → -p = prune


Local에서 Remote를 설정하는 방법 : CRUD

 

Read

  • git remote -v → -v = verbose : 상세 출력 

Create

  • git remote add origin git@github.com:aaron/example.git

Update

  • git remote set-url origin git@github.com:aaron/example.git

Delete

  • git remote remove origin

 


로컬에서 Git(Local)과 Github(Remote) 동기화

 

  • fetch : 원격 Github Repository에서 생성/삭제된 브랜치를 가져오는 것뿐만 아닌 최신 코드 모두 가져오기
    • 명령어 : git fetch -p
    • -p = prune
  • Merge : 로컬에 가져온 “원격 브랜치의 최신 코드”를 “로컬 브랜치의 구식 코드”에 합치는 작업


Merge 종류 : (1) Fast-Forward (2) 3-Way Merge (3) Squash Merge

  • Fast-Forward : Remote에 내 작업과 겹치는 어떠한 타인의 작업도 없을 때, 그대로 이어 붙이기
  • 3-Way Merge : Remote에 있는 타인의 작업 그대로, 내 작업 그대로 보존하고 머지 커밋 생성
  • Squash Merge : Remote에 있는 타인의 작업 기준으로 다시 내가 작업하여 하나의 커밋으로 뭉쳐 생성


로컬에서 Git(Local)과 Github(Remote) 동기화 시 Conflict 충돌

  • Conflict 충돌이 발생한다는 것은 어떤 의미인가?
    • 동료 개발자들이(Git, Local) 같은 파일에 각자 다른 작업을 수행하여 이 둘을 어떻게든 합쳐야 한다는 뜻


Conflict 충돌 해결 방법 2가지 : Rebase & Merge

  • Rebase : 현재 내 작업물의 (기준이 되는) (1) Base를 다시 재설정한 뒤, (2) 다시 커밋을 쌓는다
    • 단점 : 내가 작업했던 커밋들이 다시 생성되기에, 히스토리가 리셋된다.
  • Merge : 현재 내 작업물과 Remote에 업로드되어 있는 상대 작업물 모두 존중하고, 머지 커밋을 만든다
    • 단점 : merge 커밋이 생성되어서 merge 수가 많아짐에 따라 커밋이 지저분해진다

Rebase & Merge 원리

 

Rebase & Merge  단점

- Rebase 단점 : 내가 작업했던 커밋들이 다시 생성되기에, 히스토리가 리셋된다.

- Merge 단점 : merge 커밋이 생성되어서 merge 수가 많아짐에 따라 커밋이 지저분해진다


Git 내 영역별 의미 및 용례

  • remote
  • local
    • working directory : 로컬 작업공간에서 작업할 브랜치 선택 → git checkout
      • tracked : Git이 추적하는 파일
        • Staging Area, Index : Commit 되기 위해 대기 중인 파일 (대기조) → git commit
        • Unstaged : Git 추적하는 파일 수정된 파일들의 집합
      • Untracked :Git 추적하지 않는 파일


File 삭제

명령어로 삭제하기 git rm <file>

  • Staging Area로 바로 올려 Commit 시 바로 삭제
  • Git Repository에서 삭제 예정(Staging) + Local에서 삭제

 

파일을 그냥 삭제하기 (마우스 우클릭이든, 리눅스 명령어든)

  • Unstaged에 올려 개발자가 한번 검토한 후 Staging Area에 올리도록 함
  • Git Repository에서 삭제 검토(Unstaged) + Local에서 삭제

명령어로 삭제하기 git rm --cached <file>

  • Staging Area로 바로 올려 Commit 시 바로 삭제되도록 함 (동시에 Untracked에서 나만 보기)
  • Git Repository에서 삭제 예정(Staging) + Local에서 사용

파일수정 : add, restore

모든 파일 변경 내용은 Unstaged 상태로. Commit 할 것들만 선택적으로 Staging Area로 전달

  • git add <file> : 변경된 파일 하나만 지목하여 Staging Area로 전달
  • git add. : 모든 파일 변경 사항들을 한 번에 Staging Area로 전달
  • git add -p : 모든 파일 변경 사항들을 작은 단위로 세부적으로 확인하며 Staging Area로 전달전달
    • y = yes : 현재 보고 있는 hunk를 add(stage) 합니다.
    • n = no : 현재 보고 있는 hunk를 add(stage) 하지 않습니다.
    • q = quit : 현재 add(stage) 과정 종료 = add 할 건 다 끝나서 더 이상 볼 필요 없을 때
    • s = small : 현재 보고 있는 hunk를 더 작은 단위의 hunk로 나눕니다.
    • e = edit : 현재 보고 있는 hunk 내용을 직접 편집합니다.
  • Staging Area로 전달한 것을 다시 복구시키고 싶다면
    • git restore --staged <file> : Staging Area → Unstaged (git add 이전)
    • git restore <file> : Unstaged → (Unmodifed) (수정 이전)

 

  1. --staged 옵션 따라 Staging Area에서 롤백할지 Unstaged에서 롤백할지 결정
  2. 추가, 삭제, 수정 시나리오에 따라 이전 상태 달리 정의
    1.  --staged 옵션이 있으면 : Staging Area에서 롤백
      • 삭제할 파일의 이전 상태 = Unstaged에서 대기 : Staging Area에서 → Unstaged로 이동
      • 수정된 파일의 이전 상태 = Unstaged에서 대기 : Staging Area에서 → Unstaged로 이동
      • 추가된 파일의 이전 상태 = Untracked : Staging Area에서 → Untracked로 이동--staged 옵션이 없으면 : Unstaged에서 롤백 (아무 일도 없던 것처럼 깨끗이 롤백)
        • 삭제할 파일의 이전 상태 = 미삭제(존재) : Unstaged에서 → 기존 Git 이 추적하던 파일 존재
        • 수정된 파일의 이전 상태 = 미수정 : Unstaged에서 → 기존 Git 이 추적하던 파일의 이전 상태
    2. --staged 옵션이 없으면 : Unstaged에서 롤백 (아무 일도 없던 것처럼 깨끗이 롤백)
      • 삭제할 파일의 이전 상태 = 미삭제(존재) : Unstaged에서 → 기존 Git 이 추적하던 파일 존재
      • 수정된 파일의 이전 상태 = 미수정 : Unstaged에서 → 기존 Git 이 추적하던 파일의 이전 상태


Git 트러블슈팅

직전 커밋에 대한 간단 수정

Amend 

git commit --amend

 

다시 생성 (롤백) 

Reset : git reset HEAD~1

  • --soft : Staging Area
  • --mixed (Default) : Unstaged/Untracked
  • --hard : 완전히 없애는 것

 

다시 생성 : Rebase - git rebase -i HEAD~3

날려 먹었을 때 : Reflog - git reflog --no-abbev