Git 완벽 가이드: 핵심 개념, 명령어 심화 학습 및 심층 비교

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 작업 흐름 개요
  1. 수정: 작업 디렉토리에서 파일을 수정합니다.
  2. 스테이징: git add 명령어를 사용하여 수정된 파일을 작업 디렉토리에서 스테이징 영역으로 이동시킵니다.
  3. 커밋: git commit 명령어를 사용하여 스테이징 영역의 스냅샷을 로컬 저장소에 영구히 저장하여 새 커밋을 만듭니다.
  4. 동기화: 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은 현재 디렉토리 아래에 원격 저장소와 동일한 이름의 디렉토리(로컬 디렉토리 이름을 지정하지 않은 경우)를 생성하고, 원격 저장소의 모든 히스토리를 로컬에 다운로드합니다.
    • 다음 작업을 자동으로 수행합니다:
      1. 원격 저장소의 이름을 origin으로 지정합니다 (별칭).
      2. 로컬 main (또는 master) 브랜치가 원격 origin/main (또는 origin/master) 브랜치를 추적하도록 설정합니다.
      3. 원격 저장소의 기본 브랜치를 로컬 작업 디렉토리로 체크아웃합니다.
    • 복제가 완료되면 로컬에서 개발, 커밋 및 원격 저장소와의 동기화를 수행할 수 있습니다.
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 수정
      
  • 상세 설명: origingit 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 (커밋할 게 없음, 작업 트리 깔끔함): 모든 변경 사항이 커밋되었고, 작업 디렉토리에 스테이징되지 않은 수정 사항이 없습니다.
  • 일반적인 옵션:
    • 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 -ugit add .의 기능을 합친 것과 같습니다.
      • 참고: 현재 디렉토리뿐만 아니라 전체 작업 트리의 변경 사항을 처리합니다.
      • 적용 시나리오: 모든 변경 사항(수정, 추가, 삭제)을 빠짐없이 한 번에 스테이징하고 싶을 때 가장 안전하고 포괄적인 방법입니다.

태그: Git 버전 관리 분산 버전 관리 Git 명령어 Git 개념

8월 6일 08:16에 게시됨