1. 원격 저장소 생성하기
  2. 원격 저장소 관리하기
  3. 원격 저장소와 작업하기
  4. 협업할 때 작업 순서

들어가기 전에

원격 저장소와 commit을 주고받으려면 일단 원격 저장소가 존재해야 한다. 먼저, 원격 저장소를 생성해 보자. 원격 저장소는 당장 내 컴퓨터 경로 내에 생성할 수도 있고 Github와 같은 Git 호스팅 서버를 이용할 수도 있다.


원격 저장소 생성하기

내 컴퓨터에 원격 저장소를 생성해 보자
git remote add <원격 저장소 이름> <디렉토리 경로>
  • 내 컴퓨터 내에 디렉토리 경로에 원격 저장소를 생성하는 명령어이다. 내 컴퓨터를 NFS(Network File System) 등의 서버로 이용할 때 사용할 수 있다. 그러나, 모든 데이터가 내 컴퓨터에 집중되어 있기 때문에 그에 따르는 위험 또한 존재하므로 주의하여 사용하여야 한다. Git command to create remote repository to directory path


Github 회원가입
  1. 이제 서버에 내 원격 저장소를 생성하기 위해 대표적인 Git 호스팅 플랫폼인 Github에 회원가입을 해보자. 이메일을 입력하고 Sign up 버튼을 클릭하면 바로 다음 페이지로 진행된다. Home page of Github official website

  2. 사용할 비밀번호와 닉네임을 입력하고 Continue 버튼을 클릭한다. Sign up page to fill essential informations of Github official website

  3. 확인 버튼을 클릭하면 나오는 간단한 퀴즈를 풀어서 매크로가 아님을 증명한다. Checking if it is a person while signing up

  4. 입력한 이메일을 확인하여 도착해있는 이메일 코드를 입력하면 회원가입이 완료된다. Page to fill email code in order to qualify signing up


Personal access tokens

Github의 API를 사용하여 원격 저장소에 명령어를 사용하여 작업을 수행하려면 이 Personal access token이 필요하다. 터미널 환경에서 인증 화면이 표시되었을 때 아이디와 비밀번호가 아닌 이 token을 입력해야 권한이 생긴다. 그럼, 이제 Personal access token을 만들어보자.

  1. 먼저 처음 Github에 로그인했을 때 나타나는 홈 화면 우측 상단의 프로필사진을 클릭한다. Home page when login status to Github

  2. 팝업되는 메뉴에서 Settings 메뉴를 클릭한다. Popup menu when profile picture clicked in Github

  3. Settings 페이지에서 좌측 가장 하단의 Developer settings 버튼을 클릭한다. Menu in settings page in Github

  4. 사진의 순서대로 버튼을 클릭하여 새로운 token 생성을 진행한다. Developer settings page in Github

  5. 팝업되는 메뉴에서 하단의 classic token을 선택한다. Popup menu when generate new token clicked

    • 생성하고자 하는 token의 이름을 목적에 따라 입력한다.
    • token의 유효기간을 설정한다. (보안을 위해서는 주기적으로 바꿔주는 게 좋을 수 있으나… 필자는 무기한으로 사용하고 있다.)
    • 다음으로 아래에 옵션이 많지만, 초심자의 경우엔 일단 repository에만 접근할 수 있어도 된다. (추후 token 적용 범위 수정도 가능하다.) Page to fill information about new personal access token
  6. token 생성 버튼을 클릭한다. Generate token button

  7. token 생성이 완료되었다. token의 코드는 지금 단 한 번만 보여주므로 반드시 안전한 곳에 기록해 둬야 한다. (터미널 환경에서 인증할 때 사용될 수 있다.) Page when completed generating new token


Github 서버에 원격 저장소를 생성해 보자
  1. 자 이제 회원가입도 완료되었고 원격 저장소를 생성해 보자. 먼저 처음 Github에 로그인했을 때 나타나는 홈 화면 우측 상단의 프로필사진을 클릭한다. Home page when login status to Github

  2. 팝업되는 메뉴에서 Your repositories 메뉴를 클릭한다. Popup menu when profile picture clicked in Github

  3. 우측 상단의 새 원격 저장소 생성 버튼을 클릭한다. Personal repositories page in Github

    • 원하는 원격 저장소의 이름을 입력한다.
    • Private 저장소는 유료 결제를 해야만 선택할 수 있다. 선택되어 있는 Public을 그대로 두면 된다.
    • README file이란 이 저장소의 프로젝트를 소개할 수 있는 markdown 문서이다. 필요하다면 생성한다.
    • 이전 포스트에서 생성해 보았던 .gitignore 파일을 여기서 생성할 수 있다. 선택하는 언어에 따라 default로 설정되어 있는 값들이 존재해서 편리하다. 무엇을 추적에서 제외해야할지 애매하다면 여기서 파일을 생성하자.
    • 프로젝트에 적용될 라이센스 종류에 따라 파일을 추가할 수 있다. Page to fill information about new remote repository
  4. 새 원격 저장소 생성이 완료되었다. New remote repository page

