Git push pull 차이 | 원격 저장소·GitHub 협업·Pull Request 완벽 가이드
이 글의 핵심
Git push pull 차이에 대한 실전 가이드입니다. 원격 저장소·GitHub 협업·Pull Request 완벽 가이드 등을 예제와 함께 상세히 설명합니다.
[Git 실전 가이드 #3] 원격 저장소와 협업
이전 글: Git 브랜치와 병합(#2)에서 브랜치 생성·병합·충돌 해결을 다뤘습니다.
원격 저장소(remote)는 GitHub·GitLab 같은 서버에 있는 Git 저장소입니다. 커밋은 각 시점의 스냅샷이고, push는 로컬에 쌓인 스냅샷을 원격에 복사해 올리는 과정, pull은 원격의 새 스냅샷을 가져와 현재 브랜치에 합치는 과정입니다. 팀원과 같은 이력을 맞추려면 이 두 동작을 번갈아 쓰게 됩니다. 이 글에서는 remote 추가·push·pull·fetch와 GitHub 협업·Pull Request(PR) 흐름까지 정리합니다.
이 글을 읽으면:
git remote,git push,git pull,git fetch를 올바르게 사용할 수 있습니다.- push와 pull의 차이,
pull --rebase,push --force-with-lease를 언제 써야 하는지 알 수 있습니다. - GitHub에서 브랜치 공유·PR·이슈 연동·Actions로 협업하는 방법을 이해할 수 있습니다.
- origin·upstream·fork, SSH/HTTPS, 팀 규칙(커밋·브랜치 보호·리뷰)을 실무에 맞게 정리할 수 있습니다.
목차
- 원격 저장소란
- 원격 추가·확인·clone
- push: 로컬 → 원격 올리기
- pull과 fetch: 원격 → 로컬 가져오기
- GitHub 협업과 Pull Request
- 자주 묻는 질문 (FAQ)
1. 원격 저장소란
로컬 vs 원격
- 로컬 저장소: 여러분 PC의
.git폴더. commit은 여기만 반영됩니다. - 원격 저장소: GitHub·GitLab·Bitbucket 등 서버에 있는 저장소. push로 로컬 커밋을 올리면 팀원이 pull·clone으로 받을 수 있습니다.
push는 “로컬 브랜치의 커밋을 원격 브랜치에 올리는 것”, pull은 “원격 브랜치의 최신 커밋을 가져와서 현재 로컬 브랜치에 합치는 것”이라고 보면 됩니다. 협업 시에는 작업 전에 pull로 최신 상태를 맞추고, 작업 후에 push로 올리는 습관이 중요합니다.
2. 원격 추가·확인·clone
원격 저장소 추가
로컬 저장소에 원격 저장소를 연결합니다:
git remote add origin https://github.com/username/repo.git
# git remote add: 원격 저장소 추가 명령
# origin: 원격 저장소의 별칭 (관례적으로 origin 사용)
# https://github.com/username/repo.git: 원격 저장소 URL
#
# 동작:
# .git/config 파일에 아래 내용이 추가됨:
# [remote "origin"]
# url = https://github.com/username/repo.git
# fetch = +refs/heads/*:refs/remotes/origin/*
origin의 의미:
- origin: 원격 저장소의 기본 이름 (관례)
- 다른 이름도 가능:
git remote add upstream https://... - 여러 원격 저장소를 추가할 수 있음 (origin, upstream, backup 등)
실전 예시:
# 1. 로컬 저장소 초기화
git init
# 2. 원격 저장소 추가
git remote add origin https://github.com/myuser/myproject.git
# 3. 첫 커밋 후 push
git add .
git commit -m "Initial commit"
git push -u origin main
# -u: 추적 관계 설정 (다음부터 git push만 입력 가능)
원격 목록·URL 확인
git remote -v
# origin https://github.com/username/repo.git (fetch)
# origin https://github.com/username/repo.git (push)
-v로 각 remote 이름과 URL을 확인할 수 있습니다. URL을 바꾸려면 **git remote set-url origin <새URL>**을 사용합니다.
저장소 복제(clone)
원격 저장소를 로컬로 복사합니다:
git clone https://github.com/username/repo.git
# git clone: 원격 저장소를 로컬로 복제
# https://github.com/username/repo.git: 복제할 원격 저장소 URL
#
# 동작:
# 1. "repo" 폴더 생성
# 2. 원격 저장소의 모든 커밋 히스토리 다운로드
# 3. 기본 브랜치(main/master)를 체크아웃
# 4. origin 원격 저장소 자동 설정
# 5. 추적 관계 자동 설정 (origin/main → main)
cd repo
# 복제된 폴더로 이동
clone 후 상태:
# 원격 저장소 확인
git remote -v
# origin https://github.com/username/repo.git (fetch)
# origin https://github.com/username/repo.git (push)
# → origin이 자동으로 설정되어 있음
# 브랜치 확인
git branch -vv
# * main 1a2b3c4 [origin/main] Initial commit
# → main 브랜치가 origin/main을 추적하도록 설정됨
clone vs init + remote add:
# 방법 1: clone (간편, 권장)
git clone https://github.com/username/repo.git
# 한 번에 모든 설정 완료
# 방법 2: init + remote add (수동)
mkdir repo
cd repo
git init
git remote add origin https://github.com/username/repo.git
git fetch origin
git checkout -b main origin/main
# 여러 단계 필요, 실수 가능성 있음
clone 옵션:
# 특정 브랜치만 clone
git clone -b develop https://github.com/username/repo.git
# 얕은 clone (최근 커밋만, 빠름)
git clone --depth 1 https://github.com/username/repo.git
# 특정 폴더 이름으로 clone
git clone https://github.com/username/repo.git my-project
3. push: 로컬 → 원격 올리기
기본 push
git push -u origin main
- origin: 원격 저장소 이름
- main: 로컬 브랜치 이름. “origin의 main 브랜치에 현재 main을 올린다”는 뜻입니다.
- -u (—set-upstream): “앞으로 git push만 쳐도 origin main으로 보내라”는 추적 관계를 저장합니다. 최초 1회만 써도 됩니다.
이후에는 git push만 입력해도 origin의 해당 브랜치로 올라갑니다. 다른 브랜치를 올릴 때는 git push -u origin feature/login처럼 브랜치 이름을 지정하면 됩니다.
push가 거부될 때
원격에 내가 가진 것보다 더 최신 커밋이 있으면 push가 거부됩니다. 이때는 먼저 git pull(또는 git pull —rebase)로 원격 변경을 받아 온 뒤, 다시 git push하면 됩니다. “원격이 앞서 있으니 당겨서 맞춘 다음 올리라”는 의미입니다.
git pull origin main
git push origin main
4. pull과 fetch: 원격 → 로컬 가져오기
git pull
pull은 “원격 저장소의 변경을 가져와서 현재 브랜치에 바로 병합”합니다. fetch + merge를 한 번에 하는 명령이라고 보면 됩니다.
git pull origin main
현재 브랜치가 main일 때, origin/main의 최신 커밋을 가져와 main에 병합합니다. 협업 시 “작업 시작 전에 한 번 pull”하는 것이 충돌을 줄이는 데 도움이 됩니다.
git fetch
fetch는 “원격의 최신 이력을 가져오기만 하고, 현재 브랜치를 바로 바꾸지 않음”입니다. 가져온 내용은 origin/main 같은 원격 추적 브랜치에만 반영됩니다.
git fetch origin
git log origin/main # 원격 main 상태 확인
git merge origin/main # 필요할 때 병합
“일단 원격 상태만 확인하고, 나중에 병합할지 결정하고 싶을 때” fetch를 쓰고, “당장 현재 브랜치를 최신으로 맞추겠다”면 pull을 쓰면 됩니다.
push와 pull 정리
| 동작 | 명령 | 설명 |
|---|---|---|
| 로컬 → 원격 | git push origin main | 로컬 main 커밋을 원격 main에 올림 |
| 원격 → 로컬(병합까지) | git pull origin main | 원격 main을 가져와 현재 브랜치에 병합 |
| 원격 → 로컬(가져오기만) | git fetch origin | 원격 이력을 origin/main 등에만 반영 |
**git pull --rebase와 git push --force-with-lease**처럼 협업에서 자주 쓰는 변형은 8. 실전 명령어에서 이어서 정리합니다.
5. GitHub 협업과 Pull Request
PR이란?
Pull Request(PR)는 “내 브랜치의 변경을 main(또는 develop)에 반영해 달라고 요청하는 것”입니다. GitHub·GitLab에서는 코드 리뷰·토론·CI 결과를 PR 안에서 처리합니다.
기본 흐름
- 로컬에서 feature 브랜치를 만들고 작업·커밋합니다.
- git push -u origin feature/login으로 해당 브랜치를 원격에 올립니다.
- GitHub에서 “Compare & pull request” 버튼을 눌러 base: main ← compare: feature/login으로 PR을 만듭니다.
- 리뷰·수정 후 Merge하면 main에 반영됩니다.
- (선택) 병합된 feature/login 브랜치를 원격·로컬에서 삭제하고, main을 pull해서 최신으로 맞춥니다.
이렇게 하면 main은 항상 검증된 변경만 포함하고, 이력이 PR 단위로 남아 추적하기 쉬워집니다.
6. 원격 저장소 심화: origin·여러 remote·SSH와 HTTPS
origin이란 무엇인가
origin은 Git이 붙여 주는 고정된 특별 이름이 아니라, “지금 이 저장소에서 기본으로 쓰는 원격”을 가리키기 위해 관례적으로 쓰는 별칭(alias)입니다. git clone을 하면 첫 원격이 보통 origin으로 .git/config에 기록됩니다.
- 실제 URL은 **
git remote -v로 확인하고,git remote get-url origin**으로만 URL만 볼 수도 있습니다. - 팀에서는 “origin = 우리가 매일 push하는 저장소”처럼 의미를 맞춰 두면, “origin에 올려줘” 같은 대화가 단순해집니다.
- 이름은 자유롭습니다.
git remote rename origin company처럼 바꿀 수 있지만, 도구·문서 예제가 대부분 origin을 쓰므로, 특별한 이유가 없으면 그대로 두는 편이 협업에 유리합니다.
여러 원격 저장소 관리: upstream과 fork
같은 프로젝트에 여러 서버 쪽 저장소를 둘 수 있습니다. 대표적인 경우가 fork입니다.
- Fork: GitHub에서 원본 저장소를 내 계정으로 복사한 뒤, 로컬에서는
origin을 fork URL로 둡니다. 원본(상위) 저장소는 관례적으로 **upstream**이라는 이름으로 추가합니다.
git remote add upstream https://github.com/original-owner/awesome-project.git
git fetch upstream
git checkout main
git merge upstream/main
# 또는 팀 정책에 따라: git rebase upstream/main
- 사내에서는 메인 저장소와 미러·레거시 원격을 동시에 쓰는 경우
backup,vendor처럼 이름을 나누기도 합니다. 중요한 것은 어느 remote에 push하면 어떤 결과가 나는지를 팀과 합의하는 것입니다.
SSH vs HTTPS 인증
| 구분 | HTTPS | SSH |
|---|---|---|
| URL 예 | https://github.com/user/repo.git | [email protected]:user/repo.git |
| 인증 | 브라우저·PAT(Personal Access Token)·자격 증명 헬퍼 | SSH 공개키를 GitHub에 등록 |
| 장점 | 방화벽 환경에서 허용되는 경우가 많음 | 반복 입력이 줄고, 스크립트·CI와 궁합이 좋을 때가 많음 |
기존 저장소를 전환하려면 **git remote set-url origin <새 URL>**만 바꾸면 됩니다. 팀 표준(HTTPS만 허용, SSH만 허용 등)이 있으면 그에 맞추면 됩니다.
7. 협업 워크플로우: Fork·PR·리뷰·충돌 후 push
Fork와 Pull Request 전체 과정
- GitHub에서 원본 저장소를 Fork해 내 네임스페이스에 복사본을 만듭니다.
- fork 저장소 URL로
git clone하고, 필요하면 **git remote add upstream <원본 URL>**으로 원본을 추가합니다. - feature 브랜치를 만들어 작업한 뒤, **
git push -u origin feature/설명으로 fork(origin)**에 올립니다. (같은 저장소 내 협업이면origin에 feature 브랜치만 push하면 됩니다.) - GitHub에서 PR을 열 때 base(합쳐질 쪽, 보통 원본의
main)와 compare(내 변경 브랜치)를 지정합니다. fork에서 기여할 때는 base = 원본 저장소, compare = fork의 브랜치 조합이 됩니다. - 리뷰 피드백에 따라 커밋을 추가·수정하고, 같은 브랜치에 push하면 PR이 자동으로 갱신됩니다.
- 승인 후 Merge. 로컬에서는
git checkout main,git pull(또는upstream에서 가져오기)으로 정리합니다.
Code Review 베스트 프랙티스
- 작게 자주: 변경 범위가 작을수록 리뷰가 빠르고 정확해집니다.
- PR 본문: 무엇을·왜 바꿨는지, 스크린샷·재현 방법·위험 요소를 적습니다. “리뷰어가 맥락을 추측하지 않게” 하는 것이 목표입니다.
- 코멘트 문화: 지적보다는 질문과 제안(
~하면 어떨까요?)을 쓰고, 스레드가 해결되면 resolve합니다. - 승인 기준: 팀이 정한 최소 승인 수·필수 리뷰어·CODEOWNERS 규칙이 있으면 따릅니다.
Conflict 해결 후 force push 주의사항
- PR 브랜치에서 rebase로 최신
main을 맞추면 로컬 커밋 순서가 바뀌므로, 이미 원격에 올라간 브랜치를 갱신하려면 **git push --force-with-lease**가 필요할 수 있습니다. - **
--force-with-lease**는 “내가 마지막으로 본 원격 상태와 같을 때만 덮어쓴다”는 조건이 있어--force보다 안전하지만, 그래도 다른 사람이 같은 브랜치에 push한 내용을 덮어쓸 수 있는 위험은 남습니다. - 공유 브랜치(
main,develop등)에는 force push를 하지 않는 것이 원칙이고, 보통 저장소 브랜치 보호 규칙으로 막습니다. 충돌은 merge 커밋으로 해결하면 대개 일반git push로 충분합니다.
8. 실전 명령어: rebase pull·force-with-lease
git fetch vs git pull
git fetch: 원격의 최신 커밋·브랜치 정보를 가져와origin/main같은 원격 추적 브랜치에만 반영합니다. 현재 체크아웃한 브랜치를 자동으로 바꾸지 않습니다.git pull: 내부적으로는 **fetch+ 현재 브랜치에 대한 병합(또는 rebase)**에 가깝습니다. “지금 작업 중인 브랜치를 원격과 맞추겠다”는 의도가 분명할 때 씁니다.
정리하면, 상태만 확인하거나 병합 시점을 내가 정하고 싶을 때는 fetch 후 git log HEAD..origin/main으로 차이를 본 뒤 merge/rebase를 선택하고, 바로 동기화하려면 pull이 편합니다.
git pull —rebase
git pull --rebase(또는git pull --rebase origin main): 가져온 원격 커밋 위에 내 로컬 커밋을 다시 쌓습니다. 머지 커밋 없이 이력을 한 줄로 유지하고 싶을 때 팀에서 선호하기도 합니다.- 이미 push한 커밋을 rebase로 고치면 히스토리가 바뀌므로, 협업 브랜치에서는 팀 규칙을 반드시 확인합니다. 아직 push하지 않은 로컬 커밋 정리에 특히 잘 맞습니다.
- 기본 동작을 바꾸려면
git config pull.rebase true등을 쓸 수 있으나, 전역 설정은 동료와 충돌할 수 있으니 저장소별·팀 합의가 안전합니다.
git push —force-with-lease
- 예:
git push --force-with-lease origin feature/my-work - 원격 ref가 내가 기대하는 것과 다르면 push가 거부되어, 다른 사람이 그 사이에 올린 커밋을 실수로 덮어쓰는 확률을 줄입니다.
- 그래도 강제 push는 본인 전용 feature 브랜치 등 합의된 경우에만 쓰고,
main에는 쓰지 않는 것이 기본입니다.
9. GitHub 기능: PR 템플릿·이슈 연동·Actions
Pull Request 템플릿
저장소 루트 또는 .github/ 아래에 **pull_request_template.md**를 두면, PR을 열 때 설명란에 자동으로 본문이 채워집니다. (경로는 GitHub 문서 기준으로 여러 형태 지원.)
- 체크리스트 예: “테스트 실행함”, “문서 수정함”, “브레이킹 체인지 여부” 등을 넣어 누락을 줄입니다.
Issue 연동 (Closes #123)
PR 본문이나 커밋 메시지에 다음과 같은 키워드를 쓰면, PR이 병합될 때 이슈를 닫을 수 있습니다.
Closes #123,Fixes #45,Resolves #10등 (키워드 목록은 GitHub 문서 참고)
또한 **#이슈번호**만 적어도 교차 링크가 생겨, 추적성을 높일 수 있습니다.
GitHub Actions CI/CD 기초
.github/workflows/ 아래에 YAML 워크플로를 두면, push·pull_request 같은 이벤트마다 테스트·빌드·린트를 자동 실행할 수 있습니다.
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: echo "여기에 npm test, cargo test 등 실제 명령"
브랜치 보호 규칙에서 “필수 상태 검사”로 이 워크플로를 묶으면, CI가 통과하기 전에는 merge 불가 같은 협업 규칙을 기술적으로 강제할 수 있습니다.
10. 팀 협업 규칙: 커밋·브랜치 보호·리뷰 체크리스트
커밋 메시지 규칙
많은 팀이 Conventional Commits 스타일을 씁니다.
- 형식 예:
feat(scope): 요약,fix(api): 타임아웃 처리,docs: README 갱신 - 한 커밋에는 한 가지 의도를 담으면 리뷰·되돌리기·cherry-pick이 쉬워집니다.
- 이슈 트래커와 연동할 때 본문에 **
#123**을 넣어 링크하는 관습도 흔합니다.
브랜치 보호 규칙
GitHub Settings → Branches → Branch protection rule에서 예를 들어 다음을 설정할 수 있습니다.
main에 직접 push 금지, Pull Request 필수- 승인 최소 인원, CODEOWNERS 리뷰 필수
- 필수 상태 검사(CI 통과), 대화 해결 후 merge 등
- force push 금지, 삭제 금지로 운영 브랜치를 보호
팀 규모와 배포 주기에 맞게 단계적으로 도입하는 경우가 많습니다.
코드 리뷰 체크리스트
작성자(PR 올리는 사람)
- 변경 범위와 목적이 PR 설명에 드러나는가?
- 스스로 diff를 한 번 읽어 보았는가? (오타·디버그 출력 제거)
- 테스트·재현 방법을 적었는가?
리뷰어
- 요구사항·버그 재현을 만족하는가?
- 에러 처리·보안(입력 검증, 비밀 노출)이 적절한가?
- 읽기 쉬운 이름·적절한 모듈 경계인가?
- 팀 컨벤션·성능·접근성 등 프로젝트 우선순위에 맞는가?
체크리스트는 팀 문화에 맞게 짧게 유지하는 것이 실제로 지켜지기 쉽습니다.
11. 자주 묻는 질문 (FAQ)
Q. git push가 “rejected” 될 때 어떻게 하나요?
A. 원격에 새 커밋이 있을 때 발생합니다. git pull origin main(또는 git pull —rebase origin main)으로 원격 변경을 받아 온 뒤 git push를 다시 하면 됩니다. pull 후 충돌이 나면 브랜치와 병합(#2)의 충돌 해결 절차대로 처리하면 됩니다.
Q. push와 pull의 차이가 뭔가요?
A. push는 “로컬 커밋을 원격에 올리는 것”, pull은 “원격 변경을 가져와 현재 브랜치에 병합하는 것”입니다. 협업 시에는 먼저 pull로 최신화한 뒤 작업하고, 작업이 끝나면 push로 올리는 순서를 지키는 것이 좋습니다.
Q. PR과 merge의 차이는?
A. merge는 Git 명령으로 브랜치를 합치는 것이고, PR은 GitHub/GitLab 같은 서비스에서 “이 브랜치를 저 브랜치에 합쳐 달라”고 요청·리뷰·승인 후 merge하는 과정 전체를 말합니다. 보통 PR을 “만든 뒤” 리뷰를 거쳐 “Merge” 버튼으로 병합합니다.
마무리
- 원격 추가: git remote add origin
<URL>, clone하면 자동 설정됨. - 올리기: git push -u origin main (최초 1회 -u로 추적 설정).
- 가져오기: git fetch는 원격 이력만 갱신, git pull은 가져와 현재 브랜치에 맞춤. 선형 이력이면 git pull —rebase를 팀과 합의해 사용.
- 안전한 덮어쓰기: feature 브랜치에서 히스토리를 고친 뒤에는 **
git push --force-with-lease**를 고려하고, 공유 브랜치에는 force push 금지. - 협업: feature 브랜치 → push → PR → 리뷰·이슈 연동(Closes #n) → Merge; fork 기여 시 upstream으로 원본과 동기화.
- GitHub: PR 템플릿·Actions CI·브랜치 보호 규칙으로 품질 게이트를 걸 수 있음.
한 줄 요약: remote·push·pull·fetch로 원격과 동기화하고, PR·리뷰·브랜치 보호·CI로 협업 품질을 지킬 수 있습니다. 다음으로 되돌리기·rebase(#4)를 읽어보면 좋습니다.
다음 글: Git 실전 가이드 #4: 되돌리기·rebase·정리 — reset, revert, rebase, 정리
이전 글: Git 실전 가이드 #2: 브랜치와 병합
협업 흐름 다이어그램
flowchart LR
subgraph local [로컬]
L[작업 브랜치]
end
subgraph remote [원격 origin]
R[원격 브랜치]
end
L -->|git push| R
R -->|git fetch / git pull| L
R -->|PR 생성·리뷰·Merge| M[기본 브랜치 반영]
설명: 로컬에서 push로 원격에 올리고, fetch/pull로 최신을 받으며, GitHub에서 PR·리뷰를 거쳐 기본 브랜치에 합쳐지는 흐름을 나타냅니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- Git 브랜치와 병합 | “merge conflict 났어요” 충돌 해결 방법 (branch, merge)
- Git 되돌리기 | “실수한 커밋 취소하고 싶어요” reset·revert·rebase 차이
- Git 기초 입문 [#1] — 설치·커밋·브랜치·원격 저장소 한 번에
실전 팁
실무에서 바로 적용할 수 있는 팁입니다.
디버깅 팁
- 문제가 발생하면 먼저 컴파일러 경고를 확인하세요
- 간단한 테스트 케이스로 문제를 재현하세요
성능 팁
- 프로파일링 없이 최적화하지 마세요
- 측정 가능한 지표를 먼저 설정하세요
코드 리뷰 팁
- 코드 리뷰에서 자주 지적받는 부분을 미리 체크하세요
- 팀의 코딩 컨벤션을 따르세요
실전 체크리스트
실무에서 이 개념을 적용할 때 확인해야 할 사항입니다.
코드 작성 전
- 이 기법이 현재 문제를 해결하는 최선의 방법인가?
- 팀원들이 이 코드를 이해하고 유지보수할 수 있는가?
- 성능 요구사항을 만족하는가?
코드 작성 중
- 컴파일러 경고를 모두 해결했는가?
- 엣지 케이스를 고려했는가?
- 에러 처리가 적절한가?
코드 리뷰 시
- 코드의 의도가 명확한가?
- 테스트 케이스가 충분한가?
- 문서화가 되어 있는가?
이 체크리스트를 활용하여 실수를 줄이고 코드 품질을 높이세요.
이 글에서 다루는 키워드 (관련 검색어)
Git, 원격저장소, push, pull, fetch, git pull —rebase, force-with-lease, origin, upstream, fork, GitHub, 협업, Pull Request, PR, Closes, GitHub Actions, 브랜치 보호 등으로 검색하시면 이 글이 도움이 됩니다.
관련 글
- Git 실전 가이드 시리즈 목차 | 기초·브랜치·원격·rebase