컴퓨터과학과

Git 종합 가이드

공부하는노년 2025. 3. 12. 11:23
반응형

Git의 기본 개념부터 명령어, 브랜치 관리, 원격 저장소 사용법, 협업 방식, 고급 기능, 설정 및 환경 구성, 오류 해결까지 모두 정리합니다.

Git

Git 종합 가이드: 기본 개념부터 활용까지

소프트웨어 개발에서 Git은 가장 널리 쓰이는 버전 관리 도구입니다. 분산형 버전 관리 시스템(DVCS)의 대표격인 Git을 활용하면 파일 변경 이력 추적, 백업, 협업을 효율적으로 수행할 수 있습니다 (Git).

 

아래에서는 Git의 개념부터 주요 명령어, 브랜치 관리, 원격 저장소 활용법, 협업 방식, 고급 기능, 설정 방법, 그리고 자주 발생하는 오류 해결책까지 차근차근 정리합니다. 초보자도 이해할 수 있도록 친절한 설명과 실무에서 바로 활용 가능한 예제를 함께 제공합니다.

1. Git 기본 개념

Git이란?

Git은 2005년 리누스 토르발스(Linus Torvalds)가 개발한 무료 오픈소스 분산 버전 관리 시스템입니다 (Git). 버전 관리 시스템(VCS)은 파일의 변경 이력을 시간순으로 기록하여 필요할 때 과거 버전으로 돌아가거나 변경 사항을 비교할 수 있도록 해주는 도구입니다. 중앙집중식 VCS(Centralized VCS)와 달리, Git과 같은 분산형 VCS에서는 각 개발자마다 전체 저장소의 복사본(히스토리 포함)을 가지고 작업합니다 (Git - About Version Control). 이로써 모든 개발자가 원격 서버와 통신하지 않고도 로컬에서 커밋 역사 전체를 보유하고 작업할 수 있어 오프라인 작업이나 백업에 유리합니다.

Git의 핵심 특징을 요약하면 다음과 같습니다 (Git) (What is Git version control? | GitLab):

  • 분산형 구조: 중앙 서버 외에도 각 클라이언트(개발자)가 프로젝트의 전체 이력을 로컬에 저장하므로, 서버에 문제가 생겨도 로컬 저장소를 이용해 복구할 수 있습니다 (Git - About Version Control). 다시 말해, 각 클론이 완전한 백업 역할을 합니다.
  • 빠른 속도와 성능: Git은 C언어로 구현되어 매우 빠른 동작을 보이며, 대규모 프로젝트도 효율적으로 처리합니다 (Git). 로컬에서 대부분의 작업이 이루어지므로 네트워크 지연 없이 즉각적인 버전 비교나 히스토리 검색이 가능합니다 (What is Git version control? | GitLab).
  • 작은 크기와 효율성: 분산형임에도 불구하고 저장소 용량 효율이 높고, 변경된 부분만 저장(델타 저장)하여 공간을 절약합니다.
  • 강력한 분기(branched)와 병합(merged) 기능: Git은 저렴한 로컬 브랜칭쉬운 병합을 제공하여 개발자들이 실험적인 변경을 자유롭게 시도하고, 나중에 메인 본(branch)에 합칠 수 있게 해줍니다 (Git). 브랜치의 생성, 삭제가 가벼우며 여러 워크플로우를 유연하게 지원합니다 (Git).
  • 스테이징 영역: Git만의 독특한 개념으로, 작업 트리(working directory)에서 커밋 사이에 인덱스(index) 또는 스테이징 영역(stage)를 둡니다. 이를 통해 커밋에 포함할 변경사항을 선택적으로 모아둔 후 한꺼번에 기록할 수 있습니다 (Git).
  • 신뢰성과 데이터 무결성: Git은 SHA-1 해시를 이용해 커밋, 파일, 브랜치 등의 객체를 관리하므로, 데이터 변조 여부를 쉽게 감지할 수 있고 히스토리가 안전하게 보존됩니다. 또한 여러 개발자가 각각 전체 이력을 보유하므로 하나의 저장소 손상으로 전체 기록을 잃을 위험이 적습니다 (What is Git version control? | GitLab).
  • 협업과 분산 워크플로: Git은 중앙집중식 모델뿐 아니라 다양한 협업 워크플로우를 지원합니다. 예를 들어 개발자들 각자가 기능 브랜치를 만들어 작업한 뒤 메인 브랜치에 통합하거나, 저장소를 포크(fork)하여 풀 리퀘스트(PR)를 보내는 등 유연한 협업이 가능합니다 (What is Git version control? | GitLab) (What is Git version control? | GitLab).

분산 버전 관리 모델 개념도

 

위 그림은 분산형 버전 관리의 개념도입니다. 중앙 서버가 존재하더라도, 각 개발자 컴퓨터(A, B)가 버전 데이터베이스(프로젝트 이력)의 전체 사본을 가지고 있음을 보여줍니다. 개발자들은 서로 또는 서버와 데이터를 주고받으며 작업 내용을 동기화합니다.

 

이처럼 Git에서는 중앙 저장소가 일시적으로 다운되더라도 다른 개발자의 저장소를 이용해 데이터를 복구할 수 있고, 개발자들이 동시에 서로 다른 장소에서 비동기적으로 작업할 수 있다는 장점이 있습니다 (Git - About Version Control) (What is Git version control? | GitLab).

 

반면 기존의 중앙집중식 VCS에서는 한 곳에만 이력이 저장되므로 서버 장애 시 협업이 중단되고, 백업을 소홀히 하면 단일 장애점(single point of failure) 문제가 발생할 수 있었습니다 (Git - About Version Control). Git의 분산 구조는 이러한 문제를 해결하여 안정성과 협업 생산성을 높였습니다.

 

요약하면, Git = 빠르고 강력한 분산형 버전관리 시스템입니다. 전 세계 개발자의 대다수가 Git을 사용하고 있으며, 사실상 현대 소프트웨어 개발 표준 도구로 자리매김했습니다. 이제 Git을 실제로 어떻게 사용하는지 기본 명령어를 알아보겠습니다.

2. Git 명령어 정리

Git을 효과적으로 사용하려면 기본적인 명령어들의 역할과 사용법을 이해해야 합니다.

 

