SPACE LOGBOOK

OCEAN LOGBOOK

Git에서 말하는 Origin은 절대경로가 아니다.

2026.08.26

Git에서 말하는 Origin은 절대경로가 아니다.

2026.08.26

오늘 세무 업무와는 전혀 상관없는 곳에서, 아주 좋은 공부를 하나 했다. 운영 중인 웹사이트 서버를 정리하다가 우연히 마주친 해프닝인데, 파고들어보니 git의 origin이라는 개념을 제대로 이해하는 데 이만한 실전 사례가 없다 싶어서 기록으로 남긴다.

#git#origin#바이브코딩#인프라정리

1. 발단 — “로컬에서 커밋만 하고 푸시는 안 해도 될까?”

운영 중인 홈페이지의 UI를 손보다가, 사소한 질문 하나를 던졌다. “지금 로컬에서 커밋만 하고 GitHub에 푸시는 안 해도 되나?” 돌아온 답이 흥미로웠다.

“라이브 서버의 git이 GitHub 원격이 아니라 로컬 번들 파일을 origin으로 쓰고 있어서, 지금 푸시해도 서버에 자동 반영되지 않는다”

처음엔 이 말이 무슨 뜻인지 감이 안 왔다. “서버 git도 커밋해달라”고 시켰더니 별문제 없이 서버에서도 커밋이 됐다. 그런데 뭔가 이상했다. 로컬 커밋 해시와 서버 커밋 해시가 서로 다르다는 것이다. 분명 같은 파일, 같은 내용인데 왜 서로 다른 “이력”을 갖고 있는 걸까?

2. 먼저 origin이 뭔지부터 — 우체통 비유

git에서 origin은 사실 아무 의미도 없는 이름표다. “이게 내 주 원격 저장소야”라고 스스로 붙인 별명일 뿐이라, 실제로 어디를 가리킬지는 완전히 자유다. GitHub 주소를 가리킬 수도 있고, 서버 안의 로컬 파일을 가리킬 수도 있다.

문제는 여러 컴퓨터가 협업하는 구조에서 생긴다. 로컬PC와 서버가 진짜로 “같은 히스토리”를 공유하려면, 둘의 origin이 같은 곳을 가리키고 있어야 한다.

origin은 “우체통을 가리키는 화살표”다 ✔ 정상 — 모두 같은 우체통 로컬 PC 서버 GitHub ✘ 오늘의 해프닝 — 서버만 딴 곳을 봄 로컬 PC GitHub 서버 번들 파일

그림 1. origin이 같은 곳(GitHub)을 보면 협업이 되고, 다른 곳을 보면 겉보기엔 똑같이 동작해도 실제로는 서로 무관한 두 개의 역사가 쌓인다.

3. 왜 서버만 딴 곳을 보고 있었나 — 4단계로 재구성한 전말

Claude Code와 함께 서버를 뒤져본 결과, 원인은 “처음엔 GitHub 저장소가 없었다”는 아주 단순한 사실에서 출발한 것으로 드러났다. 시간 순으로 재구성하면 이렇다.

① 최초 — GitHub 저장소가 아직 없던 시절 로컬에서 개발 → 서버로 옮길 방법이 필요 → GitHub 계정/인증 세팅 없이 가장 간단한 방법인 git bundle로 저장소 전체를 파일 하나로 묶어 서버로 전송 로컬 저장소 bundle 전송 서버 (origin=번들) ② 나중에 — GitHub에 정식 저장소 생성 필요에 의해 개인 계정/프로젝트-테마 저장소를 GitHub에 만듦 이때 로컬 PC의 origin만 GitHub 주소로 새로 설정됨 로컬 (origin=GitHub) GitHub 서버 (origin=번들, 그대로) ← 전환 누락! ③ 그 사이 — 서버는 “혼자만의 역사”를 계속 쌓음 배포할 때마다 파일을 scp로 복사받고, 서버 스스로 스냅샷 커밋을 생성 파일 내용은 로컬/GitHub와 계속 일치했지만, 커밋 해시(이력)는 계속 갈라짐 로컬→GitHub 이력 A 서버 자체 이력 B ≠ ④ 오늘 — 서버 origin을 GitHub로 통일 두 달 전쯤 한번 시도했다가 미완성으로 남았던 deploy key를 재발견, 전환 완료

그림 2. “GitHub 없이 시작 → 나중에 GitHub 생성 → 로컬만 전환 → 서버는 방치”라는 흐름이 오늘 해프닝의 근본 원인이었다.

흥미로운 부가 발견 — 서버의 /root/.ssh/를 뒤져보니 두 달 전쯤 생성된 배포 전용 SSH 키가 이미 존재했다. GitHub Deploy Keys 목록에도 지문이 똑같은 키가 등록되어 있었다. 즉, 과거의 나(혹은 과거 세션)가 오늘과 똑같은 전환 작업을 한 번 시도했다가, 키만 만들고 GitHub 등록까지 하고서 실제 연결은 마무리 짓지 않고 멈췄던 것이다. 미스터리를 풀어보니 결국 “내가 예전에 벌여놓고 잊어버린 일”이었다는 게 이 해프닝의 반전 포인트였다.

4. 왜 이게 “겉보기엔” 문제없이 굴러갔나

