Git 허브 공부하기
프로젝트 시 어떤 기능을 빼고 더하고 고치고 수정하는 과정은 필수이다.
기능을 되돌리게 될 수도 있고, 서로 다른 기능의 버전을 유지해야 하는 경우도 있다.
Git 이란?
형상관리 도구(Configuration Management Tool) 중 하나이다.
형상관리 도구는 다른말로 버전 관리 시스템이라고 한다.
버전 관리 시스템으로, 프로젝트의 소스 코드의 변경이력을 효과적으로 관리하는 도구이다.
효과적 관리란?
- 여러 명이 동시에 작업하더라도 문제 없도록 한다.
- 소프트웨어의 여러 버전을 동시에 관리 할 수 있다.
- 프로젝트 진행의 모든 로그를 볼 수 있으며 해당 시점으로 되돌리는 것도 가능하다.
코드 관리 측면
변경된 이력확인 가능
이전 이력으로 되돌리기
다른 기능의 버전 코드 유지 가능
현재 최종이 어느 시점인지 표현할 수 있다.
협업의 측면
각 기능별로 분업 후 하나의 코드로 합칠 수 있음
같은 부분을 수정해 문제가 생기는 경우 안내 가능
협업으로 인한 실수 예방
팀원 간의 커뮤니케이션 지원
사용자 설정 및 세팅
1. git 셋업하기
git 명령어 | git config
git config는 Git에서 사용하는 설정 값을 구성하는 명령어이다.
Git에 관한 설정을 추가/변경/삭제하는 명령어
로컬에서 사용할 Git 사용자 이메일과 이름을 설정
설정 파일 : System 설정 파일 / Global 설정 파일 / 로컬 설정 파일
Git에서 설정 가능한 값은 전역 설정과 프로젝트별 설정 두가지로 나뉜다.
- System 설정 : 모든 시스템 사용자에게 적용 (git-config --system)
- 전역 설정 : 모든 Git 저장소에서 사용하는 설정
전역 설정은 --global 옵션과 함께 사용하며, 현재 사용자에게 적용되는 설정이다.
예를 들어, 사용자의 이름과 이메일 주소를 설정할 때 다음과 같은 명령어를 사용할 수 있다.
$ git config --global user.name "Your Name"
$ git config --global user.email "your_eamil@example.com"
- 로컬 설정 / 프로젝트별 설정 : 특정 Git 저장소에서만 사용하는 설정
하나의 Repository에만 적용 (git config --local)
프로젝트별 설정은 프로젝트 디렉토리에서 git config 명령어를 실행하여 설정한다.
이 설정은 해당 프로젝트에서만 적용된다.
예를 들어, 프로젝트의 기본 에디터를 vim으로 설정할 때 다음과 같은 명령어를 사용할 수 있다.
$git config core.editor vim
또한 사용자에 대한 설정값도 바꿔 줄 수 있다.
$ git config user.name
Your Name
$ git config user.email
your_email@example.com
→ 설정 확인 방법 : 설정 한 부분에 대해 목록으로 표시가 된다.
$ git config --list
2. Github 계정에 ssh key 등록
① ssh key 만들기
https://bit.ly/368zxvR
② Github 접속 후 오른쪽 상단 프로필 클릭 후 SSH and Gpg Keys
③ New SSH Key를 클릭하고 Title과 복사한 Key 입력 후 Add SSH Key 클릭
깃 초기화 및 삭제
Git 초기화 명령어 | git init
초기화 할 대상 폴더에서 명령어(git init) 입력
Git 초기화 시 폴더 안에 숨심 폴더로 .git 폴더 생성(Local Config 등으로 구성, Local 저장소로 만듦)
Git 삭제 | .git 폴더 삭제
단순히 .git 폴더를 삭제하면 삭제가 된다.
(mac의 경우 폴더 삭제하는 명령어를 입력 : rm -rf .git)
3. gitignore 란?
사용자가 git에 등록(커밋)되지 않길 원하는 파일(등록하면 git에게 영향을 받지 않음) 또는 폴더들의 목록을 저장하는 곳으로 .gitignore에 등록된 파일(폴더)들은 커밋 시 자동으로 제외된다
작성법
- #은 주석의 역할
- 폴더 : /폴더명 (예: /docs)
- 파일 : 파일명.확장자 (예: text.txt)
- 폴더 안 파일 /폴더명/파일명.확장자 (예: /docs/test.txt)
- 폴더 안 특정 확장자 파일 전부 (예: /docs/*.text)
- 폴더 하위 모든 특정 확장자 파일 전부 (예 : /docs/**/*.txt)
- 자동 완성 시켜주는 곳 : https://gitignore.io
gitignore.io
Create useful .gitignore files for your project
www.toptal.com
git 기본 동작 원리 : 데이터가 오가는 흐름 순서
Working Directory |
Staging Area |
Local Repository |
Remote Repository |
|||
작업 파일 | 변경 이력 있는 파일 |
컴퓨터 저장소 |
온라인 저장소 |
|||
― git add → Working Directory에서 Staging Area로 등록 |
― git commit → Staging Area에 등록된 파일을 Local Storage로 등록 |
― git push → Local Storage에서 변경된 파일들을 Remote Repository로 등록 |
||||
← git merge ― Local Repository의 변경사항을 Working Directory로 전달 |
← git fetch ― Remote Repository의 변경된 파일들을 Local Repository로 전달 |
① Working Directory
작업하는 파일이 있는 디렉토리
② Staging Area
깃에 등록하기 전에 어떤 것들을 등록할지 Git에 등록할 (커밋) 파일들이 올라가는 영역
- Commit Massage : commit시 함께 작성해 저장하는 메세지(메모), 어떤 시점에 어떤 작업을 한 것인지 파악하기 위해 작성한다
③ Local Repository : git 초기화, git init
로컬 Git 프로젝트의 메타데이터와 데이터 정보가 저장되는 영역으로 gitinit을 할 때, .git이 있는 곳이다 내 PC에 파일이 저장되는 개인 전용 저장 공간
- 저장소(Repository)
파일이나 폴더를 저장하는 곳으로 Git 저장소는 파일 변경 이력 별로 구분되어 저장된다.
snapshot : 파일이나 폴더를 사진을 찍듯 순간의 상태를 저장한다.
- 생성
1. 원하는 폴더 생성
2. 해당 폴더에서 git init 명령어 입력
3. .git 폴더 생성 확인
원격저장소(Remote Repository)에서 복사해 Local Repository를 생성할수도 있다.
④ Remote Repository
Github 등의 서비스를 통한 온라인 상의 저장소, 원격 저장소라고도 불림,
파일이 전용 서버(Github)에서 관리되며 여러 사람이 함께 공유한다.
- origin : 원격(Github 등의 온라인 저장소)에 있는 코드
- 생성 : Github를 통해 생성한다.
git 사용하기
1. Clone
로컬에서 작업하기 위해 Remote Repository(원격 저장소)를 복제해 내 PC에 Local Repository(PC)로 저장하는 것
- 소스트리를 이용해 clone
ⓐ Github 원격 저장소에서 SSH 주소를 복사한다.
(* https의 경우 보안에 취약한 편 ssh를 권장한다.)
2. 소스트리를 이용해 clone
URL에서 복제 선택
3. 복사한 SSH 주소 입력, 복사할 폴더 설정, 이름 설정
2. Add
변경된 파일 중 Repository에 올릴 파일들을 등록한다.
Local Repository(로컬 저장소) 나의 작업 폴더(Working Directory) - 파일 등록 영역(Staging Area) |
push | Github Remote Repository (원격 저장소) |
내 PC | → | 온라인 |
3. push
처음 push를 하면 없던 origin이 생기게 된다. (origin/main으로 변경됨.)
(*origin : 원격 저장소를 의미)
commit을 하고 push를 하면 원격 저장소에 저장이 되고, 히스토리에서 언제 저장되었는지 등 을 확인할 수 있다.
4. pull
나의 작업 폴더(Working Directory) / 파일 등록 영역(Staging Area) |
Pull = Fetch+Merge |
Local Repository(로컬 저장소) |
Fetch | Github Remote Repository (원격 저장소) |
← |
||||
← | ||||
내 PC | 온라인 |
원격 저장소의 변경사항을 로컬 저장소의 나의 작업 저장소로 가져오는 것이다.
로컬 저장소까지 끌어오는 것이 Fetch이고, 내 작업 폴더에 합치는 것이 Pull이다.
① Fetch와 Merge
- Fetch : 원격 저장소의 소스를 로컬 저장소로 받아와 일치 시킨다.(내 작업 소스에는 반영 X)
- Merge : Fetch해 온 로컬 저장소의 소스를 내 작업 소스에 합친다. (합칠 때 같은 부분의 소스가 다를 경우 충돌 발생.)
이 두개를 합친 것이 pull이다.
(같은데 다른 소스가 있으면 충돌이 발생할 수 있다.)
② Pull을 하는 상황은 언제 발생할까? (동기화)
- 원격 저장소는 여러 프로젝트 개발 인원들이 동시에 사용한다.
- 다른 개발자가 변경상태를 Push해 원격 저장소에 반영한다면 내 입장에서는 원격 저장소에 변경사항이 발생한 것이다.
Branch
독립적으로 어떤 작업을 따로 진행하기 위한 가지(사람 별로 가지를 쳐서 분업을 나타내거나, 기능별로 가지를 치는 것)
- checkout : 사용할 다른 브랜치, 시점을 지정
- head : 내가 지금 작업하고 있는 로컬 브랜치, 체크아웃 한 부분이 head가 옮겨지게 된다.
나무가지를 의미, 기존에 만들어 놓은 버전(Main)에서 복사해 새로운 가지를 만들어 다른 방향으로 작업을 이어 나가는 것
① 브랜치 생성 : 브랜치 이름 작성 후 생성
- git을 사용하여 branch를 생성할 때의 명령어는 다음과 같다
git branch [branch_name]
위의 명령어를 실행하면, 현재 작업중인 branch에서 분기되어 [branch_name]이라는 이름의 새로운 branch가 생성된다.
② 새 브랜치 체크 아웃 : 브랜치를 생성한 뒤 현재 작업 소스를 해당 브랜치의 상태로 변경(Head의 이동)
파일을 변경하고 저장하면 위와 같이 커밋할 거리가 생기기 때문에 커밋하지 않은 변경 사항이라 뜬다.
이 때 커밋을 하지 않고 main에서 브랜치 생성을 해준다. 위와 같이 새 브랜치 체크아웃을 체크해주면
git checkout feature-branch
해당 명령어와 같은 기능이 실행되며, 여기서 커밋을 해주면 이 브랜치에 커밋된다.
③ 브랜치 생성 직후 : 가지는 생겼지만 소스의 상태가 같기 때문에 한줄에 표시된다. 변경사항이 없어 브랜치는 로컬 저장
소에만 반영되어 있는 상태이다.
bug_fix라는 브랜치는 생성이 되었지만, commit과 push를 해주지 않았기 때문에 아직 origin이 뜨지는 않았다.
④ main 브랜치 커밋 & 푸시 : feature 브랜치는 그대로 있고 Main 브랜치만 뻗어 나간다. main 브랜치는 원격 저장소에 까지 반영된다.
* main이 처음 만들어졌을 때 기본 브랜치이다.
git add [file_name]
git commit -m "Commit message"
3번에서 새 브랜치에 커밋 해줄 경우 위와 같은 명령어로 add로 파일 추가하고 커밋을 해주면 된다.
git push -u origin [branch_name]
그리고 새로운 브랜치에 변경된 내용을 원격 저장소로 푸시할 경우 push까지 해주면 된다.
-u 옵션을 사용하면 해당 브랜치를 upstream 브랜치로 설정한다.
소스트리에서 커밋을 해주면 origin/main은 그대로 있고 bug_fix 브랜치만 커밋이 되어 시점에 올라가게 된다.
push할 브랜치를 선택하고 push해주면 origin이 브랜치 앞에 생기게된다. 그럼 원격 저장소에 올라가진다.
여기서 또 다른 시점, 브랜치로 옮기기 원한다면 그곳에 옮겨서 checkout을 해주면 된다. 소스트리에서는 체크아웃 할 지점에서 더블클릭을 해주면 이동된다.
checkout
① 브랜치 전환하기
git checkout [branch_name]
git에서는 checkout 명령어를 사용해서 다른 브랜치로 전환할 수 있다. 위의 명령어로 [branch_name] 브랜치로 전환할 수 있다.
② 커밋으로 돌아가기
git checkout [branch_name]
git에서는 checkout 명령어를 사용하여 이전 커밋 상태로 돌아갈 수 있다. 이전 커밋의 상태는 변경하지 않고 해당 상태에서 작업할 수 있다.
③ 새로운 브랜치 생성하기
git checkout -b [new_branch_name]
git에서는 checkout명령어를 사용해서 새로운 브랜치를 생성할 수 있다.
④ 변경 내용 취소하기
git checkout -- [file_name]
아래의 명령어를 통해 변경 내용을 취소할 수 있다.
main에서 파일 변경하기
main에서 파일 내용을 변경하게되면 커밋해야할 사항이 생기기 때문에 main 기준으로 또 새로운 가지가 생기게 된다.
위의 상태에서 그대로 main에서 커밋하고 바로 push까지 해주면 원격 저장소 main 부분에서 파일이 올라가게 되며 동기화가 된다.
Merge
merge란, 각각의 브랜치에서 작업이 완료된 후 통합 브랜치(Main)로 모아 합치는 작업
- 기준이 되는 브랜치는 팀원들끼리 서로 합의하고 가야한다.
- Merge 후 결과 Branch로 체크아웃 후 Merge 대상 브랜치에서 Merge
- 꼭 최근 시점에 Merge를 할 필요는 없으며, Merge할 커밋 시점을 선택해 Merge하는 것도 가능하다.
git merge [branch_name]
위의 git 명령어로 [branch_name] 브랜치를 현재 작업 중인 브랜치에 병합한다.
① Fast-forward 병합
두 개의 브랜치가 분기된 후, 그 중 하나의 브랜치에서 커밋을 추가한 후, 다른 브랜치에서 merge 명령어를 실행하면 git은 추가된 커밋을 가져와서 다른 브랜치에 병합한다. 이것을 Fast-forward병합이라고 한다.
#main 브랜치에서 feature 브랜치를 병합하는 예시
git checkout main
git merge feature
② 3-way 병합
두개의 브랜치가 분기된 후, 각 브랜치에서 커밋을 추가한 경우, 두 브랜치를 병합하면 Git은 3-way 병합을 수행한다. 이는 Git이 두 브랜치에서 동시에 변경된 파일을 자동으로 병합하고 충돌을 처리할 수 있도록 한다.
# main 브랜치에서 feature 브랜치를 3-way 병합하는 예시
git checkout main
git merge --no-ff feature
또한 merge 명령어에는 다양한 옵션을 사용하여 브랜치를 병합하는 방법을 세부적으로 제어할 수 있다. 예를 들어 '--no'ff'옵션을 사용하면 Fast-forward 병합을 하지 않고 3-way 병합을 항상 수행할 수 있다.
'merge' 명령어는 Git에서 가장 중요하고 유용한 명령어 중 하나이다. 브랜치를 통합하고 변경 내용을 병합할 때 자주 사용된다.
merge를 한 이후 커밋과 푸쉬까지 진행하면 origin까지 붙어서 로컬 저장소에도 반영된다.
Conflict 해결 (충돌)
Branch를 Merge할 때 발생할 수 있다.
같은 파일 같은 부분을 수정한 브랜치들을 Merge할 때 발생한다.
이 경우에 main 브랜치와 새 브랜치 중 선택해서 하나로 수정해줘야한다.
수정한 이후에는 다시 수정된 파일이 커밋을 하라고 올라가게 된다. 그러면 커밋하고 푸쉬까지 해주면 된다.
다른 작업자가 작업한 브랜치를 머지할 땐 해당 작업자와 충분한 논의가 필요하다.
위의 코드에서는 HEAD(현 시점은 main에 있음)과 new_feature 두 브랜치가 충돌나는 것을 볼 수 있다.
충돌 해결을 위해서 이렇게 원하는 부분은 남겨놓고 이전의 코드는 지워주고 해결 처리를 해준다.
git에서 충돌을 해결하는 명령어 중 일반 적인 것은 git merge 명령어와 git rebase 명령어이다.
git merge 명령어를 사용하여 충돌을 해결하려면 충돌이 발생한 파일을 수정한 후 git add 명령어를 사용하여 파일을 스테이징하고, git commit 명령어를 사용하여 커밋하면 된다.
git rebase 명령어를 사용하여 충돌을 해결하려면 충돌이 발생한 파일을 수정한 후 git add 명령어를 사용하여 파일을 스테이징하고, git rebase --continue 명령어를 사용하여 리베이스를 계속 진행하면 된다.
Fork 복제
Fork란?
다른 사람의 원격 저장소에서 어떤 부분을 수정하거나 추가 기능을 넣고 싶을 때 해당 원격 저장소를 내 원격저장소에 그대로 복제하는 것, 전문용어로 "포크뜬다"라고 한다.
Local Repository (로컬 저장소) |
Clone 복제 |
다른 사람의 Github Remote Repository (원격 저장소) |
나의 작업 폴더 (Workong Directory) |
Fork 복제 ↓ | |
← | Github Remote Repository (원격 저장소) |
|
내 PC | 온라인 |
포크할 때는 원하는 리포지토리에서 Fork 버튼을 눌러서 가져오면 된다.
Pull Request
다른 사람에게 내 브랜치를 Merge 해 달라고 하는 요청이다.
* 한 원격 저장소에서 내 브랜치를 Merge 하기전 피드백을 요청한다.
* Fork 뜬 저장소에서 원본 저장소에 개발 완료 후 원본 저장소에 Merge를 요청한다.
어떤 부분을 어떻게 수정했는지, 피드백 요청하는 부분은 정확히 어떤 파일의 어느 부분인지 기입한다.
- Pull Request 방법 : 새로운 브랜치에 푸시하게 되면 github 페이지에 compare & pull request 버튼이 생긴다.
또는 github 페이지에서 Pull Request 탭을 클릭해 생성한다.
- 어떤 브랜치에서 어떤 브랜치로 Merge 요청할 것인지 설정
Pull request한 저장소 & 브랜치 / Merge 대상 저장소 & 브랜치를 선택할 수 있다.
- Pull request 메시지 작성부분
- Merge할 두 브랜치의 소스코드 비교 부분