Git에서는 파일이 수정됨(modified)스테이징됨(staged)커밋됨(committed)의 세 가지 상태를 가지며 (What is Git version control? | GitLab), 이러한 상태 전이를 관리하는 것이 주요 명령어들의 역할입니다. 아래에서는 Git 핵심 명령어들과 사용 방법을 정리합니다 (각 명령어는 CLI에서 git 접두사와 함께 사용합니다).

  • git init – 새 Git 저장소를 초기화하는 명령입니다. 현재 디렉토리에 .git 하위 폴더를 생성하여 그곳을 로컬 저장소로 만듭니다 (Basic Git Commands You Need to Know | Simplilearn). 프로젝트 시작 시 이 명령을 실행하면 Git이 해당 디렉토리의 버전 관리를 시작합니다.
    예시: 프로젝트 폴더에서 git init 을 실행 (성공 시 .git 폴더 생성).
  • git clone – 원격 저장소(repository)를 복제(Clone)하여 로컬에 새로운 Git 저장소를 만드는 명령입니다. 주로 GitHub/GitLab 등의 URL을 인자로 받아 실행하며, 실행 후 지정한 폴더에 원격 저장소의 모든 이력이 담긴 복사본이 생성됩니다 (Basic Git Commands You Need to Know | Simplilearn). git init이 빈 저장소를 만드는 것이라면, git clone <원격_URL>은 기존 저장소를 통째로 가져오는 명령입니다.
    예시: git clone https://github.com/user/project.git (현재 폴더 밑에 project 디렉토리 생성 및 복제).
  • git status – 현재 저장소의 상태를 확인하는 명령입니다. 어떤 파일이 수정되었고(staged/unstaged), 추가되었으며(untracked), 커밋할 변경사항이 있는지 등을 상세히 보여줍니다 (Basic Git Commands You Need to Know | Simplilearn). 이 명령으로 작업 디렉토리_와 _스테이징 영역_의 상태를 항상 확인하며 작업 흐름을 파악할 수 있습니다.
    _예시:
    git status (변경된 파일 목록과 상태 출력, 예: "Changes not staged for commit", "Untracked files" 등).
  • git add – 작업 디렉토리에서 변경하거나 새로 만든 파일을 스테이징 영역(stage)에 추가하는 명령입니다. 이렇게 staging된 파일들만 다음 커밋에 포함됩니다. git add <파일>로 특정 파일을 추가하거나, git add .로 현재 디렉토리의 모든 변경 파일을 추가할 수 있습니다 (Basic Git Commands You Need to Know | Simplilearn). 커밋 전에 반드시 git add를 통해 변경사항을 staging해야 함을 기억하세요.
    예시: git add index.html style.css (지정한 파일 둘을 stage), 또는 git add . (현재 폴더 내 변경된 모든 파일 stage).
  • git commit – 스테이징된 변경사항을 로컬 저장소에 커밋(확정)하는 명령입니다. 커밋은 버전 기록의 한 단위이며, 커밋할 때는 반드시 변경 내역을 나타내는 메시지를 남겨야 합니다 (옵션 -m "메시지" 사용) (Basic Git Commands You Need to Know | Simplilearn). 이 명령을 실행하면 Git이 스테이징된 파일들의 스냅샷을 영구히 저장소 이력에 기록하고, 커밋 ID(해시값)를 부여합니다.
    예시: git commit -m "Implement feature X" (현재 stage에 있는 변경들을 하나의 커밋으로 저장, 메시지는 "Implement feature X").
  • git branch – 브랜치를 조회하거나 생성/삭제하는 명령입니다. 인자 없이 실행하면 현재 로컬 저장소에 존재하는 브랜치 목록을 보여주고, * 표시로 현재 체크아웃된 브랜치를 표시합니다 (Basic Git Commands You Need to Know | Simplilearn). git branch <새브랜치명>으로 새로운 브랜치를 생성하고, git branch -d <브랜치명>으로 병합이 끝난 브랜치를 삭제할 수 있습니다 (Basic Git Commands You Need to Know | Simplilearn).
    예시: git branch feature/login (현재 커밋에서 'feature/login' 브랜치 생성), git branch -a (로컬과 원격의 모든 브랜치 목록 표시), git branch -d feature/login (브랜치 삭제).
  • git checkout브랜치를 전환하거나 특정 커밋으로 HEAD를 이동하는 명령입니다. git checkout <브랜치명>으로 해당 브랜치로 작업 위치를 변경할 수 있습니다 (Basic Git Commands You Need to Know | Simplilearn). 자주 쓰이는 옵션으로 -b를 주면 새 브랜치를 만들면서 동시에 그 브랜치로 체크아웃합니다 (Basic Git Commands You Need to Know | Simplilearn). (참고: 최신 Git에서는 git switch 명령이 브랜치 전환에 사용되기도 합니다.)
    예시: git checkout develop (develop 브랜치로 이동), git checkout -b feature/payment (새 브랜치 feature/payment 생성 후 이동).
  • git merge – 현재 체크아웃된 브랜치에 다른 브랜치의 변경 내용을 병합하는 명령입니다. 즉, 분기되어 독립적으로 진행된 두 작업 내역을 합치는 역할을 합니다 (Basic Git Commands You Need to Know | Simplilearn). git merge <브랜치명>을 실행하면 현재 브랜치에 지정한 브랜치의 최신 커밋을 통합합니다. 병합 시 자동으로 충돌이 없으면 Fast-forward되거나 merge-commit이 생성되고, 충돌(conflict)이 있으면 병합이 중단되어 사용자가 수동으로 충돌을 해결해야 합니다.
    예시: git merge feature/login (현재 브랜치에 feature/login 브랜치를 병합).
  • git remote – 원격 저장소(remote)를 추가/조회/삭제할 때 사용하는 명령입니다. git remote add <이름> <URL> 형태로 실행하여 현재 로컬 저장소에 원격 저장소를 연결합니다 (Basic Git Commands You Need to Know | Simplilearn). 일반적으로 기본 원격 이름으로 "origin"을 사용합니다. git remote -v로 설정된 원격 저장소 목록과 URL을 확인할 수 있습니다.
    예시: git remote add origin https://github.com/user/repo.git (현재 저장소에 'origin'이라는 이름으로 해당 GitHub 저장소 연결).
  • git push – 로컬 커밋들을 원격 저장소로 업로드(밀어넣기)하는 명령입니다. git push <원격이름> <브랜치> 형태로 사용하며, 보통 git push origin main처럼 사용합니다 (Basic Git Commands You Need to Know | Simplilearn). 최초 push 시 -u 옵션을 사용하면 해당 원격 브랜치와 로컬 브랜치의 추적 관계를 설정하여 이후부터는 git push만으로도 같은 브랜치에 push할 수 있습니다. 이 명령으로 팀원들과 작업내용을 공유하게 됩니다.
    예시: git push -u origin main (현재 로컬 main 브랜치를 origin 원격의 main 브랜치로 push하고 추적 설정).
  • git pull – 원격 저장소의 변경 이력을 가져와(local 가져오기+병합), 로컬 브랜치에 통합하는 명령입니다. 내부적으로 git fetch + git merge를 한꺼번에 수행합니다 (Basic Git Commands You Need to Know | Simplilearn). git pull <원격> <브랜치>로 사용하며, 보통 git pull origin main과 같이 현재 브랜치에 원격 main 브랜치의 변경사항을 병합합니다. 협업 시 다른 사람이 푸시한 커밋을 내 로컬에 반영하기 위해 자주 사용됩니다.
    예시: git pull origin main (원격 origin의 main 브랜치 변경사항을 가져와 현재 브랜치에 병합).

이 밖에도 자주 사용하는 명령으로 git log (커밋 이력 조회), git diff (변경 내용 비교) 등이 있으며, 필요시 git help <명령>으로 각 명령의 도움말을 볼 수 있습니다. 위 핵심 명령어들을 조합하면 다음과 같은 기본 작업 흐름이 이루어집니다:

새로운 저장소 시작 → (git init 또는 git clone) → 파일 수정 → (git add) → 스테이징된 변경 확인 (git status) → 커밋 생성 (git commit) → 원격에 푸시(git push) → 다른 변경 가져오기 (git pull).

이제 Git의 브랜치 개념과 이를 활용한 작업 방식에 대해 자세히 알아보겠습니다.

3. Git 브랜치(branch) 관리

브랜치(branch)는 Git에서 여러 작업 흐름을 동시에 관리하기 위한 핵심 기능입니다.

 

브랜치를 사용하면 하나의 코드베이스에서 서로 다른 실험이나 기능 개발을 독립적인 역사로 진행할 수 있습니다. 쉽게 말해, 브랜치는 커밋의 포인터이며 새로운 브랜치를 만들면 현재 시점의 커밋에서 갈라져나온 별도 작업 선로가 생기는 것입니다. Git은 브랜치 생성과 병합이 매우 가볍고 빠르므로, 개발자들은 메인(main) 브랜치를 보호하면서도 여러 가지 변경을 동시에 진행할 수 있습니다 (Git).

 

브랜치 생성: 새 브랜치를 만드는 방법은 두 가지가 있습니다. (1) git branch <브랜치명>으로 분기만 생성하거나, (2) git checkout -b <브랜치명>으로 브랜치를 생성과 동시에 체크아웃(전환)할 수 있습니다. 예를 들어 메인 브랜치에서 git checkout -b feature/login를 실행하면 'feature/login'이라는 새 브랜치를 만들고 그 브랜치에서 작업을 시작하게 됩니다. 이렇게 만들어진 브랜치는 원본(main) 브랜치로부터 분기되었으므로, 이후 해당 브랜치에서 이루어지는 커밋들은 main과 별개의 히스토리를 갖습니다.

 

브랜치 전환: 여러 브랜치를 오가며 작업하려면 git checkout <브랜치명> 명령을 사용합니다. 이때 현재 작업 트리에 적용되던 내용이 선택한 브랜치의 최신 커밋 상태로 바뀝니다. (Staged나 modified 상태의 변경이 남아있으면 전환이 안 되거나 충돌이 발생할 수 있으니, 전환 전 커밋하거나 stash해두어야 합니다.)

작업 병합(merge): 개발이 완료되면 분기된 브랜치의 변경 내용을 다시 메인 브랜치 등에 병합(merge)해야 합니다. 병합은 현재 체크아웃된 브랜치(예: main)에 대상 브랜치(예: feature 브랜치)의 일련의 커밋들을 합치는 작업입니다 (Basic Git Commands You Need to Know | Simplilearn). git merge <브랜치명>으로 병합을 수행하면 Git이 두 브랜치의 공통 조상부터 최신 커밋까지의 변화들을 자동으로 통합합니다.

  • Fast-forward 병합: 만약 병합 대상 브랜치(main)에 새로운 커밋이 없고, 단순히 feature 브랜치에서 앞서 나간 경우라면, Git은 main 브랜치의 포인터를 feature 브랜치의 마지막 커밋으로 앞으로 이동시키는 fast-forward 방식으로 병합합니다. 이 경우 별도의 _merge commit_이 생기지 않고 히스토리가 직선으로 이어집니다.
  • 3-way 병합: 두 브랜치 모두에서 변화가 일어난 경우, Git은 기본적으로 공통 조상 커밋을 기준으로 3-way 병합을 수행합니다. 이때 병합 결과를 표현하기 위한 새로운 커밋(merge commit)이 생성되며, 두 부모를 가지는 특별한 커밋으로 기록됩니다.

충돌(conflict)과 해결: 자동 병합 도중에 충돌이 발생할 수도 있습니다. 충돌은 간단히 말해 같은 파일의 같은 부분을 서로 다르게 수정한 경우에 발생합니다 (Resolving a merge conflict using the command line - GitHub Docs). 예를 들어, 개발자 A가 README.md의 10번째 줄을 수정했고 개발자 B도 10번째 줄을 다른 내용으로 수정했다면, 이 둘을 병합할 때 Git이 어느 쪽 변경을 적용해야 할지 결정하지 못해 충돌 상태로 남깁니다. 충돌이 나면 Git은 해당 충돌 파일에 특별한 표식으로 표시를 해줍니다:

<<<<<<< HEAD
개발자 A가 작업한 내용
=======
개발자 B가 작업한 내용
>>>>>>> other-branch

 

