[Git] 이클립스에서 프로젝트와 Git 연동하기
이클립스에서 생성한 프로젝트와 Git을 연동하는 과정에 대한 포스팅입니다.
Git에 대해 자세히 알고 싶다면?
Git에 대해 더 자세히 알고 싶다면 깃 공식 문서인 git-scm를 참조하는 걸 추천드립니다. 한국어를 포함한 여러 언어를 지원하고 있습니다. 챕터별로 잘 나누어져 있고 개념들을 풀어서 자세히 설명하고 있기 때문에 git에 대해 지식이 없다면 도움이 될 것 같습니다. 다만 공식 홈페이지에서 진행하는 설치 및 연동 과정(CLI)은 리눅스를 기반으로 하고 있기 때문에 윈도우 연동 과정(GUI)과는 거리가 있습니다.
생성, 연동 순서
"프로젝트 생성 및 원격 레포지토리 연동"을 하는 방법은 한 가지로 정해져 있자 않고 여러 방법이 있다. 그 중 이 포스팅에서 소개하는 방법은 "먼저 깃허브에서 원격 레포지토리를 생성하고 내 PC로 복제(Clone)한 뒤 복제한 위치에 프로젝트를 생성"하는 방법이다. 간략하게 순서를 요약하면 다음과 같다.
- 원격 레포지토리 생성
- 원격 레포지토리를 내 PC로 복사(Clone)
- 복사해온 레포지토리 위치에 프로젝트 생성
- Commit/Push
Remote Repository 만들기
Github에 접속해 로그인을 수행한 뒤 메인 화면에서 Create repository 혹은 Start a project를 클릭해 레포지토리 생성 화면으로 이동한다.
Repository name에 레포지토리 이름을 적고 Description에는 생성하려는 레포지토리에 대한 가벼운 설명이나 소개를 적는다. 다음으로 레포지토리에 대한 공개 여부를 설정할 수 있는데 다른 사람이 내 프로필 혹은 레포지토리에 대한 주소를 통한 접근을 허용하려면 public을, 개인 프로젝트로 사용하거나 공개하지 않는다면 private를 체크한다.
페이지 하단에서는 레포지토리를 생성하면서 추가할 수 있는 파일 옵션을 선택할 수 있다. 각 항목을 선택하면 그에 맞는 파일이 생성된다.
- Add a README file : 레포지토리 소개를 작성할 수 있는 파일을 생성한다.
> 포트폴리오나 외부에 공개할 프로젝트라면 추가하는 것이 좋고, 외부로 공개될 일이 없는 개인 프로젝트라면 생략해도 좋다. - Add .gitignore : 로컬 레포지토리에서 Push를 수행할 때 제외할 파일 패턴 목록을 가지는 파일을 생성한다.
> 공개/비공개를 막론하고 반드시 생성해주는 것이 관리 측면에서도 좋고, 파일 성격에 따라 보안 이점이 있을 수 있다. - Choose a license : 생성할 레포지토리에 대한 라이센스를 설정한다.
> 외부에 공개하지 않을 프로젝트라면 생성해도 의미를 가지지 않지만 외부에 공개하는 경우 필수적으로 생성하는 것이 좋다.
예제에서는 readme, gitignore 두 가지를 선택해 추가해주었다.
Remote Repository 복사
이클립스에서 Git 관련 기능을 다루기 위해서 이클립스 상단 리본 메뉴에서 [Window → Show View → Other...]로 들어간다. 필터창에 git을 입력해 나오는 목록(사진 좌측)에서 "Git Repositories"와 "Git Staging"을 선택하고 Open을 누르면 이클립스 하단(혹은 좌측)에 위와 같은 탭(사진 우측)이 추가되는 것을 볼 수 있다.
가장 먼저 앞서 깃허브에서 생성한 원격 레포지토리를 그대로 내려받아 로컬 레포지토리로 사용할 것이다. [Git Repositories] 탭에서 "Clone a Git Repository"를 선택한다.
# 왜 원격 레포지토리를 복사해오는가?
레포지토리간 Push/Pull이 정상적으로 수행되려면 두 가지 중 하나의 조건이 갖춰져야 한다.
- Push
> 대상 원격 레포지토리가 비어 있어야 한다. 다시 말해 커밋 기록이 없어야 한다.
> 대상 원격 레포지토리와 로컬 레포지토리가 공통 조상(같은 히스토리)을 가져야 한다. - Pull
> 대상 로컬 레포지토리가 비어 있어야 한다. 다시 말해 커밋 기록이 없어야 한다.
> 대상 로컬 레포지토리와 원격 레포지토리가 공통 조상(같은 히스토리)을 가져야 한다.
필자는 앞서 원격 레포지토리를 생성할 때 readme, gitignore 두 항목을 체크했다. 이에 따라 원격 레포지토리에는 각 항목에 맞는 파일 두 개가 생성되었는데, 원격 레포지토리 입장에서 이는 최초의 커밋이 되었다.
이러한 상황에서 프로젝트를 생성한 뒤 프로젝트를 Commit, Push 한다고 가정하면 Push 단계는 반드시 실패한다. Push란 로컬 레포지토리에 작성한 히스토리를 원격 레포지토리에 이어 작성하는 행위와 같다. 하지만 현재 로컬 레포지토리는 프로젝트를 만든 후 초기 상태를 commit 한 히스토리를, 원격 레포지토리는 readme, gitignore를 생성한 commit 히스토리를 가지고 있는 상태이기에 히스토리를 이어쓸 수 없다. 다시 말해 두 레포지토리간 공통 조상이 다르기 때문에 히스토리 불일치가 발생, Push를 수행할 수 없게 되는 것이다.
이렇듯 히스토리 불일치를 사유로 한쪽의 히스토리를 완전히 비워둔 상태로 연동을 진행하거나 한 쪽의 레포지토리를 다른 한 쪽에 복사해온 뒤 이어서 Commit, Push를 진행하는 것이다.
이 포스팅에서는 후자인 한 쪽의 레포지토리를 복사해오는 방식을 다루고 있다.
여기서 원격 레포지토리를 복사해 올 주소가 필요한데, 앞서 생성한 원격 레포지토리에 접속하여 우측에 [Code]를 누르면 주소를 복사할 수 있다.
URI 항목에 방금 복사한 주소를 붙여넣기 하면 오른쪽처럼 Host, Repository path, protocol이 자동으로 셋팅된다. 이제 레포지토리에 접근하기 위해 인증에 필요한 User, Password를 입력해야 하는데 User는 Github를 가입할 때 만들었던 아이디를 비밀번호는 계정 비밀번호가 아닌 개인 액세스 토큰을 입력한다. 2021-08 까지는 계정 비밀번호로 인증했지만 이후부터는 보안상의 문제로 개인 액세스 토큰 인증으로 변경되었다.
개인 액세스 토큰 발급은 여기를 참조.
브랜치를 선택하는 화면이다. 별도로 생성한 브랜치가 없기 때문에 그대로 Next를 눌러 넘어가면 기본 브랜치가 선택된다.
원격 레포지토리를 내려받아 저장할 위치를 지정한다. 원격 레포지토리를 내려받으면 이 레포지토리(디렉터리)는 이제부터 로컬 레포지토리로서 사용될 것이다. 저장소를 내려받을 위치는 "평소 프로젝트를 생성/관리하는 경로"로 지정한다. 이유는 다음과 같다.
원격 레포지토리 클론이 성공한 경우 "C:\Workspace\Java\GitTest"의 내부는 위와 같다. 원격 레포지토리에서 생성한 gitignore, readme 파일을 내려받은 것을 확인할 수 있고 숨김 상태로 생성된 ".git" 디렉터리를 확인할 수 있다. 이 디렉터리는 로컬 레포지토리로 사용되는데, 이 디렉터리는 통상적으로 프로젝트 루트에서 관된다. 따라서 이 위치에 그대로 프로젝트를 만들 것이다.
작업을 완료한 후 이클립스로 돌아와 Git Repositories 탭을 보면 로컬 저장소가 생성된 것을 볼 수 있다.
.gitignore 파일 생성하기
앞서 원격 레포지토리에서 gitignore 파일을 생성했고 그 레포지토리를 복제(Clone)하였기에 gitignore 파일을 PC에서 직접 편집할 수 있다. 이클립스에서 직접 편집할 수 있다면 편하겠지만 이클립스는 기본적으로 .으로 시작하는 파일은 패키지 익스플로러에서 숨겨지도록 설정되어 있다. 물론 설정을 변경하면 .으로 시작하는 파일이라도 익스플로러에서 확인할 수 있지만 버전마다 설정하는 방법이 조금씩 다르다는 것을 확인하였으므로 여기서는 다루지 않도록 않으려 한다.
gitignore에 작성할 큰 틀은 toptal 에서 자동 생성할 수 있다. 사이트에 접속해서 현재 환경에 맞는 키워드를 작성하고 생성을 누르면 그에 맞는 패턴들을 자동으로 작성해준다. 큰 틀은 이 사이트를 통해 작성하고 프로젝트 환경에 따라 추가적으로 필요한 것이 있다면 직접 추가하도록 한다. 작성된 텍스트를 복사한 뒤 앞서 생성한 ".gitignore"에 붙여넣기한다. 이 때 편집기는 메모장, 워드 패드, VS Code 어떤 것을 사용해도 좋다.
원격 저장소에 프로젝트를 push할 때 프로젝트와 관련이 없는 파일이나 백업 파일, 컴파일 된 파일 등은 올리지 않는다. 프로젝트를 올릴 때 파일을 일일이 선택하기보다 프로젝트 단위로 올리게 되는 일이 잦은데 이 과정에서 앞에 말한 파일들은 추적 대상에서 벗어나게 할 필요가 있다. 이 때 사용하는 것이 .gitignore 파일이다. 프로젝트에서 깃에 올릴 파일을 찾는 과정을 추적(tracking)이라고 하는데, .gitignore에 등록된 파일들은 untracked files가 되어 추적 대상에서 제외된다.
프로젝트 생성
[File > New > Java Project]를 선택한다. 프로젝트 이름은 앞서 생성한 디렉터리 이름과 같은 이름을 지정하고 위치 역시 같은 위치를 지정해준다. "Use default location"을 해제하면 위치를 직접 지정할 수 있다.
참고로 예제로 사용함에 있어 자바 프로젝트 구조가 가장 심플했기에 자바를 선택하였지만 다른 프로젝트를 생성해도 상관없다.
프로젝트를 생성하고 나면 기본 구조에 앞서 생성한 readme 파일이 포함되어 있는 것을 확인할 수 있다. 앞서 말했듯 .으로 시작하는 파일은 탐색기에 표시되지 않으므로 .gitignore는 탐색기에 포함되지 않는다.
추가적으로 프로젝트를 우클릭하여 [Team] 메뉴를 펼쳐보면 기존에 보이지 않던 Commit, Pull 등의 메뉴가 추가된 것을 확인할 수 있다. 이로 인해 방금 생성한 프로젝트가 로컬 레포지토리를 정상적으로 인식되고 있다는 것을 알 수 있다.
Commit/Push를 하려면 파일 생성/수정이 필요하기에 클래스를 하나 추가했다.
Commit, push하기
Git Staging 탭의 Unstaged Changes를 보면 처음 생성된 파일 혹은 수정이 발생한 파일이 표시되는데 처음이라면 모든 파일이 대상이 된다.
Unstaged Changes의 요소(Commit 대상)들은 우측의 +, ++ 버튼으로 목록의 Staged Changes로 이동할 수 있다. 즉 커밋할 대상을 선택하는 것이다. 처음 커밋이니 ++ 버튼으로 모든 파일을 추가한 뒤 커밋 메시지(커밋에 대한 일종의 주석)를 입력해준다. 마지막으로 하단의 Commit and Push를 눌러 먼저 커밋을 진행한다. 다음 화면에서 Push를 할 것인지 묻는 화면이 나오는데 마찬가지로 Push를 클릭해 진행한다.
깃허브에 접속해 결과를 확인한다.