GitHub 원격 저장소와 로컬 Git 저장소 연동하는 방법
GitHub는 원격에서 Git 저장소를 호스팅해주시는 서비스입니다. GitHub 웹에서 원격 Git 저장소를 간단히 생성할 수 있습니다.
- 관련 글: GitHub에서 새로운 저장소 생성하는 방법
웹에서도 간단한 작업은 할 수 있습니다만, 본격적으로 프로그래밍 작업을 하려면 로컬 시스템에 저장소를 복제해와야합니다. 혹은 로컬에서 작업하던 Git 저장소가 있는 경우에는 이 내용을 GitHub에서 만든 저장소에 Push 해야합니다. 이 글에서는 시나리오 별로 새로 생성한 GitHub저장소를 사용하는 방법에 대해서 알아봅니다.
GitHub에서 저장소 만들기
GitHub에서 새로운 저장소를 만드는 방법에 대해서는 위에서 링크한 글에서 더 자세하게 소개합니다. 여기서는 아래 페이지로 이동해서 비어있는 상태로 저장소를 하나 만들어보겠습니다.

아래 README, .gitignore, licence 체크 박스들은 모두 체크 해제하고 Create repository 버튼을 클릭하면 새로운 저장소가 생성됩니다.

저장소가 비어있으면 GitHub에서는 몇 가지 시나리오 가정해서 저장소 셋업하는 방법을 안내합니다. 각 방법들에 대해서 한 번 살펴보겠습니다.
그 전에 잠시 안내 페이지 상단의 Git 저장소 주소를 알아두어야합니다.

Git 저장소 주소는 HTTPS나 SSH 중 프로토콜 중 하나를 선택할 수 있습니다. HTTPS 프로토콜을 사용하는 경우 코드를 Push할 때 GitHub ID와 Password로 로그인을 해야합니다. SSH 프로토콜을 사용하려면 먼저 SSH 공개키와 개인키를 만들어야합니다.
여기서는 SSH 키가 셋업되어있다고 가정하고 SSH 프로토콜을 전제로 설명 하겠습니다.
시나리오 1: 로컬에서 저장소 초기화하고 GitHub 저장소에 푸시하기
먼저 GitHub에서 소개하는 첫 번째 시나리오부터 살펴보겠습니다. 이 시나리오는 Git 저장소를 커맨드라인에서 초기화하고, 앞에서 생성한 GitHub 저장소를 원격 저장소로 등록하는 방법입니다. Git 저장소로 사용할 디렉터리를 만들고 GitHub에서 안내하는대로 명령어를 쭉 실행하면 됩니다.
echo "# literate-engine" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:lainyzine/literate-engine.git
git push -u origin main
한 줄씩 자세히 살펴보겠습니다. 명령어에는 포함되어있지 않지만, 앞에서 설명한대로 먼저 Git 저장소로 사용할 디렉터리를 만들고 해당 디렉터리로 이동해야합니다. 예를 들어 /tmp/literate-engine
을 로컬 Git 저장소로 한다면 다음 명령어를 실행합니다.
$ mkdir /tmp/literate-engine
$ cd /tmp/literate-engine
GitHub 안내 첫 번째 줄의 echo
명령어는 README.md 파일을 만듭니다.
$ echo "# literate-engine" >> README.md
$ ls
README.md
$ cat README.md
# literate-engine
그 다음에 오는 git init
명령어는 로컬에서 Git 저장소를 초기화하는 명령어입니다. Git 저장소를 초기화하고 status
로 상태를 확인해보겠습니다.
$ git init
Initialized empty Git repository in /tmp/literate-engine/.git/
$ git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
nothing added to commit but untracked files present (use "git add" to track)
저장소 상태(git status
)로 알 수 있는 중요한 정보들이 있습니다. 먼저 초기화된 저장소의 브랜치는 master이고, 아직 커밋이 하나도 없는 빈 저장소라는 점입니다. 아직 앞에서 만든 GitHub 저장소와 연결은 되어있지 않지만, 두 저장소의 상태는 같습니다. 그리고 Untracked 파일 목록에서 앞서 추가한 README.md 파일을 확인할 수 있습니다.
다음 두 명령어는 이 README.md 파일을 Git 저장소 master 브랜치에 포함시킵니다. 단, 커밋을 하기 전에는 사용자 이름과 이메일 설정을 권장합니다. 여기에 사용한 이메일은 GitHub에서 사용자 계정을 연결할 때도 사용 됩니다.
# 사용자 이름과 이메일을 설정합니다.
# (이미 설정되어있다면 다음 두 줄은 무시해주세요)
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"
# README.md 파일을 저장소에 커밋합니다.
$ git add README.md
$ git commit -m "first commit"
다음 명령어는 현재 브랜치를 강제로 main
브랜치로 이동 시킵니다. 기존 브랜치는 삭제됩니다.
$ git branch -M main
변경 후 git branch
명령어로 현재 저장소의 브랜치 목록을 확인해보면 main
만 있는 것을 확인할 수 있습니다. git log
로 첫 커밋 내용도 확인해봅니다.
$ git branch
* main
$ git log
commit ce1d2a4caa706292ac56645fd96a8970b0a6ffa2 (HEAD -> main)
Author: LainyZine <lainyzine.com@gmail.com>
Date: Wed May 19 15:29:14 2021 +0900
first commit
자 그러면 로컬 저장소와 원격 저장소의 차이를 생각해보겠습니다. 로컬 저장소에는 main 브랜치에 ce1d2a4 커밋이 있지만, GitHub에서 만든 원격 저장소에는 브랜치도 커밋도 아무것도 없는 상태입니다. 아직 두 저장소는 연결되어있지 않습니다. 여기서 되돌아봐야할 부분이 Git이 분산 버전 관리 도구라는 점입니다. 즉, 로컬의 Git 저장소와 GitHub의 원격 저장소는 둘 다 독립적인 Git 저장소입니다.
이 때 두 저장소를 연결해주는 명령어가 바로 git remote
입니다. 하나의 Git 저장소에는 다수의 원격 Git 저장소를 등록할 수 있습니다. 원격 저장소를 등록하고 원격 저장소의 내용을 로컬에 가져오거나(fetch, pull), 로컬 저장소의 내용을 원격에 전송(Push)할 수 있습니다. git remote
로 원격 저장소를 등록하는 기본 형식은 다음과 같습니다.
git remote add [REMOTE_NAME] [REMOTE_GIT_URL]
여기서 [REMOTE_NAME]
은 원격 저장소의 이름으로 사용할 문자열을 지정합니다. 관습적으로, 코드 공유를 위해 사용하는 원격 저장소의 이름으로 origin
을 사용합니다. [REMOTE_GIT_URL]
에는 원격 Git 저장소 주소를 지정합니다. 바로 여기에 앞에서 생성한 GitHub 저장소의 주소를 넣어줍니다.
바로 다음 명령어입니다.
$ git remote add origin git@github.com:lainyzine/literate-engine.git
git remote -v
명령어로 현재 로컬 Git 저장소에 등록된 원격 저장소 목록을 확인할 수 있습니다.
$ git remote -v
origin git@github.com:lainyzine/literate-engine.git (fetch)
origin git@github.com:lainyzine/literate-engine.git (push)
이 원격 저장소에 앞서 커밋만 내용을 Push하면, 로컬 저장소와 원격 저장소의 상태가 똑같아집니다. 다음 명령어에서 -u
옵션의 인자는 앞에서 지정한 원격 저장소의 이름이고, main은 브랜치 이름입니다.
$ git push -u origin main
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 234 bytes | 234.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github-lainyzine:lainyzine/literate-engine.git
* [new branch] main -> main
Branch 'main' set up to track remote branch 'main' from 'origin'.
Push가 정상적으로 성공했습니다. 메시지를 자세히 살펴보면, main 브랜치가 아직 원격 저장소에 없어서 새로 만들었다는 걸 알 수 있습니다.
다시 GitHub 저장소 페이지로 돌아가서 새로고침을 해보면, main 브랜치의 마지막은 커밋은 ce1d2a4이고, README.md 파일이 추가된 것을 확인할 수 있습니다. 즉, 로컬 Git 저장소의 main 브랜치와 GitHub 저장소의 main 브랜치가 동기화되었습니다.