위와 같이 <<<<<<< HEAD=======, >>>>>>> 브랜치명 사이에 서로 충돌하는 두 버전의 코드가 나타납니다. 이 경우 개발자는 수동으로 충돌을 해결해야 합니다. 기본적인 충돌 해결 절차는 다음과 같습니다 (Resolving a merge conflict using the command line - GitHub Docs) (Resolving a merge conflict using the command line - GitHub Docs):

  1. git status로 어떤 파일에 충돌이 발생했는지 확인합니다. 충돌 파일들은 "Unmerged paths"로 표시됩니다.
  2. 문제가 된 파일을 텍스트 편집기로 열고 <<<<<<<, =======, >>>>>>> 마커를 찾아서 충돌 부분을 수정합니다. 둘 중 하나의 변경을 취하거나, 두 변경을 조합하거나, 필요하면 새로운 내용을 작성합니다. 최종적으로 남기고 싶은 코드만 남도록 편집하고, 충돌 표식 줄들은 모두 삭제합니다 (Resolving a merge conflict using the command line - GitHub Docs).
  3. 파일을 저장한 후 git add <파일>로 수정된 파일을 다시 staging합니다 (Git은 충돌이 해결되어 파일이 업데이트되었음을 인지).
  4. git commit으로 충돌 해결 내용을 커밋합니다 (커밋 메시지는 자동으로 "Merge branch '...' resolve conflict" 등으로 생성되거나 직접 작성할 수 있습니다) (Resolving a merge conflict using the command line - GitHub Docs). 이 커밋을 통해 병합이 완료됩니다.

충돌을 해결한 후 git log 등을 보면 병합 커밋이 생성된 것을 확인할 수 있습니다. 충돌을 피하려면 가능한 한 자주 원격 변경을 pull하여 다른 사람들의 변경과 빨리 통합하거나, 한 파일을 동시에 편집하는 상황을 팀 내에서 조율하는 것이 좋습니다.

 

브랜치 삭제: 병합이 완료되어 더 이상 필요 없는 브랜치는 정리하는 것이 좋습니다. git branch -d <브랜치명> 명령으로 로컬 브랜치를 삭제할 수 있습니다 (Basic Git Commands You Need to Know | Simplilearn). (만약 아직 병합되지 않은 커밋이 있다면 삭제가 거부되며, -D 옵션으로 강제 삭제도 가능합니다만 이 경우 커밋이 잃어버릴 수 있으니 주의해야 합니다.) 원격 브랜치도 삭제하려면 git push origin --delete <브랜치명>을 사용합니다.