원격 저장소 관리하기

원격 저장소 목록
git remote
  • 원격 저장소의 이름을 목록으로 출력한다. Git command to display list of name for remote repositorie


git remote -v
git remote --verbose
  • 원격 저장소의 이름과 URL을 목록으로 출력한다. Git command to display list of name and URL for remote repositorie


로컬 저장소와 원격 저장소 연결
git remote add <원격 저장소 이름> <원격 저장소 URL>
  • Github 서버의 원격 저장소를 연결하는 명령어이다. 서버의 데이터와 로컬의 데이터로 나뉘어져서 관리되므로 내 컴퓨터에 원격 저장소를 생성하는 것보다 상대적으로 안전하며 저장소가 서버에 존재하기 때문에 다른 개발자들과의 소통 또는 협업이 가능하다. Git command to add remote repository from server in Github


원격 저장소 이름 변경
git remote rename <변경 전 원래 이름> <변경할 이름>

Git command to rename remote repository


원격 저장소 자세한 정보 출력
git remote show <원격 저장소 이름>

Git command to display details about the remote repository


원격 저장소와의 연결 삭제
git remote rm <원격 저장소 이름>

Git command to remove remote repository from local


원격 저장소와 추적 브랜치 동기화
git remote prune <원격 저장소 이름>
  • 로컬 저장소와 원격 저장소의 추적 브랜치를 확인하고 원격 저장소에 더 이상 존재하지 않는 추적 브랜치를 로컬 저장소에서 제거한다.

  • 명령어 실행 전 Git all branches list before git command remote prune

  • 명령어 실행 Git command to remove branch that currently doesn't exist in remote repository

  • 명령어 실행 후 Git all branches list after git command remote prune


원격 저장소와 작업하기

Flow chart of data between local repository and remote repository

  • 원격 저장소와 작업 시 데이터의 흐름도를 그려봤다. Local branchtracking branch는 이해를 도우려고 따로 작성했지만, 실제 존재하는 위치는 local repository 안에 저장되어 있어서 점선으로 표시했다.


원격 저장소에 전송하기
git push <원격 저장소 이름> <로컬 브랜치 이름>
  • 로컬 브랜치의 데이터를 원격 저장소로 전송하는 명령어이다.
  • “로컬 브랜치 이름” 대신 “태그 이름”을 사용할 경우 태그 정보를 전송할 수 있다.
  • 이름이 다른 태그
    • “태그 이름:원격 저장소에서 사용할 태그 이름” 형태로 이름을 작성하면 로컬 태그를 다른 이름으로 원격 저장소에 전송할 수 있다.
    • git push <원격 저장소 이름> <태그 이름:원격 저장소에서 사용할 태그 이름>
      
  • 다른 개발자들과 협업 중일 경우 영향을 줄 수 있으므로 신중하게 사용해야 한다.

  • 명령어 실행 전 Remote repository in Github before git command push

  • 명령어 실행 Git command to transfer datas to remote repository from local repository

  • 명령어 실행 후 Remote repository in Github after git command push


git push -d <원격 저장소 이름> <레퍼런스 이름>
git push --delete <원격 저장소 이름> <레퍼런스 이름>
  • 더 이상 필요하지 않은 레퍼런스(브랜치, 태그 등)를 원격 저장소에서 삭제하는 옵션이다.
  • 원격 저장소에서 해당 레퍼런스(브랜치, 태그 등)를 다시 복구할 수 없으므로 신중하게 사용해야 한다.

  • 명령어 실행 전 Remote repository in Github before git command push -d

  • 명령어 실행 Git command to remove unnecessary references in remote repository

  • 명령어 실행 후 Remote repository in Github after git command push -d


git push --tags <원격 저장소 이름>
  • 로컬 저장소에 있는 모든 태그를 원격 저장소로 전송하는 옵션이다. 기본적으로 옵션 없는 “git push” 명령어로는 태그를 원격 저장소로 전송하지 않는다. 그러므로 태그를 전송해야 할 때 이 옵션을 사용할 수 있다.

  • 명령어 실행 전 Remote repository in Github before git command push --tags

  • 명령어 실행 Git command to transfer tags to remote repository from local repository

  • 명령어 실행 후 Remote repository in Github after git command push --tags


