Git 완벽 가이드: 핵심 개념, 명령어 심화 학습 및 심층 비교
Git은 분산 버전 관리 시스템으로, 프로젝트 코드를 효율적이고 유연하게 관리하고 팀 협업을 지원합니다. Git을 능숙하게 다루는 것은 개발자의 기본 기술일 뿐만 아니라, 작업 효율성과 코드 품질을 향상시키는 핵심입니다.
1. Git 핵심 개념 및 작동 원리
Git의 내부 메커니즘을 이해하는 것은 효율적인 사용의 기본입니다.
1.1 Git의 세 가지 영역: 작업 디렉토리, 스테이징 영역, 로컬 저장소
- 작업 디렉토리 (Working Directory)
- 정의: 사용자 컴퓨터에서 실제로 보고 편집하며 작업하는 파일 및 디렉토리입니다. 코드 개발이 이루어지는 곳입니다.
- 상태: 파일은 "수정되지 않음", "수정됨", 또는 "추적되지 않음" 상태일 수 있습니다.
- 스테이징 영역 (Staging Area / Index)
- 정의: 작업 디렉토리와 로컬 저장소 사이에 있는 캐시 영역입니다. 이는 다음 커밋에 포함될 파일의 스냅샷을 기록하는 파일(
.git/index에 위치)입니다. - 역할: 각 커밋의 내용을 정밀하게 제어할 수 있게 해줍니다. 작업 디렉토리의 변경 사항 중 일부만 선택적으로 스테이징 영역에 추가하고, 여러 번
git add를 수행하여 논리적으로 명확한 커밋을 점진적으로 구성할 수 있습니다.
- 정의: 작업 디렉토리와 로컬 저장소 사이에 있는 캐시 영역입니다. 이는 다음 커밋에 포함될 파일의 스냅샷을 기록하는 파일(
- 로컬 저장소 (Local Repository)
- 정의: 프로젝트 루트 디렉토리 아래 숨겨진
.git폴더입니다. 모든 커밋 객체, 브랜치 포인터, 태그, 설정 등 프로젝트의 모든 버전 기록 정보를 포함합니다. - 역할: 프로젝트의 완전한 히스토리를 저장합니다. 네트워크 연결 없이도 커밋, 히스토리 조회, 브랜치 전환 등의 작업을 수행할 수 있습니다.
- 정의: 프로젝트 루트 디렉토리 아래 숨겨진
1.2 HEAD 포인터와 브랜치
- HEAD:
- 정의: 현재 작업 중인 브랜치의 최신 커밋을 항상 가리키는 특별한 포인터입니다.
- 역할: 현재 작업 디렉토리와 스테이징 영역이 기반하고 있는 커밋을 식별합니다. 새 커밋을 만들면 HEAD는 현재 브랜치와 함께 앞으로 이동합니다.
- 브랜치 (Branch):
- 정의: 특정 커밋을 가리키는 가볍고 이동 가능한 포인터입니다. 기본 브랜치는 일반적으로
main또는master입니다. - 역할: 메인 개발 라인에 영향을 주지 않고 병렬로 작업할 수 있게 해줍니다. 각 브랜치는 프로젝트 히스토리 내의 독립적인 개발 경로를 나타냅니다.
- 정의: 특정 커밋을 가리키는 가볍고 이동 가능한 포인터입니다. 기본 브랜치는 일반적으로
1.3 원격 저장소와 원격 추적 브랜치
- 원격 저장소 (Remote Repository):
- 정의: GitHub, GitLab, Gerrit 등 네트워크 상에 호스팅된 Git 저장소로, 팀 구성원 간 코드 공유 및 협업에 사용됩니다.
- 역할: 팀 협업의 중앙 허브 역할을 하며, 코드 동기화, 백업 및 배포를 용이하게 합니다.
- 원격 추적 브랜치 (Remote-tracking Branch):
- 정의: 로컬 저장소에 있는 원격 저장소 브랜치의 참조입니다 (예:
origin/main). 마지막으로 원격 저장소와 통신했을 때의 원격 브랜치 위치를 반영하는 읽기 전용 로컬 포인터입니다. - 역할: 실제로 원격 브랜치로 전환하지 않고도 원격 브랜치의 최신 상태를 알 수 있게 해줍니다. 직접 작업할 수 있는 브랜치가 아닙니다.
- 정의: 로컬 저장소에 있는 원격 저장소 브랜치의 참조입니다 (예:
1.4 Git 객체 모델 (Blob, Tree, Commit, Tag)
Git은 내부적으로 데이터를 네 가지 기본 객체로 저장합니다:
- Blob (Binary Large Object): 파일의 내용을 저장합니다. 각 파일의 내용은 고유한 Blob 객체를 가집니다.
- Tree (트리 객체): 디렉토리 구조와 파일 이름의 매핑을 저장합니다. Blob 객체(파일) 및 다른 Tree 객체(하위 디렉토리)에 대한 포인터를 포함합니다.
- Commit (커밋 객체): 특정 시점의 프로젝트 스냅샷을 저장합니다. 다음을 포함합니다:
- Tree 객체에 대한 포인터 (프로젝트 루트 디렉토리의 스냅샷).
- 작성자 정보, 커밋터 정보, 커밋 시간.
- 커밋 메시지.
- 하나 이상의 부모 커밋에 대한 포인터 (일반적으로 하나이며, 병합 커밋은 여러 개).
- Tag (태그 객체): 특정 커밋을 가리키는 영구적인 참조로, 주로 릴리스 버전을 표시하는 데 사용됩니다.
1.5 Git 작업 흐름 개요
- 수정: 작업 디렉토리에서 파일을 수정합니다.
- 스테이징:
git add명령어를 사용하여 수정된 파일을 작업 디렉토리에서 스테이징 영역으로 이동시킵니다. - 커밋:
git commit명령어를 사용하여 스테이징 영역의 스냅샷을 로컬 저장소에 영구히 저장하여 새 커밋을 만듭니다. - 동기화:
git push명령어를 사용하여 로컬 저장소의 커밋을 원격 저장소로 보내거나,git pull명령어를 사용하여 원격 저장소의 업데이트를 로컬 저장소로 가져옵니다.
2. Git 기본 설정 및 저장소 관리
2.1 git config: Git 환경 설정
- 목적: 사용자 정보, 편집기, 별칭, 줄 바꿈 처리 등 Git의 동작을 설정합니다.
- 적용 범위:
--system: 시스템 수준, 모든 사용자와 모든 저장소에 적용됩니다 (보통 관리자 권한 필요).--global: 사용자 수준, 현재 사용자의 모든 저장소에 적용됩니다.--local(기본값): 저장소 수준, 현재 저장소에만 적용됩니다.
- 일반적인 사용법:
# 전역 사용자 이름 설정 (커밋 기록의 Author용) git config --global user.name "Your Name" # 전역 사용자 이메일 설정 git config --global user.email "your.email@example.com" # 모든 설정 확인 git config --list # 특정 설정 확인 git config user.name # 기본 텍스트 편집기 설정 (예: VS Code, Vim) git config --global core.editor "code --wait" # VS Code git config --global core.editor "vim" # Vim # Git 별칭 설정 (단축키) git config --global alias.co checkout # git checkout = git co git config --global alias.br branch git config --global alias.ci commit git config --global alias.st status git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" # 줄 바꿈 자동 변환 설정 (특히 크로스 플랫폼 협업 시 중요) # Windows 사용자 권장: git config --global core.autocrlf true # Linux/macOS 사용자 권장: git config --global core.autocrlf input - 상세 설명:
core.autocrlf는 Windows(CRLF)와 Unix/Linux(LF) 간의 줄 바꿈 규칙 차이를 처리합니다.true는 Git이 커밋 시 CRLF를 LF로 변환하고, 체크아웃 시 LF를 CRLF로 다시 변환함을 의미합니다.input은 Git이 커밋 시 CRLF를 LF로 변환하지만, 체크아웃 시에는 변환하지 않음(LF 유지)을 의미합니다.
2.2 git init: 로컬 저장소 초기화
- 목적: 빈 디렉토리 또는 기존 프로젝트 디렉토리에 빈 Git 저장소를 생성합니다.
- 사용법:
mkdir my_new_project cd my_new_project git init - 상세 설명:
git init를 실행하면 현재 디렉토리에.git숨김 폴더가 생성됩니다. 이 폴더가 로컬 저장소이며, Git이 프로젝트를 관리하는 데 필요한 모든 메타데이터를 포함합니다. 이 시점에서 작업 디렉토리와 스테이징 영역은 비어 있지만, 파일을 받을 준비가 된 상태입니다.
2.3 git clone: 원격 저장소 복제
- 목적: 원격 저장소에서 모든 히스토리와 브랜치를 포함한 전체 저장소를 로컬에 복사합니다.
- 사용법:
git clone <원격 저장소 URL> [로컬 디렉토리 이름] # 예시: git clone https://github.com/user/repo.git MyProject - 상세 설명:
git clone은 현재 디렉토리 아래에 원격 저장소와 동일한 이름의 디렉토리(로컬 디렉토리 이름을 지정하지 않은 경우)를 생성하고, 원격 저장소의 모든 히스토리를 로컬에 다운로드합니다.- 다음 작업을 자동으로 수행합니다:
- 원격 저장소의 이름을
origin으로 지정합니다 (별칭). - 로컬
main(또는master) 브랜치가 원격origin/main(또는origin/master) 브랜치를 추적하도록 설정합니다. - 원격 저장소의 기본 브랜치를 로컬 작업 디렉토리로 체크아웃합니다.
- 원격 저장소의 이름을
- 복제가 완료되면 로컬에서 개발, 커밋 및 원격 저장소와의 동기화를 수행할 수 있습니다.
2.4 git remote: 원격 저장소 연결 관리
- 목적: 로컬 저장소와 원격 저장소 간의 연결 정보를 관리합니다.
- 사용법:
git remote -v # 모든 원격 저장소의 이름과 URL 나열 (상세 모드) git remote add <이름> <URL> # 새 원격 저장소 연결 추가 # 예시: git remote add upstream https://github.original.com/repo.git git remote rm <이름> # 원격 저장소 연결 삭제 git remote rename <이전 이름> <새 이름> # 원격 저장소 연결 이름 변경 git remote set-url <이름> <새 URL> # 원격 저장소의 URL 수정 - 상세 설명:
origin은git clone이 자동으로 생성해주는 기본 원격 저장소 이름입니다.upstream과 같이 여러 개의 원격 저장소를 추가할 수 있습니다. 예를 들어,upstream은 원본 상위 저장소를 가리키고,origin은 사용자의 Fork를 가리키도록 설정할 수 있습니다.
3. 일상 개발: 파일 상태 및 로컬 커밋
3.1 git status: 작업 디렉토리 상태 확인
- 목적: 작업 디렉토리와 스테이징 영역에 있는 파일의 현재 상태를 표시하여, 어떤 파일이 수정되었는지, 어떤 파일이 스테이징되었는지, 어떤 파일이 추적되지 않는지 파악할 수 있게 해줍니다.
- 사용법:
git status - 상세 설명:
- Untracked files (추적되지 않는 파일): 새로 생성된 파일로, Git이 아직 추적을 시작하지 않았습니다. 버전 관리에 포함시키려면
git add가 필요합니다. - Changes to be committed (커밋할 변경 사항): 스테이징 영역에 추가된 파일로, 다음
git commit시 이 변경 사항들이 포함됩니다. - Changes not staged for commit (커밋을 위해 스테이징되지 않은 변경 사항): 수정되었지만 아직 스테이징 영역에 추가되지 않은 파일입니다.
- nothing to commit, working tree clean (커밋할 게 없음, 작업 트리 깔끔함): 모든 변경 사항이 커밋되었고, 작업 디렉토리에 스테이징되지 않은 수정 사항이 없습니다.
- Untracked files (추적되지 않는 파일): 새로 생성된 파일로, Git이 아직 추적을 시작하지 않았습니다. 버전 관리에 포함시키려면
- 일반적인 옵션:
git status -s또는git status --short: 간결한 형식으로 상태를 표시하며, 각 파일을 한 줄씩 두 글자로 상태를 나타냅니다 (예:M는 수정되었지만 스테이징 안 됨,MM은 스테이징 영역에 추가되었지만 작업 디렉토리에서 다시 수정됨).
3.2 git add: 파일을 스테이징 영역에 추가
- 목적: 작업 디렉토리의 변경 사항(새 파일, 수정, 삭제)을 스테이징 영역에 추가하여 커밋을 준비합니다.
- 사용법:
git add <파일명> # 지정된 파일 추가 git add dir/ # 지정된 디렉토리 아래 모든 파일 추가 - 상세 설명:
git add는 파일을 저장소에 "추가"하는 것이 아니라, 작업 디렉토리에 있는 파일의 현재 상태 스냅샷을 스테이징 영역에 기록합니다. 다음git commit시 이 스테이징 영역의 스냅샷을 기반으로 커밋이 생성됩니다. - 유사 명령어 비교:
git add .:- 역할: 현재 디렉토리 및 그 하위 디렉토리에 있는 모든 수정된 파일과 새로 생성된 파일을 스테이징 영역에 추가합니다.
- 참고: 삭제된 파일은 포함하지 않습니다. Git 2.0 이전 버전에서는 디렉토리 이름 변경도 처리하지 않았습니다.
- 적용 시나리오: 모든 수정 및 새 파일을 커밋하려 하고, 삭제된 파일이 없을 때 사용합니다.
git add -u(또는--update):- 역할: 모든 수정된 파일과 삭제된 파일을 스테이징 영역에 추가합니다.
- 참고: 새로 생성된 추적되지 않는 파일은 포함하지 않습니다.
- 적용 시나리오: 기존 파일의 수정 및 삭제에만 집중하고, 새 파일을 현재 커밋에 포함시키고 싶지 않을 때 사용합니다.
git add -A(또는--all):- 역할: 모든 변경 사항(수정, 새 파일, 삭제)을 스테이징 영역에 추가합니다.
git add -u와git add .의 기능을 합친 것과 같습니다. - 참고: 현재 디렉토리뿐만 아니라 전체 작업 트리의 변경 사항을 처리합니다.
- 적용 시나리오: 모든 변경 사항(수정, 추가, 삭제)을 빠짐없이 한 번에 스테이징하고 싶을 때 가장 안전하고 포괄적인 방법입니다.
- 역할: 모든 변경 사항(수정, 새 파일, 삭제)을 스테이징 영역에 추가합니다.