Git 브랜치를 적절히 활용하면, 각 기능이나 이슈마다 별도 브랜치에서 개발하고 충분히 테스트한 후 메인 브랜치에 합치는 방식으로 개발 프로세스를 체계화할 수 있습니다. 예를 들어 많이 사용되는 Git Flow 프로세스에서는 개발용 브랜치(develop), 주요 배포 브랜치(main/master), 기능 브랜치(feature/), 릴리즈 브랜치(release/), 핫픽스 브랜치(hotfix/*) 등을 운용하여 병렬 개발과 안정적인 배포를 진행합니다.

4. Git과 원격 저장소

로컬 저장소의 작업 내용을 다른 사람과 공유하려면 원격 저장소(remote repository)를 이용해야 합니다. 원격 저장소는 보통 중앙 서버나 클라우드에 위치한 Git 저장소로, 여러 개발자가 여기에 push와 pull을 주고받으며 협업합니다. 유명한 Git 원격 호스팅 서비스로 GitHub, GitLab, Bitbucket 등이 있습니다. 이들 서비스는 Git 저장소를 저장할 뿐만 아니라 이슈 트래킹, 코드 리뷰(Pull Request), CI/CD 등 부가 기능을 제공하여 협업을 더욱 편리하게 해줍니다.

 

Git에서 원격 저장소를 사용하는 기본 방법은 다음과 같습니다:

  • 원격 추가 (git remote add): 먼저 로컬 저장소를 원격 저장소와 연결해야 합니다. 보통 GitHub이나 GitLab에서 새 저장소를 만들면 HTTPS 또는 SSH URL이 제공됩니다. 이 URL을 사용하여 git remote add origin <URL> 명령으로 원격을 추가합니다 (Basic Git Commands You Need to Know | Simplilearn). 관례적으로 첫 원격 이름은 "origin"으로 하며, origin을 기본 원격으로 간주합니다.
  • 복제 (git clone): 원격에 이미 저장소가 있다면, 앞서 언급한 git clone으로 원격 저장소를 내 컴퓨터에 처음 받아옵니다 (Basic Git Commands You Need to Know | Simplilearn). clone 시 자동으로 origin 원격이 설정되고, 기본 브랜치까지 체크아웃됩니다.
  • 푸시 (git push): 로컬에서 커밋한 변경들을 원격 저장소에 업로드하려면 git push 명령을 사용합니다 (Basic Git Commands You Need to Know | Simplilearn). 예를 들어 git push origin main은 내 로컬 main 브랜치의 새 커밋들을 origin 원격의 main 브랜치에 밀어넣습니다. 앞서 설명했듯, 최초 한 번은 -u 옵션으로 upstream(추적) 브랜치를 설정해두면 이후로는 브랜치 이름 생략 가능입니다. git push를 하면 원격 저장소의 해당 브랜치에 내 커밋이 추가되어, 다른 협업자들이 그 변경을 볼 수 있게 됩니다.
  • 풀 (git pull): 다른 이가 원격에 푸시한 내용을 내 로컬로 가져오려면 git pull을 사용합니다 (Basic Git Commands You Need to Know | Simplilearn). 이 명령은 원격 저장소의 변경(commits)을 가져와 현재 브랜치에 병합까지 수행하므로, 한 명령으로 내 로컬을 최신 상태로 업데이트해줍니다. 예를 들어 git pull origin main을 실행하면, origin의 main 브랜치 커밋 내역을 fetch하고 내 현재 브랜치에 merge합니다. (만약 현재 브랜치가 main이고 upstream 추적이 설정되어 있다면 git pull만으로도 동작합니다.)
  • 페치 (git fetch): 참고로 git pull은 자동 병합까지 하므로 충돌이 생길 경우 까다로울 수 있습니다. 병합을 수동으로 조정하고 싶다면 git fetch origin으로 원격 커밋들을 가져오기만 하고, 나중에 필요 시 git merge로 병합할 수도 있습니다. fetch는 로컬 이력을 업데이트하지 않으므로 안전하게 원격 변경사항을 확인하는데 쓰입니다.

원격 저장소 생성과 초기 푸시: 만약 처음부터 내 로컬 프로젝트를 GitHub 등에 올리고 싶다면, GitHub 웹사이트에서 빈 원격 저장소를 만든 후, 로컬에서 git remote add origin <URL>으로 연결하고, git push -u origin main으로 초기 커밋을 푸시합니다. 이때 GitHub가 기본 브랜치 이름을 master 대신 main으로 사용하고 있으므로, 로컬에서도 main 브랜치를 만들어 사용하거나, push 시 git push origin <로컬브랜치>:main처럼 리모트 main에 맞춰 보낼 수 있습니다.

 

원격 브랜치 추적: 로컬 브랜치를 원격 브랜치와 연결하면 (예: git push -u로), 이후 git pull이나 git push 명령만 쳐도 Git이 현재 브랜치와 연결된 원격/브랜치를 알아서 사용합니다. git branch -vv 명령으로 각 로컬 브랜치가 추적중인 원격 브랜치를 확인할 수 있습니다.

 

인증(Authentication): 원격 저장소와 통신할 때는 권한 인증이 필요합니다. HTTPS 방식이면 매번 사용자명/패스워드를 입력하거나 Personal Access Token을 사용해야 하고, SSH 방식이면 사전에 SSH 키를 생성하여 원격 서비스에 등록해두어야 합니다. 초보자의 경우 HTTPS로 clone/push 하다가 인증 오류가 날 수 있는데, GitHub의 경우 2021년부터 비밀번호 대신 Token을 쓰도록 하였으니 유의해야 합니다. SSH는 한 번 설정해두면 비밀번호 입력 없이 편리하게 사용 가능하므로 많이 선호됩니다.

 

GitHub vs GitLab vs Bitbucket: 세 서비스 모두 Git 저장소 호스팅을 제공하지만 약간씩 특화된 점이 있습니다. GitHub은 가장 큰 오픈소스 커뮤니티로 포크 & 풀리퀘스트 문화의 중심이고, GitLab은 프라이빗 저장소와 DevOps 파이프라인(CI/CD) 통합에 강점이 있으며, Bitbucket은 소규모 팀이나 기업에서 Jira 등의 Atlassian 도구와 연계에 장점이 있습니다. 그러나 기본적인 Git 원격 사용법은 동일합니다.

 

정리하면, 원격 저장소는 Git 협업의 허브입니다. 개발자들은 원격을 통해 서로의 작업을 공유하고 최신 상태를 동기화합니다. 다음 섹션에서는 이러한 원격 저장소를 활용한 협업 방식에 대해 살펴보겠습니다.

5. Git 협업 방식 (Fork, Pull Request, Merge)

Git을 활용한 협업에는 여러 가지 방식이 있지만, Fork & Pull Request(PR) 모델과 공동 저장소(Shared Repository) 모델이 대표적입니다. 여기서는 주로 포크(Fork)풀 리퀘스트(Pull Request)를 활용한 협업 흐름을 중점적으로 설명하고, 그 외에 일반적인 협업 패턴도 간략히 다룹니다.

Fork & Pull Request 모델

이 모델은 오픈소스 프로젝트에서 흔히 볼 수 있는 협업 방식입니다. 기여자가 원본 저장소를 포크(fork)해서 자신의 원격 저장소로 복사한 후, 변경을 가하고, 풀 리퀘스트(PR)를 통해 원본 저장소에 변경 병합을 요청합니다 ( Forking Workflow | Atlassian Git Tutorial ) ( Forking Workflow | Atlassian Git Tutorial ). 권한이 없는 외부 기여자도 코드에 참여할 수 있도록 하는 유용한 방법입니다. 전체 흐름을 순서대로 살펴보죠:

  1. Fork: 기여하고 싶은 대상 프로젝트의 저장소를 자신의 계정으로 포크합니다. 예를 들어 GitHub에서 userA/open-project라는 저장소를 내 계정 YourName/open-project로 Fork하면, 이는 본질적으로 서버 측에서 git clone을 수행하여 내 계정에 동일한 저장소 복사본을 만드는 것입니다 ( Forking Workflow | Atlassian Git Tutorial ). (GitLab이나 Bitbucket에서도 유사한 Fork 기능 제공) 이 포크 저장소는 원본 저장소의 완전한 복제본이며, 나만의 공간에서 자유롭게 실험할 수 있습니다.
  2. Clone: 내 계정으로 포크된 저장소 (YourName/open-project)를 로컬로 클론합니다 ( Forking Workflow | Atlassian Git Tutorial ). git clone https://git서비스/YourName/open-project.git 명령으로 내 컴퓨터에 저장소를 받아오면, origin은 자동으로 내 포크 저장소를 가리키게 됩니다. 보통 fork의 origin을 그대로 사용하고, 원본 저장소는 upstream이라는 별칭으로 추가로 등록합니다. (예: git remote add upstream https://git서비스/userA/open-project.git으로 원본을 upstream으로 추가 ( Forking Workflow | Atlassian Git Tutorial ))
  3. Branch 생성: 로컬 저장소에서 새로운 작업을 위한 브랜치를 만듭니다. 예를 들어 git checkout -b feature/new-feature처럼 브랜치를 만든 뒤 그 브랜치에서 수정 작업을 합니다 ( Forking Workflow | Atlassian Git Tutorial ). 포크 모델에서도 기본적으로 작업은 브랜치 단위로 이루어지는 것이 권장됩니다. (포크 저장소의 기본 브랜치인 main/master를 그대로 수정하지 않는 것이 좋음)
  4. Commit & Push: 변경을 완료하면 해당 브랜치에서 적절히 커밋(commit)하고, 내 포크(origin)에 푸시(push)합니다 ( Forking Workflow | Atlassian Git Tutorial ). 예를 들어 git push origin feature/new-feature를 하면 내 포크 저장소의 feature/new-feature 브랜치에 커밋들이 업로드됩니다. 이 시점까지의 변경은 나의 원격 저장소에만 적용되며, 원본 저장소에는 아무 영향이 없습니다.
  5. Pull Request 생성: 포크한 Git 호스팅 서비스(GitHub 등)에서 Pull Request를 열어 원본 저장소 측에 내 변경을 병합해달라고 요청합니다 ( Forking Workflow | Atlassian Git Tutorial ). PR 작성 시, base 저장소 (원본의 어떤 브랜치에 병합할지)와 head 저장소 (내 포크의 어떤 브랜치를 보낼지)를 지정합니다. 보통 base는 원본의 main (또는 develop) 브랜치, head는 내 포크의 feature 브랜치가 됩니다 ( Forking Workflow | Atlassian Git Tutorial ). PR에는 변경 내용 설명이나 관련 이슈 번호 등을 첨부해 원본 프로젝트 관리자가 맥락을 이해하기 쉽게 합니다.
  6. 코드 리뷰 및 피드백: 원본 저장소의 관리자나 협업자들이 PR의 코드를 리뷰합니다. GitHub 등의 PR 인터페이스를 통해 코드에 대한 코멘트를 남기거나 수정 요청을 할 수 있습니다. PR 작성자는 필요하면 추가 커밋을 푸시하여 PR에 반영하고 대화를 이어갑니다.
  7. Merge: 리뷰가 완료되고 승인되면, 원본 저장소 관리자가 PR을 머지(Merge)합니다. GitHub에서는 "Merge pull request" 버튼을 클릭하여 병합할 수 있고, 이때 merge commit을 만들지 여부(Fast-forward 가능하면 안 만들 수도 있음), 커밋들을 squash할지 등의 옵션을 선택할 수 있습니다. 머지가 완료되면 원본 저장소의 브랜치에 변경 내용이 반영되고, PR은 닫힙니다. 이렇게 하면 기여자의 커밋들이 원본 프로젝트에 합류하게 됩니다 ( Forking Workflow | Atlassian Git Tutorial ).
  8. 동기화(Optional): 원본 저장소에 병합된 후, 기여자는 자신의 포크 저장소를 원본과 동기화(sync)할 필요가 있습니다. 보통 git pull upstream main으로 원본의 최신 main을 가져와 내 로컬 main을 업데이트하고, git push origin main으로 자신의 포크 main도 갱신합니다. 그리고 사용했던 feature 브랜치는 필요없다면 삭제합니다.

위 과정이 Fork & PR 워크플로의 기본 골자입니다 ( Forking Workflow | Atlassian Git Tutorial ) ( Forking Workflow | Atlassian Git Tutorial ). 이 방식을 통해 원본 프로젝트 측은 외부인의 기여를 선택적으로 받아들일 수 있는 장점이 있습니다. 포크된 저장소는 기여자 개인 공간이므로, 원본에 write 권한 없이도 기여가 가능하고, 관리자는 PR을 검토하여 신뢰할 수 있을 때만 병합하면 됩니다 ( Forking Workflow | Atlassian Git Tutorial ) ( Forking Workflow | Atlassian Git Tutorial ). 이러한 "fork-pull" 모델은 GitHub 등에서 오픈소스 협업의 표준으로 활용되고 있습니다.

공동 저장소(Shared Repository) 모델

한편, 회사나 소규모 팀에서는 보통 하나의 중앙 원격 저장소를 공동으로 관리하며 협업합니다. 이 경우 각 기여자는 동일한 원격 저장소에 푸시할 수 있는 권한이 있고, 굳이 포크를 뜨지 않습니다. 협업 방식은 브랜치 기반 개발로 이뤄지는데, 흔한 패턴은 다음과 같습니다:

  • Feature Branch Workflow: 메인 브랜치(main 또는 develop)는 항상 배포 가능한 상태로 유지하고, 새로운 기능이나 버그 수정을 할 때마다 기능 브랜치(feature branch)를 만들어 개발합니다. 예를 들어 feature/login-page 브랜치를 만들어 작업하고, 완료되면 PR이나 직접 merge로 main에 합칩니다. Merge 후 해당 브랜치는 삭제하고, main 브랜치는 곧 배포하거나 다음 릴리즈 준비를 합니다. 여러 개발자가 각자 다른 기능 브랜치에서 동시 작업할 수 있어 병렬 개발이 가능하지만, 모두가 하나의 원격 저장소에서 branch를 push/pull하기 때문에 권한 관리충돌 조정이 필요합니다.
  • Git Flow: 앞서 언급한 Git Flow 모델은 개발 브랜치와 릴리즈 브랜치 등을 활용한 체계적인 공동작업 모델입니다 ( Forking Workflow | Atlassian Git Tutorial ). 예를 들어 개발은 develop 브랜치에서 통합하고, 안정 버전은 main(master) 브랜치에 태그를 달아 관리하며, 큰 릴리즈 전에는 release 브랜치를 따로 두어 최종 손질을 하고 main에 병합합니다. 긴급 수정은 hotfix 브랜치에서 처리한 후 두 브랜치(main, develop)에 모두 반영합니다. 이 모델은 협업 인원이 많고 릴리즈 주기가 분명한 프로젝트에서 유용합니다.
  • PR을 통한 코드 리뷰: 비록 같은 저장소에서 작업해도, Pull RequestMerge Request를 이용한 코드 리뷰 과정은 여전히 적용할 수 있습니다. 예를 들어 팀원이 feature 브랜치를 push한 후, 그 브랜치를 main에 merge하기 전에 GitLab의 Merge Request나 GitHub의 Pull Request로 다른 팀원들에게 코드 리뷰를 요청할 수 있습니다. 이는 코드 품질을 높이고 지식을 공유하는 좋은 습관입니다. (이 때의 PR은 포크가 아닌 같은 저장소 내 브랜치 사이의 PR입니다.)

공동 저장소 모델의 경우 초기 세팅이 간단하고, CI/CD 파이프라인 구성이 일원화되는 장점이 있습니다. 다만 쓰기 권한이 있는 모두가 원격에 push할 수 있으므로, 누가 언제 무엇을 배포 브랜치에 넣는지 팀 규칙을 정하고 관리해야 합니다. 일반적으로는 작은 수정은 직접 main에 push하기도 하지만, 중요한 변경은 브랜치에서 PR 리뷰를 거쳐 merge하는 정책을 많이 사용합니다.

 

정리: Git에서는 이러한 다양한 협업 방식이 모두 가능합니다. 오픈소스 프로젝트처럼 권한 분리를 원하면 Fork & PR 모델을, 사내 개발처럼 신속한 공유가 중요하면 Shared Repository 모델을 쓰거나, 두 가지를 상황에 맞게 혼합하기도 합니다. 핵심은 브랜치원격을 활용하여 여러 사람이 동시에 작업하되 최종적으로 코드를 합치는 프로세스를 원활히 만드는 것입니다. Git의 강력한 분산성과 브랜치 기능 덕분에, 전 세계 개발자들은 자유로운 협업 환경을 구축할 수 있었습니다.

6. Git 고급 기능 (Rebase, Cherry-pick, Tag, Stash 등)

기본적인 add/commit/merge만으로도 Git을 사용하는 데 문제는 없지만, 복잡한 히스토리를 다루거나 특정한 상황에서 유용한 고급 기능들도 많이 제공됩니다. 여기서는 자주 사용되는 고급 기능 몇 가지 – Rebase, Cherry-pick, Tag, Stash –를 소개합니다.

Rebase (리베이스)

리베이스는 한 브랜치의 커밋들을 다른 브랜치의 끝(base)으로 옮겨 재적용하는 작업을 말합니다 ( git rebase | Atlassian Git Tutorial ). 기본 개념은 “밑바탕을 갈아치운다”는 뜻으로, 예를 들어 feature 브랜치를 main 브랜치 최신 커밋 위로 재배치(rebase)하면 마치 feature 브랜치를 처음부터 main의 최신 상태에서 시작한 것처럼 히스토리가 재작성됩니다 ( git rebase | Atlassian Git Tutorial ). 리베이스를 수행하려면 해당 브랜치에서 git rebase <대상브랜치> 명령을 실행합니다.

  • 용도: 리베이스의 주요 목적은 히스토리를 깔끔하게 정리하는 것입니다. merge를 하면 두 갈래 히스토리가 merge commit으로 합쳐지지만, rebase를 하면 별도 merge commit 없이 직선형 연속 히스토리를 만들 수 있습니다. 예를 들어 공동작업 중 main 브랜치에 다른 사람의 커밋이 들어간 경우, 내 로컬 feature 브랜치를 main에 rebase하면, 내 커밋들이 최신 main 끝으로 이동되어 병합 없이도 main에 바로 fast-forward 병합할 수 있는 상태가 됩니다.
  • 장점: 프로젝트 이력이 병렬로 분기되었다 합쳐지는 복잡한 그래프 형태가 아닌, 일렬로 쭉 이어진 히스토리를 유지할 수 있습니다. 특히 오픈소스 기여시 PR 병합 전에 maintainer가 기여자의 커밋들을 rebase & squash하여 한 줄로 정리하기도 합니다.
  • 주의: 리베이스는 커밋 해시를 변경시키는 작업입니다. 기존 커밋을 새로운 기반에 적용하면서 커밋 ID가 새로 발급되므로, 이미 원격에 공유된 브랜치에 대해 리베이스를 하면 히스토리 불일치가 발생합니다. 따라서 “공유된(public) 브랜치에는 rebase 하지 말라”는 것이 일반적인 권장사항입니다. 대신 로컬 개인 브랜치에서만 rebase를 활용하고, force-push가 필요한 상황(공유 브랜치를 rebase한 뒤 강제로 원격 갱신)은 팀원의 인지를 꼭 구해야 합니다.
  • 인터랙티브 리베이스: git rebase -i 옵션을 사용하면 대화형(rebase interactive) 모드로 들어가서 커밋들을 재배열하거나, 합치거나(squash), 편집할 수 있습니다. 이를 통해 불필요한 자잘한 커밋을 하나로 합치거나, 커밋 순서를 변경하는 등 히스토리를 깔끔하게 리팩토링할 수 있습니다. 단, 이 역시 로컬에서만 사용하는 것이 좋습니다.
    예시: git rebase main (현재 브랜치를 main 브랜치 최신 커밋 위로 rebase), git rebase -i HEAD~5 (최근 5개 커밋을 대상으로 인터랙티브 리베이스 실행하여 편집).

요약하면, Rebase = 커밋 재배치로 이해할 수 있습니다. Merge와 마찬가지로 브랜치를 합치는 목적이지만, 기록 방식이 다르므로 상황에 따라 적절히 선택해야 합니다 ( git rebase | Atlassian Git Tutorial ). (일반적으로 협업 브랜치는 merge, 개인 브랜치 정리는 rebase를 많이 활용합니다.)

Cherry-pick (체리픽)

체리픽은 말 그대로 체리만 쏙 골라 담듯이, 특정 커밋 한 개(또는 몇 개)를 다른 브랜치에 적용하는 기능입니다. git cherry-pick <커밋해시> 형태로 사용하면 현재 체크아웃된 브랜치에 해당 커밋의 변경사항을 그대로 복사하여 새로운 커밋으로 만든 뒤 적용합니다 ( Git Cherry Pick | Atlassian Git Tutorial ) ( Git Cherry Pick | Atlassian Git Tutorial ).

  • 용도: Cherry-pick은 여러 갈래 브랜치에서 선택적으로 패치 적용이 필요할 때 유용합니다. 예를 들어, main 브랜치에서 버그 하나를 수정하는 커밋을 했는데 이 수정이 현재 개발 중인 develop 브랜치에도 필요하다면, develop 브랜치 체크아웃 후 그 커밋을 cherry-pick하여 가져올 수 있습니다. 또, 긴급한 버그 픽스(commit f 등)를 과거 릴리즈 브랜치에도 적용해야 할 때 cherry-pick으로 해당 커밋을 복사해 넣을 수 있습니다 ( Git Cherry Pick | Atlassian Git Tutorial ) ( Git Cherry Pick | Atlassian Git Tutorial ).
  • 동작: Cherry-pick은 대상 커밋의 diff를 계산하여 현재 브랜치에 새로운 커밋으로 적용합니다. 원본 커밋과 내용은 같을 수 있지만 커밋 해시는 새로 부여되므로, 히스토리상 별개의 커밋으로 남습니다. 만약 cherry-pick 대상 커밋이 여러 개라면 하나씩 순차 적용하거나, 범위를 지정할 수도 있습니다 (git cherry-pick A..B는 커밋 A 이후부터 B까지 적용).
  • 주의: Cherry-pick으로 동일한 변경이 두 번 기록되면, 나중에 브랜치를 병합할 때 중복된 변경으로 인한 충돌이 발생할 수 있습니다. 예를 들어 develop에 cherry-pick으로 가져온 커밋이 나중에 main과 병합될 때 이미 main에도 존재하므로 충돌이나 중복이슈가 생길 수 있습니다. 이러한 경우에는 merge 시 Git이 동일 커밋을 알아보고 자동으로 제거(squash)해주기도 하지만, 상황에 따라 수동 조치가 필요할 수 있습니다. Cherry-pick은 강력하지만 자주 쓰면 히스토리가 난잡해질 수 있으므로 신중하게 사용합니다 (일반적으로 긴급 핫픽스나 특정 커밋 이식에만 사용 권장).
  • 예시: git cherry-pick 1a2b3c4d (해시가 1a2b3c4d인 커밋을 현재 브랜치에 적용), git cherry-pick C1 C2 C3 (C1, C2, C3 세 커밋을 차례로 적용). 충돌이 나면 일반 merge처럼 해당 커밋 적용이 중단되며, 수동으로 충돌 해결 후 git cherry-pick --continue로 진행합니다.

Cherry-pick은 부분 병합의 일종으로 볼 수 있습니다. 브랜치를 전체로 합치기엔 부담스러울 때 꼭 필요한 특정 변경만 쏙 빼서 가져오는 도구로 기억해두세요 ( Git Cherry Pick | Atlassian Git Tutorial ) ( Git Cherry Pick | Atlassian Git Tutorial ).

Tag (태그)

태그(tag)는 커밋에 붙이는 이름표입니다. 태그를 이용하면 특정 커밋을 쉽게 가리킬 수 있고, 주로 릴리즈 버전을 표시하는 데 사용됩니다 (Git - Tagging). 예를 들어 첫 출시 버전에 해당하는 커밋에 v1.0이라는 태그를 달아두면, 나중에 해당 커밋을 일일이 해시로 기억하지 않아도 v1.0으로 참조할 수 있습니다.

Git에는 두 종류의 태그가 있습니다:

  • 경량 태그 (Lightweight tag): 단순히 특정 커밋에 이름을 붙입니다. 추가 메타데이터 없이 해시만 가리키는 포인터입니다.
  • 주석 태그 (Annotated tag): 태그 생성자의 이름, 이메일, 날짜와 태그 메시지 등을 함께 저장합니다. Git 데이터베이스에 별도의 객체로 저장되며, GPG로 서명할 수도 있어 릴리즈 태그에 주로 사용됩니다.

태그 만들기: git tag <태그이름>으로 현재 HEAD 커밋에 경량 태그를 달 수 있습니다. Annotated tag를 만들려면 -a 옵션과 메시지(-m)를 주어 git tag -a v1.0 -m "Release 1.0"처럼 실행합니다. 특정 과거 커밋에 태그를 달고 싶다면 커밋 해시를 마지막에 지정합니다 (git - Create a tag in a GitHub repository - Stack Overflow). 예: git tag -a v1.0 1a2b3c4d -m "Release 1.0"는 해시 1a2b3c4d 커밋에 v1.0 태그 부여 (git - Create a tag in a GitHub repository - Stack Overflow).

 

태그 확인: git tag 명령만 입력하면 저장소의 태그 목록을 보여줍니다 (Git - Tagging). 태그 이름은 보통 버전 문자열(v1.0.0 등)을 씁니다. git show <태그>로 태그가 가리키는 커밋과 태그 메시지를 볼 수 있습니다.

 

태그 공유: 로컬에서 만든 태그는 기본적으로 git push로 자동 전송되지 않습니다 ( git tag | Atlassian Git Tutorial ). git push origin <태그이름>으로 개별 태그를 푸시하거나, 한꺼번에 모든 태그를 보내려면 git push origin --tags 명령을 사용합니다 ( git tag | Atlassian Git Tutorial ). (협업 시 태그도 일종의 데이터이므로, 릴리즈를 알리려면 태그 푸시를 잊지 말아야 합니다.) 다른 사용자가 저장소를 clone하거나 pull할 때 태그도 받아지지만, 이미 clone한 상태라면 git fetch --tags로 수동 갱신이 필요할 수 있습니다.

 

체크아웃: 태그도 하나의 커밋 참조이므로, git checkout <태그이름>으로 해당 태그 시점의 파일 상태를 가져올 수 있습니다 ( git tag | Atlassian Git Tutorial ). 다만 태그를 체크아웃하면 HEAD가 분리(detached HEAD)된 상태가 되는데, 보통 과거 버전을 살펴보는 용도로만 하고, 그 상태에서 작업을 이어나가려면 새로운 브랜치를 만들도록 합니다.

요약하면, 태그는 특별한 이름이 붙은 커밋 스냅샷입니다. 주요 버전 릴리즈나 마일스톤에 태그를 걸어두면 나중에 소프트웨어 버전 관리를 하기 수월합니다. 예를 들어 git tag -a v2.0 -m "Major update"로 태그하고 GitHub Releases와 연동해 릴리즈 노트를 작성하면 릴리즈 관리에 큰 도움이 됩니다.

Stash (스태시)

스태시(stash)는 현재 작업 중인 변경사항들을 임시로 저장해두는 기능입니다. 저장(Stash)해둔 변경은 나중에 다시 적용(unstash)할 수 있습니다. git stash 명령을 실행하면 커밋되지 않은 변경사항(스테이징 여부 무관)을 모두 스택(stack)에 쌓아두고, 작업 디렉토리를 마지막 커밋 상태로 되돌립니다 ( git stash - Saving Changes | Atlassian Git Tutorial ) ( git stash - Saving Changes | Atlassian Git Tutorial ). 마치 현재 작업 내용을 잠시 치워놓고 깨끗한 상태로 다른 일을 할 수 있게 해주는 것입니다.

  • 용도: Stash는 작업 전환이 필요할 때 유용합니다. 예를 들어, 새로운 기능을 구현하다가 급한 버그 수정 요청이 들어온 경우, 아직 완료되지 않은 코드를 커밋하긴 애매할 때 git stash로 임시저장해두고 버그 수정을 진행할 수 있습니다 (Basic Git Commands You Need to Know | Simplilearn) ( git stash - Saving Changes | Atlassian Git Tutorial ). 버그 수정이 끝나면 다시 원래 작업 브랜치로 돌아와 git stash pop으로 저장했던 변경을 복원하여 이어서 개발할 수 있습니다. 이처럼 “미완성 작업 → 급한 다른 작업 → 복귀” 시나리오에서 유용합니다.
  • 동작: stash를 하면 Git이 변경 내역을 가리키는 객체들을 만들어 .git/refs/stash에 저장합니다. 여러 번 stash하면 스택처럼 쌓이는데, git stash list로 목록을 볼 수 있습니다. 각 stash에는 고유한 이름(예: stash@{0}, stash@{1} ...)과 커밋 해시처럼 식별자가 있습니다.
  • 복원: git stash pop은 가장 최근 stash를 적용하면서 스택에서 제거합니다 (Basic Git Commands You Need to Know | Simplilearn). git stash apply는 적용만 하고 남겨둡니다. 여러 stash 중 특정 것을 적용하려면 git stash apply stash@{2} 같은 식으로 지정할 수 있습니다. stash 적용 시에도 충돌이 날 수 있으며, 이 경우 일반 충돌 해결처럼 수동 해결 후 git add/git commit하면 됩니다.
  • 옵션: git stash -u는 추적 안 된(untracked) 파일까지 함께 stash에 포함시킵니다 (Basic Git Commands You Need to Know | Simplilearn). 기본적으로는 Git이 관리 중인 파일의 변경만 stash하며, 새로 생성한 untracked 파일은 제외하므로, 필요하다면 -u(또는 --include-untracked)를 붙입니다. git stash -a는 .gitignore된 파일까지 모두 포함(–all)합니다. 또한 stash에도 메시지를 붙일 수 있어 git stash push -m "작업중이던 UI개선"처럼 하면 나중에 구분하기 편합니다. git stash drop은 stash 항목을 제거하고, git stash clear로 모두 삭제할 수 있습니다.
  • 제한: stash는 로컬 전용입니다. stash된 변경사항은 원격으로 푸시되거나 공유되지 않으므로, 협업자와 공유해야 할 변경이라면 stash가 아니라 commit/push를 해야 합니다 ( git stash - Saving Changes | Atlassian Git Tutorial ). 또한 stash는 임시 수단이므로 잊어버리지 말고 가급적 빨리 pop하여 적용하거나 제거해야 합니다. 오래 방치하면 그만큼 코드베이스와 괴리가 커져서 나중에 충돌이 날 가능성이 높습니다.

Stash는 “작업 중단 임시 저장”으로 기억하면 됩니다. 작은 변경을 실험하거나 여러 작업을 한정된 작업공간에서 교대로 진행해야 할 때, stash를 잘 활용하면 편리합니다 ( git stash - Saving Changes | Atlassian Git Tutorial ).


이외에도 Git에는 reset, revert, reflog, submodule 등 다양한 고급 명령과 기능들이 있습니다. 예를 들어 git reset은 커밋을 취소하거나 staging 상태를 되돌릴 때, git revert는 기존 커밋의 변경을 반대로 적용하는 "anti-commit"을 만들어 이력을 보존하면서 변경 취소할 때 쓰입니다. git reflog는 HEAD 이동 내역을 추적해 실수로 잃어버린 커밋을 찾을 때 유용합니다. 이러한 기능들은 필요할 때마다 학습하여 사용할 수 있으며, 모든 것을 처음부터 다 알 필요는 없습니다. 우선 앞서 설명한 기본/고급 기능들을 익히면 대부분의 Git 작업을 수행하는 데 큰 문제가 없을 것입니다.

7. Git 설정 및 환경 구성 (설정 파일, .gitignore 등)

Git을 사용하면서 개인이나 프로젝트별로 설정(config)을 조정해야 하는 경우가 많습니다. 올바른 설정을 통해 편의성을 높이고 실수를 예방할 수 있습니다. 또한 프로젝트에는 종종 형상 관리에 포함시키면 안 되는 파일들이 있기 마련인데, 이를 다루려면 .gitignore 설정이 필수적입니다. 이번 장에서는 Git 설정과 환경 구성을 위한 요소들을 살펴보겠습니다.

글로벌 사용자 설정 (user.name, user.email 등)

Git을 설치한 후 가장 먼저 해야 하는 일은 사용자 이름과 이메일을 설정하는 것입니다. 이는 각 커밋의 작성자 정보로 기록되며, 협업 시 누가 어떤 변경을 했는지 식별하는 데 사용됩니다. 다음 명령으로 전역 설정을 할 수 있습니다 (Basic Git Commands You Need to Know | Simplilearn):

git config --global user.name "Your Name"
git config --global user.email your.email@example.com

--global 옵션은 이 설정이 현재 컴퓨터 사용자 계정 전체에 적용됨을 의미합니다. 이러한 설정 값은 보통 사용자의 홈 디렉토리에 있는 ~/.gitconfig 파일에 저장됩니다. (Windows의 경우 C:\Users\<User>\.gitconfig) 이후 생성하는 모든 Git 저장소에서 기본적으로 이 이름과 이메일이 커밋 작성자 정보로 사용됩니다. 만약 특정 저장소에서만 별도 이름/이메일을 쓰고 싶다면 --local 옵션(해당 저장소 .git/config에 기록)을 사용하면 됩니다.

 

기타 글로벌 설정:

  • 편집기 설정: git config --global core.editor "code --wait"처럼 하면 Git이 기본으로 여는 편집기를 VSCode로 지정할 수 있습니다 (커밋 메시지 작성 등에서 활용).
  • 색상 출력: git config --global color.ui auto로 설정하면 Git 명령 출력에 색상이 입혀져 가독성이 높아집니다 (기본 값이 auto인 경우도 있음).
  • 줄 끝 형식: Windows와 Unix 계열 간 줄바꿈 차이를 다루기 위해 core.autocrlf 설정을 켜둘 수 있습니다. 예: Windows 사용자는 git config --global core.autocrlf true로 설정하면 체크아웃 시 CRLF로 변환, 커밋 시 LF로 자동변환하여 혼용으로 인한 문제를 줄여줍니다.

.gitignore 설정

프로젝트를 하다 보면 버전 관리에서 제외해야 할 파일들이 생깁니다. 예를 들어, 컴파일된 바이너리나 로그 파일, 사용자별 설정 파일, 대용량 파일 등은 Git으로 관리하지 않는 게 좋습니다. 이러한 파일 패턴을 지정해 Git이 아예 추적하지 않도록 하는 목록이 .gitignore 파일입니다. .gitignore은 저장소 루트(또는 하위 디렉토리)에 위치하며, Git은 여기에 명시된 패턴과 일치하는 파일은 git add를 하더라도 무시합니다.

 

.gitignore 작성: .gitignore 파일은 일반 텍스트 파일로, 각 줄에 하나의 패턴을 적습니다. 예시:

# 빌드 결과물 무시
/build/
/dist/

# 로그 파일 무시
*.log

# OS/IDE 생성 파일 무시
.DS_Store
Thumbs.db

# 환경 설정 파일 무시
.env

 

위 예시는 흔히 무시하는 항목들입니다:

  • 슬래시(/)로 끝나는 패턴 (/build/ 등)은 디렉토리를 가리킵니다. 해당 폴더와 그 안의 모든 내용을 버전 관리에서 제외합니다.
  • *.log는 확장자가 .log인 모든 파일을 무시합니다.
  • 특정 파일명 .DS_Store(맥 OS 생성), Thumbs.db(윈도우 생성) 등을 명시적으로 무시합니다.
  • .env는 주로 환경변수 설정 등 민감정보 파일이므로 무시 예시로 넣었습니다.

.gitignore의 패턴 문법은 단순 문자 매칭이며, *은 와일드카드, ?는 한 글자 대체, **/은 경로 중간 포함 등의 규칙이 있습니다. !로 시작하는 패턴은 무시에서 예외로 취급합니다 (즉, 이전에 무시된 패턴 중 특정 것은 다시 추적하도록). 예: !important.sql은 앞에서 *.sql로 모든 SQL을 무시했어도 important.sql은 추적하게 만듭니다.

 

적용 시점: .gitignore는 아직 Git이 추적하지 않은 파일에 대해서만 효과가 있습니다. 이미 한 번 커밋 등에 추적된 파일은 .gitignore에 추가해도 무시되지 않습니다. 따라서 기존 파일을 무시하려면 Git 캐시(index)에서 제거(git rm --cached 파일명) 후 커밋해야 합니다.

 

글로벌 .gitignore: 모든 프로젝트에서 공통으로 무시하고 싶은 파일들이 있다면 전역 .gitignore를 설정할 수 있습니다. 예를 들어 OS 생성파일(.DS_Store 등)이나 IDE 설정파일 등을 전역에서 제외하고 싶다면, 특정 경로에 전역 ignore 파일을 만들고 git config --global core.excludesfile ~/.gitignore_global 처럼 지정해둘 수 있습니다. 그러면 각 저장소의 .gitignore에 넣지 않아도 전역으로 무시됩니다.

 

예시들: 일반적으로 언어/플랫폼별 추천 .gitignore 템플릿이 존재합니다. GitHub에서는 다양한 .gitignore 템플릿 모음을 제공하니 참고하면 편리합니다. 예컨대 Node.js 프로젝트라면 node_modules/, Python은 __pycache__/, Java는 target/ 등의 항목이 필수적입니다 (Git Ignore and .gitignore - W3Schools). 팀원 간 .gitignore를 잘 관리하면 불필요한 파일이 저장소에 올라가 혼란을 주는 일을 막을 수 있습니다.

프로젝트별 설정 (로컬 .git/config 등)

각 Git 저장소 내부의 .git/config 파일에는 해당 저장소에 국한된 설정이 저장됩니다. 예를 들어 원격 저장소(URL, 브랜치 추적 설정), 설정된 hook 스크립트, git config --local로 지정한 값들이 여기 기록됩니다. 일반적으로 수동으로 편집할 일은 드물고, 명령어로 설정을 변경하면 이 파일이 바뀝니다.

 

훅(Hook) 설정: Git은 커밋이나 병합, 푸시 등의 이벤트 발생 시 특정 스크립트를 실행할 수 있는 hook 기능이 있습니다 (예: pre-commit, post-merge 등). .git/hooks/ 디렉토리에 샘플 훅들이 있으며, 이를 편집하여 활성화하면 Git 동작을 자동화할 수 있습니다. 예컨대 pre-commit 훅을 설정하여 커밋 전에 코드 린트나 테스트를 자동 수행하게 할 수 있습니다. 훅은 팀원과 공유하려면 별도의 방법이 필요하지만 (Git 자체는 훅을 버전 관리하지 않음), CI 연동이나 일부 툴로 강제할 수 있습니다.

 

리포지토리 설정 예시: 프로젝트에 따라 특수한 Git 설정이 필요한 경우도 있습니다. 예를 들어 Unity 같은 게임 엔진 프로젝트에서는 대용량 바이너리 에셋이 많아 Git LFS(Large File Storage)를 설치/구성하기도 합니다. 또, 파일 대소문자 민감도나 개행문자 처리 설정을 .gitattributes 파일로 지정하여 플랫폼 간 차이를 조율할 수도 있습니다.

사용자 환경 구성 팁

  • 프롬프트 설정: Git Bash나 터미널에서 작업할 때 현재 Git 브랜치명이 프롬프트에 표시되도록 설정하면 편리합니다. 이는 터미널 프로그램 설정이나 oh-my-zsh/git-prompt 등의 도구를 이용하면 쉽게 구현됩니다. 브랜치를 인지하지 못해 잘못된 브랜치에 커밋하는 실수를 줄여줍니다.
  • GUI 도구 활용: Sourcetree, GitKraken, GitHub Desktop 같은 GUI 클라이언트를 사용하면 시각적으로 Git 설정과 변경 내역을 관리하기 쉬워집니다. 초보자는 GUI에서 시작해 점차 CLI로 넘어가는 것도 방법입니다.
  • 에디터 통합: VSCode 같은 에디터는 Git과 통합되어 변경사항 표시, 충돌 시각화, UI 커밋 등이 가능합니다. 익숙한 도구의 도움을 받아 Git을 사용하는 것도 생산성을 높이는 환경 구성입니다.

결론적으로, Git 설정은 전역 (글로벌)로컬 (프로젝트별)로 나뉘며, .gitignore를 비롯한 환경 구성 파일들을 잘 활용해야 원활한 버전 관리를 할 수 있습니다. 올바른 설정은 실수를 방지하고 협업 효율을 높여주므로, 프로젝트 시작 시 한 번 점검하고 넘어가는 것이 좋습니다.

8. Git 오류 해결 (자주 발생하는 오류 및 대처법)

Git을 사용하다 보면 초보자든 숙련자든 다양한 에러/경고 메시지를 접하게 됩니다. 당황하지 않고 원인을 파악하면 대부분 해결책이 있습니다. 이번 장에서는 자주 발생하는 Git 오류와 그 해결 방법을 소개합니다.

1) Merge conflict (병합 충돌)

