콘텐츠로 이동

git commit과 push, 원격 저장소

11/11(수)

한 줄 요약: commit은 변경을 내 컴퓨터의 .git에 기록하는 일이고, push는 그 기록을 원격 저장소(GitHub 등)로 보내는 일이다. 둘은 별개 단계라서, remote(원격 저장소 연결)가 없어도 commit은 얼마든지 쌓인다.

📍 만난 상황

  • 2026-11-11 10:56 — 학습 일지 자동화를 만들던 중이었다(→ 작업 2). Claude가 "commit까지 끝났다"고 말한 직후, 아직 새 repo를 연결하지 않았는데 커밋을 어디에 한 거냐고 물었다 → 그날 일지
  • 확인해 보니 remote가 없었다. 커밋 2개는 Mac의 ~/learning-log/.git 안에만 있었다.
  • 오전에 git init으로 로컬 저장소만 만들었기 때문이다. 자동 작업도 "remote 미설정 → push 생략"으로 끝나게 되어 있었다.
  • 그 뒤 개인 GitHub에 빈 repo를 만들고 SSH로 연결해 첫 push를 했다. 쌓여 있던 커밋이 그때 한꺼번에 올라갔다.

🧩 쉽게 말하면

일기장과 클라우드 백업을 떠올리면 된다.

commit은 일기장에 오늘 쓴 쪽에 확정 도장을 찍는 일이다. 일기장은 내 책상 위에 있다. 인터넷이 없어도 된다.

push는 도장 찍힌 쪽들을 클라우드에 올리는 일이다. 클라우드 계정을 연결하지 않았으면 도장은 찍히지만 어디에도 올라가지 않는다.

둘이 한 동작이었다면 저장할 때마다 인터넷이 필요하다. 실수한 내용도 바로 남에게 공개된다. 나눠 두었기 때문에 올리기 전에 정리할 기회가 생긴다.

📖 제대로 알기

기본 용어

  • 저장소(repository, repo): 파일과 그 변경 이력을 함께 담은 단위.
  • .git 폴더: 이력이 실제로 저장되는 숨은 폴더. 커밋은 모두 여기 들어 있다.
  • 커밋(commit): 그 시점 파일 상태의 스냅숏(사진)과 메시지, 작성자, 이전 커밋을 묶은 기록 하나.
  • 스테이징(staging, git add): 다음 커밋에 넣을 변경을 골라 두는 대기 칸.
  • 브랜치(branch): 커밋 줄기에 붙인 이름표. 보통 main.

원격 관련 용어

  • 원격 저장소(remote): 다른 곳(GitHub, 사내 서버)에 있는 같은 저장소. 로컬에는 별명과 주소만 등록한다. 관례상 별명은 origin.
  • push: 원격에 없는 내 커밋을 보낸다.
  • fetch: 원격의 새 커밋을 받아 오기만 한다. 내 작업 줄기는 안 바꾼다.
  • pull: fetch 한 뒤 내 줄기에 합친다(merge 등).
  • origin/main: "마지막으로 확인한 원격 main의 위치"를 로컬에 적어 둔 표시.

init과 clone의 차이

  • git init: 빈 로컬 저장소만 만든다. remote가 없다. 오늘 경우가 이것이다.
  • git clone <주소>: 원격을 통째로 복사해 온다. origin이 자동으로 등록된다. 그래서 clone으로 시작한 사람은 "commit하면 당연히 올라갈 곳이 있다"고 느끼기 쉽다.

⚙️ 어떻게 동작하나

flowchart LR
  W["작업 폴더"] -->|"git add"| S["스테이징"]
  S -->|"git commit"| L[("로컬 저장소<br/>.git")]
  L -->|"git push"| R[("원격 저장소<br/>GitHub")]
  R -->|"git fetch / pull"| L
왼쪽 세 칸은 모두 내 컴퓨터 안이다. 네트워크를 쓰는 화살표는 push와 fetch/pull뿐이다.

  1. git init — .git 폴더가 생긴다. 이 시점에 원격은 없다.
  2. 파일 수정 → git add — 커밋에 넣을 변경을 스테이징에 올린다.
  3. git commit — .git 안에 커밋 기록이 생긴다. 네트워크를 전혀 쓰지 않는다.
  4. git remote add origin <주소> — 원격의 별명과 주소를 등록만 한다. 아직 아무것도 보내지 않는다.
  5. git push -u origin main — 원격에 없는 커밋을 모두 보낸다. 로컬에 2개 쌓였으면 2개가 한꺼번에 간다. -u는 "앞으로 이 브랜치는 origin/main과 짝"이라는 뜻이다.
  6. 원격에 이미 다른 커밋이 있으면 push가 거절된다. 예: GitHub에서 repo를 만들며 README를 같이 만든 경우. 이때는 pull로 합친 뒤 push한다. 오늘도 GitHub의 초기 README 커밋을 강제로 덮어쓰지 않고 merge로 합쳤다.

왜 이렇게 설계됐나: git은 분산 버전 관리(DVCS: 각 컴퓨터가 전체 이력을 갖는 방식)다. 각자 오프라인에서 커밋하고, 원할 때만 원격과 맞춘다. 그래서 빠르고, 서버가 죽어도 이력이 남는다.

