git을 처음 배울 때 어려운 건 개념이 아니라 명령이 실패했을 때다. fatal:로 시작하는 줄이 뜨면 무슨 일이 일어난 건지 알 수 없어서, 구글에 그 문장을 그대로 붙여넣고 블로그 몇 개를 전전하게 된다.
이 글은 로컬 저장소에서 커밋하고 원격에 올리는 흐름을 한 번 훑은 뒤, 입문자가 실제로 가장 자주 만나는 에러 7개를 증상별로 정리했다. 명령은 macOS의 git 2.39.2에서 직접 실행해 확인했다.
30초 요약
| 궁금한 것 | 답 |
|---|---|
| 최소 명령 | git init → git add → git commit → git remote add → git push -u |
| 설치 확인 | git --version. macOS는 Xcode Command Line Tools를 깔면 함께 들어온다 (다운로드) |
| 최신 버전 | 2026년 11월 7일 확인 기준 태그는 v2.56.0 (git/git 태그) |
| 첫 커밋 전 필수 | user.name과 user.email. 없으면 커밋이 거부된다 (git-config) |
| 기본 브랜치 이름 | 아직 master다. Git 3.0에서 main으로 바뀔 예정 (git-init) |
| 브랜치 전환 | git switch, 되돌리기는 git restore. 2.23부터 추가된 명령이다 (2.23 릴리스 노트) |
| push 거부 | 원격이 앞서 있어서다. git pull --rebase 후 다시 push |
| 되돌리기 | 아직 push 안 했으면 reset, 이미 공유했으면 revert |

목차
- git 기초 사용법, 이 흐름 하나만 익히면 된다
- 설치와 최초 설정 — 커밋이 거부되는 이유
- 로컬 작업 — status·add·commit·log
- 원격 저장소 — remote·push·clone
- 브랜치와 충돌 — switch·merge
- 자주 나는 에러 7가지
- 되돌리기 — restore·reset·revert 차이
- 내가 막혔던 곳
- 참고 자료
git 기초 사용법, 이 흐름 하나만 익히면 된다
git은 파일을 세 군데에 나눠 담는다. 작업 폴더, 스테이징 영역(index), 커밋 기록이다. git add는 작업 폴더의 변경을 스테이징으로 올리고, git commit은 스테이징에 있는 것만 기록으로 남긴다. 이 구조를 알고 나면 "분명히 고쳤는데 커밋에 안 들어간다"는 상황이 이해된다.
처음 배울 때는 아래 다섯 줄이면 충분하다. 나머지 명령은 이 흐름이 막힐 때 꺼내 쓰는 도구다.
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/USER/REPO.git
git push -u origin main
-u는 이후에 git push만 쳐도 같은 원격·브랜치로 올라가게 묶어두는 옵션이다. 한 번만 붙이면 된다.
설치와 최초 설정 — 커밋이 거부되는 이유
맥에서는 터미널에서 git을 처음 실행하면 Xcode Command Line Tools 설치 안내가 뜬다. 그 창에서 설치를 누르면 /usr/bin/git이 생긴다. 내 맥에서는 git version 2.39.2 (Apple Git-143)이 잡혀 있다. 더 최신 버전이 필요하면 Homebrew로 따로 깔 수 있고, 이때 PATH 순서에 따라 두 개가 공존할 수 있다. 그 이야기는 Mac 개발환경 세팅에 정리해 뒀다.
설치 다음에 반드시 하는 설정이 있다. 이름과 이메일이 없으면 git이 커밋을 만들어주지 않는다.
git config --global user.name "Henry"
git config --global user.email "me@example.com"
git config --global init.defaultBranch main
git config --list --show-origin
세 번째 줄은 새 저장소의 기본 브랜치 이름을 정한다. 공식 문서를 보면 git init의 기본값은 아직 master이고, Git 3.0에서 main으로 바뀔 예정이라고 적혀 있다. (git-init) 지금 맞춰두면 나중에 이름이 바뀌어도 헷갈리지 않는다.
--show-origin은 각 설정이 어느 파일에서 왔는지 알려준다. 회사 저장소에서만 다른 이메일을 쓰는 경우처럼 설정이 겹칠 때 이 옵션으로 원인을 찾는다.
로컬 작업 — status·add·commit·log
작업 순서는 늘 같다. 무엇이 바뀌었는지 보고, 필요한 것만 올리고, 메시지를 붙여 기록한다.
git status -sb # 현재 브랜치와 변경 파일
git add -p # 바뀐 부분을 하나씩 확인하며 스테이징
git commit -m "로그인 폼 유효성 검사 추가"
git log --oneline --graph -10
git add -p는 처음엔 번거롭게 느껴진다. 그런데 디버그 출력이나 임시 주석이 커밋에 섞이는 일이 확 줄어든다. 커밋 하나에 한 가지 변경만 담는 습관도 여기서 생긴다.
메시지는 "무엇을"보다 "왜"를 적는다. fix bug보다 빈 이메일로 로그인 시 500 오류 수정이 나중에 도움이 된다.
| 명령 | 하는 일 |
|---|---|
git status | 변경·스테이징 상태 확인 |
git diff | 작업 폴더와 스테이징의 차이 |
git diff --staged | 스테이징과 마지막 커밋의 차이 |
git add <파일> | 특정 파일만 스테이징 |
git commit -m "..." | 스테이징 내용을 커밋으로 기록 |
git log --oneline | 커밋을 한 줄씩 요약해서 보기 |
원격 저장소 — remote·push·clone
GitHub에 빈 저장소를 만들었다면 주소를 등록하고 올린다. 이미 있는 저장소를 받을 때는 clone 한 줄이면 되고, 이때 origin이 자동으로 잡힌다.
git remote add origin https://github.com/USER/REPO.git
git remote -v
git branch -M main
git push -u origin main
# 반대 방향
git clone https://github.com/USER/REPO.git
인증은 비밀번호로 하지 않는다. GitHub는 git 작업에 계정 비밀번호를 받지 않고, Personal Access Token이나 SSH 키를 쓴다. (GitHub 문서) 토큰을 URL에 넣어두면 편하지만, 그 URL이 그대로 커밋이나 로그에 남을 수 있어서 나는 SSH 키를 쓴다.
ssh-keygen -t ed25519 -C "me@example.com"
pbcopy < ~/.ssh/id_ed25519.pub # GitHub > Settings > SSH keys에 붙여넣기
ssh -T git@github.com
마지막 줄에서 Hi USER! You've successfully authenticated가 나오면 끝이다. 처음 SSH로 접속할 때 뜨는 fingerprint 확인 문구는 yes를 입력한다.
브랜치와 충돌 — switch·merge
브랜치를 만들고 옮기는 명령은 2.23에서 switch와 restore로 분리됐다. 예전 글에 있는 checkout도 여전히 동작하지만, 새로 배울 때는 역할이 나뉜 명령을 쓰는 편이 헷갈리지 않는다.
git switch -c feature/login # 만들면서 이동
git switch main # 이동
git merge feature/login # main에 합치기
git branch -d feature/login # 합친 뒤 정리
같은 줄을 양쪽에서 고쳤다면 merge가 멈추고 CONFLICT (content)를 알려준다. 충돌 파일에는 <<<<<<<, =======, >>>>>>> 표시가 생긴다. 이 표시를 지우면서 남길 내용만 정리하고 나서 저장한 뒤 세 줄을 실행한다.
git status # 충돌 파일 확인
git add <해결한 파일>
git commit # merge 커밋 완료 (또는 git merge --continue)