상황: 앞서 브랜치 병합 섹션에서 다룬 충돌(conflict) 상황입니다. git merge 또는 git pull 수행 시 "Automatic merge failed; fix conflicts and commit the result."라는 메시지와 함께 충돌이 발생할 수 있습니다. 이때 충돌 난 파일들은 <<<<<<< HEAD 형태의 머지 마커가 포함된 채로 남습니다.

 

원인: 동일한 줄(혹은 인접한 부분)을 서로 다르게 수정한 커밋을 병합할 때 Git이 자동으로 합치지 못해서입니다 (Resolving a merge conflict using the command line - GitHub Docs).

 

해결: 충돌 난 경우 Git이 알려준 해당 파일들을 열어 수동으로 수정해야 합니다. 앞서 브랜치 관리 챕터에서 설명한 충돌 해결 절차를 따르면 됩니다:

팁:

  • 충돌이 난 상태에서 git status를 보면 어떤 파일들이 충돌났는지 “unmerged paths”로 알려주므로 이를 참고합니다.
  • git log --merge를 쓰면 충돌난 커밋들의 메시지를 볼 수 있고, git diff --name-only --diff-filter=U로 충돌 파일만 리스트업할 수 있습니다.
  • 충돌 해결이 어렵다면, git merge --abort로 병합 전 상태로 되돌아갈 수도 있습니다 (rebase의 경우 git rebase --abort).
  • GUI 툴이나 VSCode의 병합 편집 기능을 사용하면 충돌 부분을 쉽게 골라서 적용할 수 있습니다.