git push -f <원격 저장소 이름> <로컬 브랜치 이름>
git push --force <원격 저장소 이름> <로컬 브랜치 이름>
  • 강제로 전송을 실행하는 옵션이다.
  • 이미 push한 적이 있는 commit을 amend 했거나 rebase, cherry-pick 등의 명령어 사용으로 기존 commit의 해시값이 변경되었을 경우 이 옵션을 통해 push 해야하는데 이런 경우엔 매우 주의해야 한다.

  • 명령어 실행 전 Remote repository in Github before git command push -f

  • 명령어 실행 Git command to force to transfer datas to remote repository from local repository

  • 명령어 실행 후 Remote repository in Github after git command push -f


git push -u <원격 저장소 이름> <로컬 브랜치 이름>
git push --set-upstream <원격 저장소 이름> <로컬 브랜치 이름>
  • 로컬 브랜치의 데이터를 원격 저장소로 전송하면서, 해당 로컬 브랜치의 추적 브랜치를 설정하는 옵션이다. “git branch” 명령어와 다르게 해당 원격 브랜치가 존재하지 않더라도 생성하면서 연결한다.
  • 이름이 다른 브랜치
    • 일반적으로 로컬 저장소의 브랜치와 원격 저장소의 브랜치 이름은 동일하게 사용한다.
    • 하지만 동일한 이름을 사용하기 어려운 상황이 존재한다. 원격 저장소에는 타 개발자 또한 접근할 수 있기 때문에 만약 타 개발자가 나와 동일한 브랜치 이름을 사용하고 업로드한 경우 내 브랜치를 전송할 때 충돌이 생긴다.
    • “로컬 브랜치 이름” 대신에 “로컬 브랜치 이름:원격 저장소에서 사용할 로컬 브랜치의 이름” 형태로 이름을 작성하면 서로 다른 이름의 로컬 브랜치와 원격 브랜치를 수동으로 연결할 수 있다. 즉, 원격 저장소에서만 사용될 새로운 이름을 로컬 브랜치에게 부여할 수 있다.
    • git push -u <원격 저장소 이름> <로컬 브랜치 이름:원격 저장소에서 사용할 로컬 브랜치의 이름>
      
  • 명령어 실행 전 Remote repository in Github before git command push -u

  • 명령어 실행 Git command to set tracking branch for the local branch as well as to transfer datas to remote repository from local repository

  • 명령어 실행 후 Remote repository in Github after git command push -u


원격 저장소에서 내려받기
git pull <원격 저장소 이름> <로컬 브랜치 이름>
  • 원격 저장소의 데이터를 로컬 브랜치로 내려받는 명령어이다.
  • fetch 명령어와 merge 명령어의 혼용과 동일한 동작을 한다. merge 동작이 포함되어 있기 때문에 conflict가 발생할 수 있다.
  • commit하지 않은 수정사항이 working directory에 존재할 경우 명령어가 실행되지 않으므로 해당 내용을 commit 하거나 stash로 임시 저장한 후에 pull 명령어를 실행해야 한다.

  • 명령어 실행 전 Log result before git command pull

  • 명령어 실행 Git command to fetch datas and merge with local branch

  • 명령어 실행 후 Log result after git command pull


git pull --allow-unrelated-histories <원격 저장소 이름> <로컬 브랜치 이름>
  • 관계 없는 commit 이력의 병합을 허용하는 옵션이다. 관계없다는 의미는 병합하려는 두 개의 이력이 공통 조상 commit을 갖고 있지 않음을 뜻한다.
  • 보통 처음 로컬 저장소를 “git init” 명령어를 통해 생성하고 Github에 새 원격 저장소를 생성한 후 연결하여 처음 내려받으려 시도할 경우 이 옵션을 사용해야 내려받을 수 있다. 새로 생성된 두 저장소가 공통된 base를 갖고 있을 리 없기 때문이다.

  • 명령어 실행 전 Log result before git command pull --allow-unrelated-histories

  • 명령어 실행 Git command to fetch datas which are unrelated with local history and merge with local branch

  • 명령어 실행 후 Log result after git command pull --allow-unrelated-histories