중간에 마음이 바뀌면 git merge --abort로 merge 직전 상태로 돌아간다. 충돌 해결이 길어질 것 같으면 이 명령을 먼저 외워두는 게 낫다.
자주 나는 에러 7가지
입문 단계에서 실제로 자주 만나는 것들만 모았다. 대부분은 명령 한 줄로 풀린다.
| 에러 메시지 | 원인 | 해결 |
|---|---|---|
fatal: not a git repository | .git이 없는 폴더에서 실행 | 저장소 루트로 이동하거나 git init |
Author identity unknown | user.name·user.email 미설정 | git config --global user.email ... |
error: remote origin already exists | origin이 이미 등록됨 | git remote set-url origin <새 주소> |
fatal: refusing to merge unrelated histories | 로컬과 원격의 커밋 계보가 따로 시작됨 | git pull origin main --allow-unrelated-histories |
! [rejected] ... (fetch first) | 원격에 내가 없는 커밋이 있음 | git pull --rebase origin main 후 push |
error: Your local changes would be overwritten by checkout | 커밋 안 한 변경이 겹침 | git stash → git switch → git stash pop |
fatal: Authentication failed | 비밀번호 인증 시도 | Personal Access Token 또는 SSH 키 사용 |
refusing to merge unrelated histories는 GitHub에서 README를 만들고 로컬에서도 git init 후 첫 커밋을 따로 만든 경우에 난다. 두 저장소가 공통 조상을 갖지 않아서 git이 기본적으로 거부한다. --allow-unrelated-histories로 한 번 합치고 나면 이후부터는 정상적으로 동작한다. (git-merge)
push가 거부됐을 때 --force로 밀어버리는 사람이 많다. 남의 커밋이 사라질 수 있으니, 정말로 내 이력으로 덮어써야 하는 상황에서만 --force-with-lease를 쓴다. 원격이 내가 마지막으로 본 상태에서 바뀌었으면 이 옵션은 push를 거부한다. (git-push)
되돌리기 — restore·reset·revert 차이
되돌리기는 "무엇을 되돌리는지"에 따라 명령이 다르다. 여기서 많이 헤맨다.
| 상황 | 명령 | 결과 |
|---|---|---|
| 파일 수정을 버리고 싶다 | git restore <파일> | 작업 폴더가 마지막 커밋 상태로 |
| add 한 것을 취소 | git restore --staged <파일> | 스테이징에서만 내려감 (파일은 그대로) |
| 마지막 커밋 메시지 수정 | git commit --amend | push 전에만 |
| 최근 커밋 취소 (기록 삭제) | git reset --soft HEAD~1 | 변경은 스테이징에 남음 |
| 이미 push 한 커밋 취소 | git revert <해시> | 취소 커밋을 새로 만듦 |
reset은 기록을 지우고 revert는 기록을 남긴다. 혼자 쓰는 브랜치면 reset이 깔끔하고, 다른 사람과 공유한 브랜치면 revert를 쓴다. 공유 브랜치에서 reset 후 force push를 하면 동료의 로컬과 어긋난다.
git restore는 --staged를 붙이느냐에 따라 대상이 완전히 달라진다. 이 차이를 모르면 "add를 취소했는데 파일까지 사라졌다"는 상황이 생긴다. (git-restore)
내가 막혔던 곳
처음 git을 쓰던 시절, 나는 git init을 홈 디렉터리에서 실행했다. 그 뒤로 새 프로젝트를 만들 때마다 git status가 이상하게 많은 파일을 보여줬고, 왜 그런지 한참 몰랐다. 상위 폴더에 .git이 있으면 git은 거기를 저장소로 인식한다. 지금은 프로젝트 폴더를 만든 뒤 그 안에서만 git init을 한다. 이미 늦었다면 ls -a로 상위 경로를 훑어 .git이 있는지 확인하면 된다.
두 번째는 첫 push에서 겪은 인증 실패다. 비밀번호를 계속 넣어도 Authentication failed가 떴다. GitHub가 git 작업에 계정 비밀번호를 더 이상 받지 않는다는 걸 그때 알았다. 토큰을 만들고 나서 해결됐지만, 토큰을 원격 URL에 넣어둔 탓에 나중에 그 주소가 스크립트에 남아 있었다. 지금은 SSH 키를 쓰고, 원격 주소에는 토큰을 넣지 않는다. 파이썬 프로젝트라면 .venv를 .gitignore에 넣는 것도 같이 챙긴다. Python 가상환경 venv 만들기에서 만든 폴더를 그대로 커밋하면 저장소가 순식간에 무거워진다.
세 번째는 git pull 습관이다. 원격에 커밋이 있는 상태에서 그냥 git pull을 하면 merge 커밋이 생기고, 이력이 지저분해진다. 혼자 쓰는 저장소에서는 git config --global pull.rebase true로 rebase를 기본으로 두는 편이 읽기 쉽다. 다만 이미 push한 커밋을 rebase하면 해시가 바뀌므로, 협업 브랜치에서는 습관대로 쓰면 안 된다.
참고 자료
- git-init — 기본 브랜치 이름, Git 3.0에서
main으로 변경 예정 - git-config —
user.name,init.defaultBranch,pull.rebase - git-switch · git-restore — 2.23에서 분리된 명령
- git-merge —
--allow-unrelated-histories, 충돌 처리 - git-push —
--force-with-lease동작 - git/git 태그 — v2.56.0
- GitHub — About authentication to GitHub — 토큰·SSH 키
- Mac 개발환경 세팅 · Python 가상환경 venv 만들기 · Claude Code 설치·사용법
'IT' 카테고리의 다른 글
| Perplexity Teammates란? — 일을 맡기는 AI 동료, 가격·한계 총정리 (0) | 2026.11.06 |
|---|---|
| AI 탈옥이란? — 프롬프트 인젝션과 차이, 막는 방법 총정리 (0) | 2026.11.06 |
| Mac 개발환경 세팅 — Homebrew·iTerm2·zsh 설치 순서와 막히는 곳 (0) | 2026.11.06 |
| Gemini Omni 1.2 Flash란? — 15초 영상·초당 $0.07 총정리 (2026) (0) | 2026.11.06 |
| Phone Harness 사용법 — AI 에이전트가 내 폰을 직접 조작하는 도구 (0) | 2026.11.05 |


