2) Push rejected / non-fast-forward (푸시 거부)

상황: 원격에 push를 시도했을 때 에러 메시지가 나는 경우입니다. 대표적인 오류는 다음과 같습니다:

error: failed to push some refs to '<원격 저장소 URL>'
hint: Updates were rejected because the tip of your current branch is behind its remote counterpart.

이 메시지는 내 로컬 브랜치의 이력이 원격 브랜치보다 뒤쳐져 있어서 푸시를 거부했다는 뜻입니다 (How To Fix the “Error: Failed to Push Some Refs To” in Git - Kinsta®). 즉, 원격 저장소에 내 로컬에 없는 새로운 커밋이 있을 때 발생합니다.

 

원인: 누군가 원격 브랜치에 나보다 앞선 커밋을 push한 경우, 혹은 내가 force push 등으로 이력을 뒤집지 않는 이상 Git은 원격의 앞선 변경을 덮어쓰지 않도록 푸시를 거부합니다 (How To Fix the “Error: Failed to Push Some Refs To” in Git - Kinsta®). 이를 non-fast-forward 상황이라고 합니다 (push 하려는 브랜치의 부모 커밋이 원격 브랜치의 최신 커밋과 다를 때).

 

해결: 이 에러가 뜨면 우선 원격 저장소의 변경을 내 로컬에 가져와야 합니다. 일반적으로 git pull을 실행하여 원격 커밋을 병합한 후 다시 git push를 시도합니다 (How To Fix the “Error: Failed to Push Some Refs To” in Git - Kinsta®).

  • 만약 직접 merge 커밋을 만들기 싫다면, 대신 git fetch + git rebase origin/<branch>로 내 커밋을 원격 최신 커밋 위로 재배치한 뒤 push할 수도 있습니다. (초보자에게는 일단 merge로 해결하는 것이 무난합니다.)
  • 충돌이 발생하면 앞서 충돌 해결 절차대로 처리한 뒤 push하면 됩니다.