가장 헷갈렸던 지점은 바로 이거였다. 서버 origin이 잘못돼 있어도, 배포는 몇 달간 아무 문제 없이 잘 됐다. 어떻게 그럴 수 있었을까?

이유는 배포 스크립트(deploy-to-server.ps1류의 배포 자동화 스크립트)가 애초에 git의 push/pull 기능을 아예 쓰지 않는 구조였기 때문이다.

기존 배포 방식 — git이 아니라 사실상 “파일 택배”였다 로컬 커밋 scp 전송 서버에 파일 복사 sudo cp 서버 자체 스냅샷 커밋 사이트 반영 → 파일 “내용”만 옮기면 되는 구조라, git origin이 어디를 보든 사이트는 멀쩡히 돌아감 → 문제는 “파일이 안 옮겨질 때”가 아니라 “히스토리를 신뢰해야 할 때(비교/롤백/추적)” 드러남

그림 3. git의 이력 관리 기능을 안 쓰고 파일 복사로만 배포했기 때문에, origin이 잘못돼 있어도 티가 안 났다. 이게 이 해프닝이 오래 안 들킨 이유다.

5. 전환 — “서버는 pull만 하면 되는” 구조로

정상적인 구조라면 이래야 한다. 로컬에서 커밋하고 push하면, 서버는 그저 git pull 한 줄로 GitHub의 최신 상태를 그대로 받아오면 된다. 별도의 파일 복사도, 서버 자체 커밋도 필요 없다.

전환 전: 로컬(커밋+push) → 서버(파일 복사 + 자체 커밋, GitHub와 무관) — 파일 내용은 일치, 커밋 해시는 불일치
전환 후: 로컬(커밋+push) → 서버(git pull만) — 파일 내용도, 커밋 해시도 완전히 일치

다만 origin 주소만 GitHub로 바꾼다고 끝나는 게 아니었다. 서버가 그동안 쌓아온 독자적인 커밋들이 있어서, 곧바로 pull하면 충돌이 날 수 있었다. 그래서 다음 순서를 밟았다.

  1. 안전 확인 — 서버가 추적하던 파일 80개 전체를 GitHub와 blob 해시(내용 지문)로 대조 → 100% 일치 확인. 즉 이력만 다를 뿐 내용 손실 위험은 없다는 게 증명됨
  2. 백업 브랜치 보존 — 혹시 모를 상황을 대비해 서버의 기존 이력을 backup/pre-pull-migration 브랜치로 남겨둠
  3. origin 교체 — 서버 origin을 번들 파일에서 실제 GitHub 주소(SSH)로 변경, 저장소 전용 배포키(Deploy Key)로 인증 연결
  4. 이력 정렬 — git reset --hard origin/main으로 서버를 GitHub와 완전히 동일한 커밋으로 맞춤
  5. 배포 스크립트 재작성 — scp+파일복사 방식을 git fetch && merge --ff-only 방식으로 전면 교체
전환 완료 후 구조 — 하나의 우체통, 하나의 이력 로컬 PC commit + push GitHub 서버 git pull만 세 곳 모두 동일 커밋 해시 — 지금 서버 상태가 “GitHub의 정확히 어느 시점”인지 언제든 명확하게 대조 가능한 상태가 됨

그림 4. 로컬 · GitHub · 서버 세 곳의 커밋 해시가 완전히 하나로 통일된 최종 구조.

6. 오늘의 교훈

돌아보니 이번 건이 처음이 아니었다. 사무실과 집, 두 군데에서 작업하다 배포 과정에서 겪었던 문제, 로컬에서 커밋·푸시는 했는데 서버가 fetch를 안 해서 생겼던 문제… 그리고 오늘처럼 “처음엔 GitHub 없이 시작했다가 중간에 저장소를 만들면서” 생긴 문제까지. 1인 개발 체제로 인프라를 하나씩 늘려가다 보면 자연스럽게 마주치는 성장통들인 것 같다.

  • origin은 이름표일 뿐, 어디를 가리키든 자유다 — 그래서 여러 컴퓨터가 협업할 땐 반드시 “같은 곳”을 보게 맞춰줘야 한다
  • 파일 내용이 같다고 이력까지 같은 게 아니다 — git에서는 “무엇이 담겨있나”만큼 “어떤 경로로 여기까지 왔나”도 중요하다
  • 겉보기에 잘 돌아간다고 구조가 옳은 건 아니다 — 파일 복사 기반 배포는 git의 이력 관리 기능을 우회했기 때문에 문제가 안 드러났을 뿐이다
  • 미완성으로 남긴 작업은 반드시 흔적을 남긴다 — 두 달 전에 벌여놓고 잊었던 SSH 키 하나가 오늘 정확히 필요한 순간에 다시 나타났다

결국 오늘의 해프닝은 “origin”이라는, 알고 나면 별것 아닌 개념 하나가 왜 그렇게 중요한지를 몸으로 배우게 해준 사례였다. 세무 실무에서 법령 개정 히스토리를 추적하는 것과, 코드에서 커밋 히스토리를 추적하는 것 — 은근히 닮아 있다는 생각도 들었다. ^^

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

이 기록은 여기까지지만,
생각은 아직 이동 중이다