🧪 예시

  • 예시 1 · 일상에 빗대어: 월요일과 화요일에 일기 2쪽에 도장을 찍었다. 수요일에 클라우드 계정을 연결하고 "올리기"를 눌렀다. 그러면 월·화 2쪽이 한꺼번에 올라간다. 월요일 것이 사라지지 않았다. 내 책상 일기장에 그대로 있었기 때문이다.

  • 예시 2 · 실제로는: 오늘 흐름을 명령으로 다시 쓰면 이렇다.

git init                                      # ①
git add . && git commit -m "첫 일지"           # ②
git remote -v                                 # ③
git remote add origin git@<호스트별칭>:<계정>/learning-log.git  # ④
git log --oneline origin/main..main           # ⑤
git push -u origin main                       # ⑥
① 로컬 저장소를 만든다. remote는 없다. ② 커밋한다. 이 커밋은 .git에만 있다. ③ 아무것도 안 나오면 remote가 없다는 뜻이다. "어디에 커밋했지?" 싶을 때 가장 먼저 칠 명령이다. ④ 원격 주소를 등록한다. 개인·회사 계정을 나눠 쓰려고 SSH 호스트 별칭을 썼다. ⑤ 아직 원격에 안 올라간 커밋 목록을 본다(fetch 이후 정확하다). ⑥ 쌓인 커밋을 한 번에 보낸다.

⚖️ 비교 · 흔한 오해

명령 어디에 기록되나 네트워크
git commit 내 컴퓨터 .git 안 씀
git push 원격 저장소 씀 (remote 필요)
git fetch 내 .git의 origin/… 표시 씀
git pull 내 브랜치 (fetch + 합치기) 씀

헷갈렸던 점: "commit = GitHub에 올리는 것"

  • 왜 그렇게 생각하기 쉬운가
  • GitHub 웹에서 파일을 고치면 "Commit changes" 버튼 하나로 바로 GitHub에 반영된다. 이건 원격 저장소에서 직접 커밋한 경우다.
  • VS Code 같은 도구에는 "Commit & Push", "Sync" 버튼이 있어서 두 단계가 한 번에 일어난다.
  • 회사 저장소는 대부분 clone으로 시작해서 origin이 이미 있다.
  • 실제로는: 로컬에서 하는 commit은 언제나 .git에만 기록된다. 올리려면 push가 따로 필요하다.

또 다른 오해: "remote 없이 커밋하면 날아간다"

아니다. .git에 안전하게 남는다. 다만 그 컴퓨터에만 있다. 디스크가 고장 나거나 폴더를 지우면 함께 사라진다.

🛠️ 실무에서는

push 전에 확인할 것 - git remote -v: 어디로 가는지. - git log --oneline origin/main..main: 무엇이 올라가는지. - git log --format='%an <%ae>' -3: 작성자 이름·이메일이 맞는지. 개인/회사 계정을 섞어 쓰면 특히 본다. - 비밀값(토큰·키)이 커밋에 없는지. push 전이면 고치기 쉽지만, push 후엔 이력에 남는다.

push 전에는 자유롭게 고칠 수 있다 - 마지막 커밋 고치기: git commit --amend - 여러 커밋 정리: git rebase -i - push 후에 이렇게 고치면 강제 push(--force)가 필요하다. 남이 이미 받아 간 이력을 바꾸게 되니 공용 브랜치에서는 피한다.

문제가 생기면 먼저 볼 것: push가 "rejected"로 거절되면, 원격에 내가 없는 커밋이 있다는 뜻이다. git pull로 합친 뒤 다시 push한다. 강제 push로 덮어쓰는 건 마지막 수단이다.

❓ 자주 묻는 질문

  • Q. origin은 꼭 그 이름이어야 하나? A. 아니다. 관례일 뿐이다. 원격을 여러 개 등록할 때는 upstream, personal처럼 다른 별명을 붙인다.
  • Q. remote를 나중에 연결해도 예전 커밋이 다 올라가나? A. 그렇다. push는 원격에 없는 커밋을 모두 보낸다.
  • Q. commit 작성자 이메일은 push 때 정해지나? A. 아니다. commit할 때 정해져 커밋 안에 박힌다. 바꾸려면 커밋을 다시 써야 하니 push 전에 확인한다.

🔭 더 깊이 보기

  • 브랜치와 merge·rebase의 차이 — 원격과 이력이 갈라졌을 때 어떻게 합칠지 정하는 기준이라서.
  • SSH 키와 호스트 별칭으로 계정 여러 개 쓰기 — 개인·회사 GitHub를 한 컴퓨터에서 나눠 쓰는 방법이라서.
  • .gitignore와 비밀값 관리 — push 전에 민감한 파일이 섞이지 않게 막는 첫 단계라서.

📚 참고 자료

  • Pro Git 2판 한국어 — 2.5 Git의 기초: 리모트 저장소 (git 공식 사이트) — remote 등록, push, fetch, pull · 링크
  • Pro Git 2판 한국어 (git 공식 사이트) — 책 전체 목차. 1장 "Git 기초"에서 세 가지 상태(수정·스테이징·커밋)를 볼 것 · 링크
  • GitHub 문서 (GitHub Docs 한국어) — 원격 저장소 연결과 첫 push 안내 · 링크

🗓️ 이력

  • 2026-11-11: remote를 연결하지 않았는데 커밋을 어디에 했냐고 물음. commit과 push가 별개라는 걸 확인 → 일지