그 외 push 관련 오류:

  • permission denied: 접근 권한 문제가 있을 때 발생합니다. 예를 들어 SSH 키 설정이 안 되었거나, GitHub 저장소에 내 계정이 권한이 없으면 "permission denied (publickey)" 또는 "access denied" 오류가 납니다. 해결: 올바른 인증 정보(SSH 키, 토큰 등) 설정이 필요합니다. GitHub의 경우 ssh-keygen으로 키를 만들고 계정에 추가하거나, HTTPS인 경우 자격 증명을 캐시하거나 토큰을 사용하는 방식으로 인증 문제를 해결합니다.
  • no upstream branch: git push 했을 때 "fatal: The current branch X has no upstream branch"라는 메시지는, 현재 브랜치를 푸시할 기본 원격/브랜치 정보가 없다는 뜻입니다. 해결: git push -u origin X 한 번 실행해서 upstream을 설정하거나, 아니면 풀 커맨드로 git push origin X:Y (원격 Y 브랜치에 push) 형태로 사용합니다. 일반적으로 새 브랜치를 원격에 처음 push할 때 -u 옵션을 붙이면 해결됩니다.

요약하면, “failed to push some refs” 오류는 먼저 pull하여 로컬과 원격의 이력을 동기화하라는 신호입니다 (How To Fix the “Error: Failed to Push Some Refs To” in Git - Kinsta®). 이를 무시하고 강제로 push (git push --force)하면 공동 작업자의 이력을 덮어쓸 위험이 있으므로, 웬만하면 권장되지 않습니다. 항상 push 전에는 git pull로 업데이트하는 습관을 들이고, 그래도 충돌하면 앞서 말한 것처럼 해결 후 push하도록 합니다.