git pull -f <원격 저장소 이름> <로컬 브랜치 이름>
git pull --force <원격 저장소 이름> <로컬 브랜치 이름>
  • 원격 저장소의 데이터로 로컬 브랜치를 강제로 덮어쓰는 옵션이다. 덮어쓴다고 하지만 원격 저장소에 존재하지 않는 로컬 브랜치의 파일들이 삭제되거나 하진 않는다. 다만, 로컬 브랜치와 원격 저장소 양쪽에 존재하는 파일의 경우 원격 저장소의 최신 commit으로 로컬 브랜치의 파일들이 덮어씌워진다.

  • 명령어 실행 전 Log result before git command pull -f

  • 명령어 실행 Git command to force both actions fetching datas and merging with local branch

  • 명령어 실행 후 Log result after git command pull -f


원격 저장소에서 일단 가져오기
git fetch <원격 저장소 이름> <로컬 브랜치 이름>
  • 원격 저장소의 데이터를 추적 브랜치로 가져오는 명령어이다.
  • “로컬 브랜치 이름”을 입력하지 않을 경우 원격 저장소의 모든 브랜치 정보를 가져올 수 있다. 다수의 개발자와 협업할 경우 먼저 fetch를 한 후 차례차례 브랜치를 병합한 후에 작업을 진행해야 한다.
  • git fetch <원격 저장소 이름>
    
  • 명령어 실행 전 Log result before git command fetch

  • 명령어 실행 Git command to bring datas to tracking branch

  • 명령어 실행 후 Log result after git command fetch


git fetch -p <원격 저장소 이름>
git fetch --prune <원격 저장소 이름>
  • 원격 저장소의 모든 브랜치 정보를 가져오면서 원격 저장소에 더 이상 존재하지 않는 추적 브랜치를 로컬 저장소에서 제거하는 옵션이다.

  • 명령어 실행 전 Git all branches list before git command fetch -p

  • 명령어 실행 Git command to remove tracking branches which doesn't exist for now and bring all branch datas

  • 명령어 실행 후 Git all branches list after git command fetch -p


가져온 데이터 수동으로 병합하기
git merge <원격 저장소 이름/로컬 브랜치 이름>
  • 추적 브랜치의 데이터를 로컬 브랜치와 병합하는 명령어이다.
  • merge 명령어의 여러 가지 자세한 사용법은 추후 포스트로 따로 다룰 예정이다.

  • 명령어 실행 전 Log result before git command merge

  • 명령어 실행 Git command to merge datas between tracking branch and local branch

  • 명령어 실행 후 Log result after git command merge

협업할 때 작업 순서

The sequence to cooperate to work in one branch

  • 실제 협업에서는 각자 브랜치를 생성해서 따로 작업하고 pull request를 통해 병합할 가능성이 높으나 만약 하나의 브랜치에 여러 명이 작업할 경우를 가정해 보자.
  • 기본적으로 원격 저장소에는 다수의 개발자가 동시에 commit을 push 할 수 없다. 그러므로, 여러 명이 협력하여 개발할 때는 순차적으로 push를 진행해야 한다. 또한 원격 저장소에 push 하기 위해서는 로컬 저장소를 최신 상태로 유지해야 한다. 만약 commit이 순차적이지 않을 경우에 Git은 push 명령어 실행을 거부한다. 로컬 저장소가 최신 상태에서만 push를 허용하는 것은 충돌을 최소화하기 위해서이다.
  • 최대한 충돌을 피하는 방법은 로컬과 원격 저장소를 빈번하게 최신으로 유지해 주는 것이다. 포인트는 Working directory에서 작업을 시작하기 전에 무조건 pull 명령어를 실행하고 작업내역을 commit한 이후엔 또 다시 pull 명령어를 실행한 후에 push 명령어를 실행하는 것이다.
  • pull ⇒ write code ⇒ add ⇒ commit ⇒ pull ⇒ push
    

마무리하며…

이번 포스트에서는 “나”만이 존재하는 로컬 환경을 벗어나 다른 개발자들과 협업이 가능한 원격 저장소를 생성하고 원격 저장소와 작업시 필수적인 명령어도 알아보았다. 첫 포스트부터 오늘까지 알아본 명령어들만 사용할 줄 알아도 이제 본인의 개발 이력 정도는 스스로 관리할 수 있을 정도의 수준이 되었다. 하지만 완벽하게 모든 버전관리 issue를 해결하기엔 아직 모자란다. 오늘 내용 중에서도 추적 브랜치, 태그 등 아직 모르는 내용들이 있을 수 있다. 천천히 전부 알아갈 예정이므로 초조할 필요 없다. 다음 포스트에서는 commit 못지않게 중요한 개념인 branch에 대해서 심층 탐구를 해보자.