시나리오 2: 로컬에서 빈 GitHub 저장소 직접 복제하기
GitHub 안내 페이지에는 나오지 않지만, 두 번째 시나리오는 비어있는 GitHub 저장소를 복제하는 방법입니다. GitHub의 빈 저장소를 바로 복제(clone)하면 좀 더 간소하게 초기 셋업을 할 수 있습니다. GitHub 저장소를 새로 만들었고, 이름은 fictional-umbrella
이라고 가정합니다. SSH 프로토콜 주소는 다음과 같습니다.
git@github.com:lainyzine/fictional-umbrella.git
먼저 Git 저장소를 복제할 디렉터리로 이동해서 git clone
으로 빈 저장소를 복제합니다.
$ git clone git@github.com:lainyzine/fictional-umbrella.git
Cloning into 'fictional-umbrella'...
warning: You appear to have cloned an empty repository.
비어있다는 경고가 나오지만, 정상적으로 클론이 됩니다. 저장소 디렉터리로 이동해서 저장소의 상태를 확인해봅니다.
$ cd fictional-umbrella
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
$ git log
fatal: your current branch 'master' does not have any commits yet
$ git remote -v
origin git@github.com:lainyzine/fictional-umbrella.git (fetch)
origin git@github.com:lainyzine/fictional-umbrella.git (push)
master 브랜치이고, 아직 커밋은 없습니다. 원격 저장소 origin이 등록되어있습니다.
첫 번째 시나리오와 다른 점은 커밋이 없는 상태라는 점입니다. 파일 추가하고 커밋하고 push하면 완전히 똑같아집니다. 단, main
브랜치를 사용하는 경우 시나리오1과 마찬가지로 다음 명령어를 실행하고 작업해주세요.
$ git branch -M main
시나리오 3: 이미 로컬의 Git 저장소가 있는 경우
세 번째 시나리오는 GitHub의 안내에서 2번째 경우에 해당합니다. 먼저 기존 로컬 Git 저장소로 이동한 다음 아래 명령어들을 차례대로 실행해주면 됩디다.
git remote add origin git@github.com:lainyzine/fictional-umbrella.git
git branch -M main
git push -u origin main
각 명령어들은 시나리오1에서 자세히 해설했기 때문에 추가적인 해설은 생략하도록 하겠습니다. 단, 명령어의 의미를 이해하셨다면 로컬 Git 저장소의 모든 내용을 푸시하는 건 아니라는 걸 알 수 있습니다. 위 명령어는 단지 main 브랜치(혹은 main으로 이름이 변경된 master 브랜치)만 Push합니다.
로컬 Git 저장소의 모든 브랜치와 태그를 Push하려면 아래와 같이 --all
, --tags
옵션을 사용합니다.
$ git push --all new-origin
$ git push --tags new-origin