LainyZine: 프로그래머 가이드 🐣

GitHub 원격 저장소와 로컬 Git 저장소 연동하는 방법

GitHub는 원격에서 Git 저장소를 호스팅해주시는 서비스입니다. GitHub 웹에서 원격 Git 저장소를 간단히 생성할 수 있습니다.

웹에서도 간단한 작업은 할 수 있습니다만, 본격적으로 프로그래밍 작업을 하려면 로컬 시스템에 저장소를 복제해와야합니다. 혹은 로컬에서 작업하던 Git 저장소가 있는 경우에는 이 내용을 GitHub에서 만든 저장소에 Push 해야합니다. 이 글에서는 시나리오 별로 새로 생성한 GitHub저장소를 사용하는 방법에 대해서 알아봅니다.

GitHub에서 저장소 만들기

GitHub에서 새로운 저장소를 만드는 방법에 대해서는 위에서 링크한 글에서 더 자세하게 소개합니다. 여기서는 아래 페이지로 이동해서 비어있는 상태로 저장소를 하나 만들어보겠습니다.

비어있는 저장소를 하나 만듭니다

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

빈 저장소 안내 페이지

저장소가 비어있으면 GitHub에서는 몇 가지 시나리오 가정해서 저장소 셋업하는 방법을 안내합니다. 각 방법들에 대해서 한 번 살펴보겠습니다.

그 전에 잠시 안내 페이지 상단의 Git 저장소 주소를 알아두어야합니다.

Git 저장소의 HTTPS/SSH 프로토콜 주소

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 브랜치가 동기화되었습니다.

로컬 Git 저장의 내용을 origin(원격 저장소)에 푸시했습니다

시나리오 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
LainyZine은 쿠팡 파트너스 활동에 따른 수수료를 제공받습니다.