← posts/b.log()

blog92@web:~$ cat posts/github-03-remote-auth-and-push-pull.md

GIT3 min read

GitHub 완전 정복 3편 — 원격 저장소 인증(SSH·PAT)과 push·fetch·pull의 차이

HTTPS+PAT와 SSH 키 두 인증 방식, 계정별 ~/.ssh/config 분리, SSH 커밋 서명, remote 연결 관리, 그리고 pull을 바로 쓰지 말고 fetch → 검토 → merge로 가야 하는 이유와 명령별 위험도 분류표를 다룹니다.

이전 편: 2편 — 커밋 만들기, 좋은 커밋 메시지, 히스토리 조회와 .gitignore

2.1 인증 — HTTPS vs SSH

GitHub는 2021년 8월부터 비밀번호 인증을 폐지했습니다. 두 가지 선택지가 있습니다.

(A) HTTPS + PAT (Personal Access Token)

bash
git clone https://github.com/user/repo.git
# Username: 내 계정
# Password: PAT 토큰 (비밀번호 아님)

토큰 발급: Settings → Developer settings → Personal access tokens → Fine-grained tokens Fine-grained 토큰은 저장소 단위·권한 단위로 범위를 좁힐 수 있어 classic 토큰보다 안전합니다.

매번 입력하기 싫으면 credential helper를 씁니다.

bash
git config --global credential.helper manager   # Windows
git config --global credential.helper osxkeychain  # macOS
git config --global credential.helper 'cache --timeout=3600'  # Linux

Windows에서 Git for Windows를 기본값으로 설치했다면 이 설정은 이미 적용돼 있습니다. git config --global --show-origin credential.helper로 현재 값을 먼저 확인하세요.

(B) SSH 키 (권장)

bash
# 1. 키 생성
ssh-keygen -t ed25519 -C "hong@example.com"
# 저장 위치 기본값 엔터, passphrase는 설정하는 걸 권장
 
# 2. ssh-agent에 등록
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
 
# 3. 공개키 복사
cat ~/.ssh/id_ed25519.pub
 
# 4. GitHub → Settings → SSH and GPG keys → New SSH key 에 붙여넣기
 
# 5. 연결 테스트
ssh -T git@github.com
# → Hi username! You've successfully authenticated...

회사 계정과 개인 계정을 같은 PC에서 쓸 때는 ~/.ssh/config로 분리합니다.

ssh-config
Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work
 
Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal
bash
git clone git@github-work:company/repo.git

2.2 커밋 서명 (GPG / SSH Signing)

GitHub에서 커밋 옆에 붙는 Verified 뱃지입니다. 커밋 author는 누구나 사칭할 수 있으므로(그냥 user.email 설정값입니다), 오픈소스나 보안이 중요한 조직에서는 서명을 요구합니다.

bash
# SSH 키로 서명하는 최신 방식 (Git 2.34+, OpenSSH 8.8+, GPG보다 간단)
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true
# GitHub → SSH and GPG keys 에 "Signing Key" 타입으로 동일 키 등록

2.3 원격 저장소 연결

bash
git remote -v                                        # 확인 (읽기 전용)
git remote add origin git@github.com:user/repo.git   # 추가
git remote set-url origin <새-주소>                   # 주소 변경
git remote rename origin upstream                    # 이름 변경
git remote remove origin                             # 연결 해제 (원격은 안 지워짐)
git remote show origin                               # 상세 정보

origin은 관례일 뿐 특별한 이름이 아닙니다. 포크 워크플로에서는 보통 이렇게 씁니다.

  • origin — 내 포크
  • upstream — 원본 저장소

2.4 push / fetch / pull — 차이를 정확히

bash
git push origin main            # 로컬 main → 원격 main
git push -u origin main         # -u: 업스트림 추적 설정 (이후 git push만 입력하면 됨)
git push --all                  # 모든 브랜치
git push --tags                 # 태그 전송
git push origin --delete old-branch   # 원격 브랜치 삭제 ⚠
bash
git fetch origin                # 원격 정보만 가져옴 — 작업 디렉토리 안 건드림 ★
git fetch --all --prune         # 모든 원격 + 사라진 원격 브랜치 정리
bash
git pull origin main            # = fetch + merge (자동)
git pull --rebase origin main   # = fetch + rebase

pull을 바로 쓰지 말아야 하는 이유는 이렇습니다.

pull은 원격 변경을 가져오는 동시에 내 작업 디렉토리에 즉시 병합합니다. 원격에 무엇이 들어왔는지 모르는 상태에서 병합이 일어나므로, 충돌이 나거나 예상치 못한 변경이 섞이면 이미 상황이 복잡해진 뒤입니다.

권장 흐름:

bash
git fetch origin                        # 1. 가져오기만 (안전, 아무것도 안 바뀜)
git log --oneline HEAD..origin/main     # 2. 원격에 뭐가 새로 들어왔는지 확인
git diff HEAD origin/main               # 3. 실제 코드 차이 확인
git merge origin/main                   # 4. 납득한 뒤 병합

fetch 후 origin/main은 원격 추적 브랜치라는 읽기 전용 포인터입니다. 내 main과 별개로 존재하며, 이 둘을 비교할 수 있다는 점이 fetch → 검토 → merge 패턴이 안전한 이유입니다.

text
fetch 직후 상태
  main         → A ─ B ─ C          (내 로컬)
  origin/main  → A ─ B ─ C ─ D ─ E  (원격에서 가져온 것)
                          └─ 여기 D, E가 뭔지 확인하고 merge 결정

2.5 명령별 위험도 분류표

이 표를 머릿속에 넣어두면 사고의 90%는 예방됩니다.

등급명령영향 범위
🟢 안전 (읽기 전용)status log diff show blame fetch branch(목록) remote -v아무것도 변경하지 않음
🟡 로컬만 변경 (복구 쉬움)add commit branch(생성) switch merge stash tag로컬 저장소만. reflog로 대부분 복구 가능
🟠 로컬 파일 소실 가능restore checkout -- <file> reset --hard clean -fd stash drop커밋 안 된 변경은 복구 불가
🔴 히스토리 변경rebase commit --amend reset(push 이후) filter-repo로컬에선 reflog로 복구 가능, push 전이라면 안전
⚫ 원격 파괴push --force push --delete남의 작업을 날릴 수 있음. 되돌리기 매우 어려움

안전 원칙 #3 — 🟠 이상 등급의 명령을 실행하기 전에는 반드시 두 가지를 하세요.

  1. git status로 커밋 안 된 변경이 없는지 확인
  2. 불안하면 git branch backup/$(date +%Y%m%d-%H%M) 로 현재 상태에 이름표를 박아두기

브랜치는 커밋 하나를 가리키는 아주 작은 파일일 뿐입니다. 백업 브랜치를 만드는 비용은 사실상 0이고, 복구 가치는 무한합니다.

더 깊이

COMMENTS (…)

댓글을 불러오는 중이에요.

NEW COMMENT0 / 1000
⌘↵ 전송

blog92@web:~$ cd ..