일반적인 버전관리와 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 키 생성기로 비공개/공개키 생성
- 출처 : SSH Keygen을 통한 새로운 SSH 키 생성 → 생성한 SSH 키 Github 내 등록
- 꼭, passphrase 설정하지 않도록! 주의!
- passphrase 설정 시 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
- git init : 현재 작업 중인 프로젝트를 Git으로 관리하겠다는 선언
- git branch -M main : 디폴트 브랜치 명칭 변경 ← master 가 아닌 main이라는 비차별 명칭
- git remote add origin git@github.com:aaron/example.git
- git push -u origin main
Remote Repository에서 시작하기 : 가져오기 - 협업, 현업에서 일반적 방식
Remote(Github)에서 새 Repository 생성 후 → Local(Git)에 Clone으로 가져오기
- Remote(Github)에 새 Repository 생성 후
- 이미 누군가 자신의 Local에서 git init을 통해 Git 설정한 뒤 Remote에 업로드했을 수 있다.
- 내 로컬로 가져와서 이어서 작업을 진행하면 된다
- 이미 누군가 자신의 Local에서 git init을 통해 Git 설정한 뒤 Remote에 업로드했을 수 있다.
- 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 이 추적하지 않는 파일
- tracked : Git이 추적하는 파일
- working directory : 로컬 작업공간에서 작업할 브랜치 선택 → git checkout
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) (수정 이전)
- --staged 옵션에 따라 Staging Area에서 롤백할지 Unstaged에서 롤백할지 결정
- 추가, 삭제, 수정 시나리오에 따라 이전 상태가 달리 정의
- --staged 옵션이 있으면 : Staging Area에서 롤백
- 삭제할 파일의 이전 상태 = Unstaged에서 대기 : Staging Area에서 → Unstaged로 이동
- 수정된 파일의 이전 상태 = Unstaged에서 대기 : Staging Area에서 → Unstaged로 이동
- 추가된 파일의 이전 상태 = Untracked : Staging Area에서 → Untracked로 이동--staged 옵션이 없으면 : Unstaged에서 롤백 (아무 일도 없던 것처럼 깨끗이 롤백)
- 삭제할 파일의 이전 상태 = 미삭제(존재) : Unstaged에서 → 기존 Git 이 추적하던 파일 존재
- 수정된 파일의 이전 상태 = 미수정 : Unstaged에서 → 기존 Git 이 추적하던 파일의 이전 상태
- --staged 옵션이 없으면 : Unstaged에서 롤백 (아무 일도 없던 것처럼 깨끗이 롤백)
- 삭제할 파일의 이전 상태 = 미삭제(존재) : Unstaged에서 → 기존 Git 이 추적하던 파일 존재
- 수정된 파일의 이전 상태 = 미수정 : Unstaged에서 → 기존 Git 이 추적하던 파일의 이전 상태
- --staged 옵션이 있으면 : Staging Area에서 롤백
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