3) Commit 관련 실수와 수정

Git 사용 초기에 흔한 실수로 커밋 메시지 오타 또는 파일을 뺴먹고 커밋하는 경우가 있습니다. 다행히 최근 커밋은 비교적 쉽게 수정할 수 있습니다. (이미 push한 후라면 주의가 필요하지만, push 전이라면 영향 범위가 적습니다.)

  • 마지막 커밋 메시지 수정: git commit --amend를 실행하면 직전 커밋을 수정 모드로 열어줍니다. 메시지만 바꾸고 닫으면 커밋 해시가 새로 부여되지만 내용은 그대로이고, 메시지만 변경됩니다. 예를 들어 "fix bug"를 "fix bug in login flow"로 고치거나, 오타를 바로잡을 수 있습니다 (Git happens! 6 Common Git mistakes and how to fix them). (이미 원격에 보낸 커밋이라면 amend 후 force push 해야 하므로 상황 판단이 필요합니다.)
  • 커밋에 빠뜨린 파일 추가: 파일을 빼먹은 채 커밋했다면, 해당 파일을 git add로 추가한 후 git commit --amend를 다시 실행합니다 (Git happens! 6 Common Git mistakes and how to fix them). Vim 등 에디터가 열리면 특별히 메시지 바꿀 것 없으면 그대로 저장 종료하면, 직전 커밋에 변경사항이 포함됩니다. 이렇게 하면 커밋 2개로 나눌 필요 없이 하나의 커밋으로 합쳐집니다.
  • 커밋 되돌리기 (reset/revert): 잘못 커밋한 경우, 아직 push 전이라면 git reset HEAD~1로 커밋을 취소하고 staging으로 돌릴 수 있습니다. 또는 git reset --hard HEAD~1로 아예 변경내용도 없던 것으로 할 수 있지만, 이 경우 해당 변경이 워킹 디렉토리에서도 사라지므로 주의해야 합니다. 이미 push한 커밋을 취소하려면 git revert <커밋해시>를 사용하여 "취소하는 커밋"을 만들어내는 편이 안전합니다. revert는 원래 커밋의 반대 연산을 적용한 새 커밋을 생성하므로 이력은 보존하면서 내용만 취소됩니다.

4) "not a git repository" 에러

상황: git status 등을 실행했더니 “fatal: not a git repository (or any of the parent directories): .git” 라는 메시지가 뜨는 경우입니다.

원인: 현재 디렉토리가 Git 저장소가 아닌데 Git 명령을 실행한 경우입니다. .git 폴더가 없다는 뜻입니다.

해결: 정확한 디렉토리에서 명령을 실행하고 있는지 확인합니다. 프로젝트 루트(.git 있는 경로)로 이동하거나, 저장소를 아직 생성하지 않았다면 git init으로 초기화해야 합니다. 간혹 실수로 잘못된 폴더에서 작업하거나, 또는 저장소 클론을 빠뜨리고 폴더만 복사한 경우에도 발생합니다. 올바른 저장소 경로로 이동하면 해결됩니다.

5) "fatal: origin does not appear to be a git repository"

상황: git pull origin main 등 명령 실행 시 “fatal: 'origin' does not appear to be a git repository” 라고 나오는 경우입니다.

 

원인: 로컬 저장소에 "origin"이라는 이름의 원격(remote)이 없을 때 발생합니다. 보통 git remote add origin ...를 안 했거나, clone을 하지 않고 init만 한 후 origin 설정을 안 한 경우입니다.

 

해결: 먼저 git remote -v로 현재 원격 설정을 확인합니다. 아무것도 없다면 git remote add origin <URL>로 origin을 등록합니다. 만약 origin은 있는데 URL이 잘못됐다면 git remote set-url origin <올바른URL>로 수정할 수 있습니다. 이후 다시 pull 또는 push를 시도합니다.

6) Detached HEAD (분리된 HEAD 상태)

상황: git checkout <커밋해시> 또는 특정 태그를 checkout한 경우, HEAD가 분리(detached)되었다는 경고 메시지가 나옵니다. 예를 들어 "You are in 'detached HEAD' state"라는 안내를 볼 수 있습니다.

 

원인: HEAD는 보통 현재 체크아웃한 브랜치를 가리키지만, 커밋 해시나 태그 같은 직접적인 커밋 포인터를 checkout하면 HEAD가 그 커밋을 가리키긴 하나 어느 브랜치에도 속하지 않은 상태가 됩니다 (Recovering from the Git detached HEAD state - CircleCI). 즉, 새 커밋을 만들어도 붙일 브랜치가 없는 "공중에 붕 뜬" 상태입니다.

 

해결/대처: Detached HEAD 자체는 에러는 아닙니다. 과거 커밋이나 태그 내용을 _읽기 전용으로 확인_할 때는 문제가 없습니다. 하지만 그 상태에서 파일을 수정하고 커밋하면 그 커밋들은 참조하는 브랜치명이 없어서 잃어버리기 쉽습니다. 만약 detached HEAD 상태에서 커밋을 해버렸다면, 즉시 git switch -c <브랜치명> (또는 git checkout -b <브랜치명>)을 실행하여 새 브랜치를 만들어 그 커밋들을 붙잡아두는 것이 안전합니다 (Fix a detached head / lost master branch? - Atlassian Community). 이렇게 하면 방금 만든 커밋에 브랜치 이름이 생겨서 히스토리에 안전하게 남습니다.

Detached HEAD를 피하려면 가급적 태그를 checkout할 때도 git switch -c temp <태그>처럼 새 브랜치로 작업하거나, 과거 커밋에서 실험하려면 브랜치를 만드는 게 좋습니다. 만약 실수로 detached HEAD에서 작업한 커밋을 잃어버렸다면, git reflog를 사용하여 HEAD 이동 기록에서 해당 커밋 해시를 찾아 복구할 수도 있습니다.

7) 기타 흔한 오류들

  • "could not resolve host" 또는 네트워크 에러: 원격 서버 접속이 안 될 때 발생합니다. 인터넷 연결을 확인하거나, URL 오타를 확인합니다. 회사 내 프록시 환경이라면 Git에 프록시 설정을 해야 할 수도 있습니다.
  • 파일 인코딩 문제: 콘솔에 한글이 깨져보이는 등 인코딩 문제가 발생하면 git config --global core.quotepath false 설정으로 파일명 등을 로컬 인코딩으로 표시하게 할 수 있습니다 (한글 경로 깨짐 해결).
  • 대소문자 변경 안됨 이슈: 파일 이름의 대소문자만 바뀐 경우 Git이 변경을 인식하지 못하는 경우가 있습니다(기본적으로 case-insensitive한 파일시스템에서는). 이 때는 이름을 완전히 다른 것으로 바꾸거나, .gitattributes 설정으로 case sensitivity를 적용해야 합니다.
  • submodule 관련 에러: "fatal: no submodule mapping found" 등은 잘못된 서브모듈 레퍼런스가 있을 때입니다. .gitmodules 파일을 확인하거나 서브모듈을 제거/재추가하는 절차가 필요합니다.
  • large file push 거부: GitHub 등은 기본 100MB 이상의 파일 push를 거부합니다. 이 경우 Git LFS 등을 도입하거나 파일을 Git 관리 밖으로 빼야 합니다.
  • CRLF 경고: "warning: CRLF will be replaced by LF" 등의 메시지는 윈도우 환경에서 텍스트 파일 줄끝 변환 관련 안내입니다. 설정한 core.autocrlf에 따른 동작이므로 특별한 에러는 아니지만, * text=auto 설정 등을 .gitattributes에 해주면 조정 가능합니다.

이처럼 Git 사용 중 나타나는 대부분의 오류는 원인을 이해하면 해결방법이 명확해지는 경우가 많습니다. 에러 메시지를 천천히 읽고, 모르는 용어는 구글에 검색해보면 전세계 개발자들이 남긴 Q&A나 공식 문서가 거의 항상 있습니다. (예: "failed to push some refs solution"으로 검색하면 수많은 해결법이 공유되어 있습니다.)

 

Git은 처음에 에러 메시지가 다소 난해할 수 있지만, 경험이 쌓이면 문제 상황을 복구하거나 되돌리는 기능이 매우 풍부하다는 것을 알게 됩니다. oh-my-git이나 git-fixup 같은 유용한 커뮤니티 문서들도 참고하면 도움이 됩니다.

 

마지막으로, 최후의 수단으로 유용한 팁은, 잘 모르겠는 상황에서는 새 브랜치를 만들어 현재 상태를 백업해두고 이것저것 시도해보는 것입니다. Git은 어떠한 경우에도 현재 디렉토리의 파일이 사라지지 않는 한 돌이킬 방법이 있으므로 겁먹지 말고 경험을 쌓아보세요.