깃(git)활용 실습 강좌
학습사이트 및 도서 https://git.jiny.dev
학습 목차
1. 깃설치 및 깃허브 가입
Git에 대한 소개와 설치, 협업을 위한 깃허브 가입방법에 대해서 설명합니다.
2. 저장소 생성 및 깃허브 연동
프로젝트를 위한 저장소를 생성하는 방법을 실습합니다. 또한, 생성한 저장소를 깃허브와 연동하는 연습을 합니다.
3. 0커밋 및 전송하기
예제 코드로 HTML 문서를 작성하고, 이를 커밋하여 저장소에 기록하는 방법을 학습합니다. 또한, 저장소의 내용을 깃허브와 동기화 합니다.
4. 저장소 복제 및 수정작업
협업을 위해서 타인의 저장소를 포크합니다. 수정 커밋을 생성하고, 협업을 시도합니다.
5. 브랜치 생성 및 병합
기능 개선 및 버그를 수정하기 위한 브랜치 생성 방법에 대해서 알아 봅니다. 브랜치를 깃허브에 커밋하고 연동합니다.
6. 리셋 및 리버트
잘못된 커밋을 삭제하거나, 이전 코드 상태로 되돌리는 방법에 대해 알아 봅니다.
깃(git) 설치
git bash
깃허브 가입
깃 저장소 생성
깃은 작성된 소스 코드 파일의 모든 변경 사항을 관리합니다.
그렇다면 깃은 파일의 변경 내역을 어떻게 저장하고 관리할 수 있을까요?
깃은 이러한 변경 사항을 전용 저장소(repository) 리포지터리에 저장합니다.
이 저장소는 일반적으로 사용하는 폴더와 유사하지만 조금 차이가 있습니다.
깃의 동작 방식을 이해하려면 저장소 동작 원리를 확실히 알아야 합니다.
폴더와 깃 저장소
- 파일시스템
- 깃의 파일관리
초기화
- 깃 배시
- 명령어 입력
- 현재 폴더 초기화 하기
- 윈도우에서 숨김화면 관리하기
숨겨진 폴더 = .git 폴더
- .git 폴더
- 깃 골격파일 생성
- 깃 저장소 복제 또는 이동
oss 폴더 만들고
hello world라는 html 파일을 만든다.
$ git init 초기화하고자하는 [폴더명]
현재 폴더를 초기화하려면 . 현재 디렉토리를 나타낸다.
깃 저장소가 초기화되면 초기화 된다고 메세지가 나타남.
git 폴더가 초기화 되면 (master)라는 표시가 나타낸다.
git을 초기화하고 나서 ls -al을 하면 .git이라는 숨겨진 폴더가 나타나게 됨.
.git 저장소를 만약 삭제하게 되면 일반 폴더와 똑같아진다. 따라서 백업이나 다른 사람에게 복사해주기 위해서는 꼭 .git이라는 숨겨진 폴더도 같이 복사가 되어야 한다.
index.html 파일을 수정하게 되었다. 내용이 추가가 되면 추가된 기록을 .git 폴더 안에 객체의 형태로 저장하게 된다.
객체라는 말은 깃에서 특별하게 관리하는 방식이다.
깃 저장소 종류
로컬 저장소와 원격 저장소
각각의 코드들은 A에도 있고 B에도 있고 C에도 있다. 코드는 각자의 모든 시스템에 저장되어 있고 안전하게 보관되어 있다. 실수로 A가 코드를 날려버렸다고 해도 B, C가 가지고 있기 때문에 안전하게 코드를 유지하게 된다. 이런 부분들이 깃의 장점이고 협업을 할 수 있는 부분이라고 할 수 있다. 이처럼 깃은 여러개의 저장소가 존재하게 되는데 이를 통해 저장소가 두 개로 구분된다.
로컷 저장소
원격 저장소
A가 자기 컴퓨터 안에서 자기의 GIT 저장소를 로컬 저장소라고 부른다. 자기 컴퓨터가 아닌 밖에 있는 B, C의 외부 저장소를 원격 저장소라고 부른다. 원격 저장소는 보다 협업을 쉽게 하기 위해서 공통된 서버 개념의 저장소를 하나 이용해서 A도 이 저장소에 접속하고 B도 이 저장소에 접속하고 C도 이 저장소에 접속하는 소스 코드를 주고 받는 것을 통해 협업을 이뤄준다.
이 서버를 직접 구축해서 구현하기에는 힘들기 때문에 github라는 원격 서버 저장소를 무료로 제공하고 있습니다. 우리는 깃허브를 통해 원격 저장소를 만들고 로컬저장소와 원격저장소를 연결하는 실습을 해보겠습니다.
repository에서 new를 눌러 생성
git remote는 원격 저장소를 등록하는 명령어이다.
git remove -v는 등록된 원격저장소를 확인할 수 있다.
커밋 및 전송하기
HTML 문서를 작성하고, 이를 커밋합니다. 커밋 기록을 원격 저장소와 동기화 하는 방법을 학습합니다.
커밋
깃은 개발 중인 소스 코드의 이력을 관리 합니다. 커밋은 깃에서 코드의 변화를 기록하는 것을 의미합니다. 모든 코드의 변경 이력은 커밋이라는 행동을 통하여 기록이 됩니다.
코드의 변화
우선적으로 전형적인 파일의 이력을 관리하는 방법에 대해서 살펴 봅니다. 기존의 파일관리에서 문제점은 무엇이고 어떻게 해결이 가능한지에 대해서 학습해 봅니다.
- 코드의 변화
- 파일 관리 방법
새 파일 생성 및 감지
커밋을 실습하기 전에 새로운 파일을 하나 생성하고, 생성한 파일이 깃과 어떻게 동작하는지에 대해서 알아 봅니다.
- 새 파일 생성
- 깃에서 새 파일 생성 확인
- 소스트리에서 새 파일 감지
git status 깃의 현재 상태를 알려준다.
git은 Untracked files 상태이다. git은 코드의 이력을 사용하기 위해서 상태라는 개념을 쓴다. git이 상태의 개념을 가지고 있는 것은 보다 효율적으로 코드의 이력을 관리하기 위해서이다.
git은 크게 3가지의 상태가 있다.
index.html에 있는 폴더를 working directory(워킹 디렉토리)라고 한다.
.git을 저장소라고 하는데 저장소에 파일이 한 번에 저장할 수가 없다. 파일들이 많아지면 변경된 파일들을 찾고 저장하는데 되게 비효율적이다. 그래서 git은 중간에 하나의 임시 저장소인 stage 영역을 두게 된다.
1. index.html을 stage영역에 등록한다. 관리가 인지된다. 이를 tracted 형태라고 한다.
만일 이 파일이 stage 영역에 한 번도 등록된 적이 없다면 git이 이 파일이 저장소에 저장을 해야하는지 안해야하는지 모르기 때문에 이 모르는 상태를 untracted라고 한다.
index.html을 어떻게 stage 저장소에 넣을 수 있을까?
$ git add 로 stage에 넣는다.
$ git status 깃 상태를 본다. 이제는 git이 new file : index.html을 알 수 있다.
2. stage 영역에 파일이 등록이 되면 최종적으로 .git 저장소로 기록을 하게 되는데 이를 commit이라고 한다.
$ git commit -m "hello world"
-m 옵션은 뒤에 내가 인지할 수 있는 문장을 넣는 것
이런 오류가 발생하는 이유는 git이 분산형 저장소를 운영하고 다양한 사람들과 코드 이력을 관리 할 수 있기 때문입니다. 따라서 git은 코드를 commmit하여 이력을 기록할 때 누가 언제 코드를 어떻게 수정했는지 권고도 같이 저장하게 된다. 이를 위해서 각 저장소마다 사용자 설정을 해줘야한다. 만일 혼자 사용하는 컴퓨터라면 // global 명령어를 설정해 사용할 수도 있다.
그럼 저장소에 사용자 설정을 해보겠다. 사용자 설정은 config 명령어를 사용한다. 사용자 설정은 크게 두가지 이메일과 이름을 수정한다. 이렇게 두개의 환경설정을 해주면 이제 저장소에 파일을 git으로 commit 할 수 있게 된다. 이제 다시 commit을 해보겠다.
잘 commit 되어있는지 확인하려면 log를 쓰면된다.
$ git log
이제 git은 하나의 index.html 파일을 기록관리하고 있습니다. 기록 관리하고 있는 index.html을 수정해 보겠다. vscode로 수정해 보겠다.
안녕하세요를 추가하고 저장한다.
$ git log로 수정된 상태를 확인해 보도록 하겠습니다.
그러면 이전과 다르게 git이 새로운 메시지를 출력합니다. index.html이 modified가 되었다고 한다. git은 추적관리되고 있는 파일들이 수정되면 수정되었는지, 수정이 안되었는지를 감지합니다. 그리고 만일 수정이 되었다면 git add 명령어를 통해 stage 영역에 등록해주라고 합니다.
다시 commit을 해보겠습니다.
$ git commit index.html
이번에는 -m없이 직접 vi 에디터로 commit 메세지를 입력해보겠습니다.
$ git log로 로컬 저장소에 2개의 commit이 존재하는 것을 확인한다.
# git push -u origin master 로 원격저장소에 올린다.
git에 로그인하고 나서 oss를 확인해 보면 올라간 것을 확인할 수 있다.
2개의 커밋이 올라간 것도 확인 가능하다.
저장소 복제 및 수정작업
협업을 위해서 타인의 저장소를 포크합니다. 수정 커밋을 생성하고, 협업을 시도합니다.
git은 init 명령어 외에 다른 방법으로도 저장소를 생성할 수 있다. 그 방법이 생성된 저장소를 복제하여 만드는 것이다.
ㄹ
git은 저장소를 두가지 방법으로 만들 수 있다.
1. init 생성 -> 작업 폴더에서 init 명령어를 통해서 .git 저장소를 새로이 생성하는 것.
2. clone 복제 -> 생성한 .git 저장소를 새롭게 복사하여 저장소를 생성하는 방식이다.
또는 이 저장소가 github와 같이 원격저장소로 전송이 되어서 공유가 되었을 때 이를 다시 clone으로 해서 .git을 복사할 수 있다.
하나의 원격저장소를 이용하여 다수의 개발자 A, B, C가 협업을 하기위한 작업이다.
깃 저장소 복제
초기화 명령(git init 명령어)은 새 저장소를 생성하는 방법 중 하나입니다. 처음 프로젝트를 시작할 때는 직접 로컬 컴퓨터에 명령어를 실행하여 저장소를 생성합니다. 외부에 있는 기존 프로젝트(깃허브, 비트버킷)를 기반으로 저장소를 생성하고 싶다면 어떻게 해야 할까요? 외부 저장소를 복제해서 생성할 수 있습니다. 이처럼 외부 저장소를 이용하여 로컬 저장소를 생성하는 것을 '깃 저장소 복제'라고 합니다.
외부의 깃 저장소 복제
서버 저장소 -> 로컬 저장소
공개 저장소
- 호스팅 저장소
- 공개 / 비공개
- 오픈소스 저장소
다운로드 vs 복제
- 내려받기
- 복제
$ git clone [git 주소] .
.을 넣으면 현재 폴더를 지정하며 아무런 표시가 없으면 github와 동일한 이름으로 폴더가 생성되어 복제가 된다.
vscode로 index.html을 수정하고 $git status를 확인하면 modified인 걸 알 수 있다.
$ git add -> git commit -> git push로 github에 올린다.
github에 push 기록을 확인할 수 있다.
ㄹ
컴퓨터1에 oss 폴더 속 파일을 push하여 github에 올린다. 원격저장소 github에서 clone을 하여 컴퓨터2에 oss1 폴더를 만든다. oss1 폴더에 있는 파일을 수정하고 다시 원격저장소로 push 한다.
oss1 파일에서 다시 oss 파일로 가서 $git log를 하여 commit 로그를 확인하면 2개를 확인할 수 있다. 하지만 원격저장소(github)에는 oss1 복제 저장소에서 작업한 내용까지 합하여 총 3개의 commit이 존재한다. 원격저장소에 존재하는 3개의 commit을 현재의 oss 저장소로 가져와서 병합을 해보도록 하겠습니다.
원격 저장소에서 새로운 commit을 가져오는 명령어 pull
$ git pull
브랜치 생성 및 병합
기능 개선 및 버그를 수정하기 위한 브랜치 생성 방법에 대해서 알아 봅시다. 브랜치를 깃허브에 커밋하고 연동합니다.
브랜치
소스 코드 이력을 관리하는 버전 외에 깃과 같은 VCS 도구를 사용하는 또 다른 이유는 브랜치 작업 때문입니다.
새로운 작업
브랜치(branch)는 나뭇가지, 지사, 분점 등 줄기 하나에서 뻗어 나온 갈림길을 의미합니다. 큰 나무 줄기에서 작은 줄기가 뻗어 나오는 것처럼 저장 공간 하나에서 가상의 또 다른 저장 공간을 만드는 것이라고 생각하면 됩니다.
- 브랜치 작업
- git 브랜치 특징
실습
git은 기본적으로 master 브랜치를 하나 가지고 있다. 그리고 브랜치는 HEAD 포인터를 가지고 있따.
- 저장소 생성 및 초기화
- 기본 브랜치
브랜치 생성
브랜치는 가상의 작업 폴더이다. 처음 git을 초기화할 때 working directory는 master 브랜치를 생성한다. 브랜치를 생성하려면 기준이 되는 브랜치 또는 커밋이 하나 있어야 한다.
ㄹ
oss 폴더는 git에 관리되고 있다. oss 안에 있는 소스코드를 유지하면서 새로운 기능이나 수정을 하고자 할 때 직접적으로 소스코드를 건들게 되면 변경 상태가 된다. 이를 계속 추적관리를 해야하는 개발자의 의무가 생긴다. 만일 변경을 하다가 실수로 어떤 작업들을 되돌리려 할 때 실수를 하나하나 개별적으로 되돌리는 것은 어렵다. 기존에 우리는 oss 폴더를 하나를 복사해서 여기에 수정을 하고 테스트를 한다음에 이를 다시 oss에 반영하는 작업을 많이 하였다. 하지만 이 두 개의 폴더를 유지관리하는 것은 그렇게 쉬운것이 아니다. 그래서 git은 실제적으로 물리적 폴더를 가지지 않고 가상의 저장소로 코드를 가지고 와서 수정 작업을하고 이를 병합해서 자동으로 코드를 결합하고 관리한다.
브랜치 생성 명령어
$ git branch [생성할 이름]
브랜치가 제대로 생성되었는지 확인하는 명령어
$ git branch -v
master 브랜치는 git에서 기본적으로 생성해서 제공하는 브랜치
test는 우리가 방금 생성한 브랜치이다.
*은 현재 어떠한 브랜치가 선택되었는지를 나타내는 것
브랜치를 생성한 후에는 해당 브랜치로 이동해줘야 한다.
$ git checkout [이동할 이름]
$ git checkout test
switched to branch 'test'
ㄹ
oss라는 저장소를 만들고 index.html 소스파일이 있다. 이 파일에는 "hello world"라는 코드로 작성했다. commit 1을 한 번 했다. 그 다음 두번 째 줄에 "안녕하세요"를 작성했다. 그다음 commit 2를 한 번 했다. 우리는 복제된 저장소에서 "깃을 통하여 협업할 수 있습니다"를 작성하고 commit 3을 했다. 현재 3개의 commit이 존재한다. 그리고 이것이 하나의 working directroy인 oss에 작업이 되어있다.
이상태에서 새로운 branch를 만들었다. 현재 마지막 상태 commit 3에서 git branch test를 만들었다. 그러면 git은 commit3를 기반으로 새로운 가상의 working directroy를 가지게 된다. 우리는 여기서 코드를 수정할 수 있게끔 되고 이 수정된 코드는 commit3에 병합이 된다.
branch가 master일 때 $ git log
branch가 test 일 때 $ git log
$ code [실행할 파일명]
vscode를 실행한다.
vscode로 수정한다.
ㄹ
oss 폴더에는 commit1, commit2, commit3이 있다. commit3에서 새로운 브랜치 test를 생성하고 수정 작업을 한 후 commmit4를 만들었다.
commit1, commit2, commit3는 master 브랜치를 의미하고 commit4는 test 브랜치가 된다. 그리고 이렇게 생성된 브랜치는 각각의 독립된 작업 영역을 가지고 있다.
git branch 변경에 따른 코드 변화를 확인할 수 있다.
ㄹ
master가 있고 이를 기반으로 브랜치를 생성해서 test를 만들었습니다. test에는 commit4라는 마크업작업 결과가 있습니다. master에는 원본인 commit3만 남아있는 상태입니다. test commit4에서 작업한 결과물을 commit3에 반영을 하기 위해서는 commit3와 commit4를 병합해줘야 한다. 그리고 이 병합한 결과물을 commit5로 저장한다.
그리고 git은 commit을 병합하는 방법이 다양하게 존재한다. 크게 두 가지 존재
1. fast-forword
2. 3 way
fast-forword 방식을 이용해보자.
기준이 되는 브랜치인 master 브랜치에 test 브랜치의 내용을 결합할 것이다.
commit을 결합하기 위해서는 merge 명령어 사용
$ git merge [브랜치 이름]
Fast-forward 방식으로 사용됨을 알 수 있다.
$git log를 통해 새로운 commit이 만들어졌는데 master와 test가 동시에 존재하는 것을 알 수 있다. 또한 mater의 내용도 test의 수정한 내용으로 변경된 것을 알 수 있다.
리셋 및 리버트
잘못된 커밋을 삭제하거나, 이전 코드 상태로 되돌리는 방법에 대해 알아 봅니다.
ㄹ
git을 이용해 프로그램에 코드의 변경 상태를 관리하는 이유는 코드의 안정적인 상태를 유지하기 위해서이다. 코드를 한 줄, 한 줄 작성할 때마다 우리는 작성한 코드를 테스트하고 또 다시 작성한 코드를 테스트 하면서 프로그램을 완성시켜 나갑니다. 이처럼 프로그램 코드를 하나하나씩 완성시켜나갈 때마다 이 작업 결과물을 commit으로 저장하여 코드의 마지막 안정한 버전들을 기록한다. 만일 우리가 프로그램 코드를 작성하다가 이 코드가 우리가 예상한 것과 달리 오류 동작이 있을 때 이 동작을 없애고(폐쇄하고) 이전의 상태의 코드로 돌아가서 다시 새로운 설계 모델로 프로그램을 작성하고자 하는 경우가 많이 발생한다.
ㄹ
이처럼 프로그램 코드를 작성할 때마다 새로운 commit을 만들고 추가된 기능을 만들고 새로운 commit을 만들고 새로운 프로그램을 만들어간다. 이렇게 프로그램을 작성하는 과정에 어떠한 이 부분이 코드가 잘못된 설계로 오류가 발생했을 때 어떠한 특정에 있는 코드에 있는 상태로 이동하고 특정 commit 상태로 코드의 상태를 이동한 후에 발생한 commit들을 삭제하고 싶은 경우도 발생하게 된다. 이럴 떄 사용하는 명령어가 reset이다.
$ git reset [되돌아갈 지점]
reset을 쓸 때는 어느 지점으로 되돌아갈 것인지 얘기해줘야 한다.
git은 각각의 상태를 commit 형태로 기록한다. 이렇게 commit이 순차적으로 기록될 때 특정한 commit으로 되돌아가기 위해서는 되돌아갈려는 지점에 commit 아이디를 입력해줘야 한다. 또는 마지막 commit은 HEAD라는 이름을 가지고 있다. HEAD라는 이름을 이용해서 ^를 붙여주게 되면 바로 이전 commit을 얘기하며 ^^를 붙이면 바로 전전 commit을 얘기한다.
git reset HEAD^
git reset HEAD^^
이를 이용하여 만일 이전 지점으로 commit을 되돌리고 취소하고 싶다면 git reset HEAD^ 하면 된다. index.html 파일이 Unstage된 상태라고 말해주고 있다. 이전과 달리 $git log에서 add test이 사라지고 그 전 commit이 보인다.
ㄹ
git은 크게 3가지 reset 모드가 존재한다.
soft : commit만 삭제할 뿐 우리가 작업한 내용은 그대로 유지한다.
mixed : commit만 삭제할 뿐 우리가 작업한 내용은 그대로 유지한다.
hard : commit과 작업 내용을 모두 삭제한다. 따라서 매우 신중하게 작업을 해줘야 한다.
reset을 할 때 아무런 메세지를 적어주지 아니면 mixed 모드가 기본값으로 reset이 된다.
위는 mixed 모드로 reset을 한 것이다. 따라서 commit은 삭제 되었지만 작업한 내용은 유지되고 있는 것을 확인할 수 있다.
ㄹ
reset은 우리가 commit을 하나 하나씩 그냥 하면서 개발 할 때 잘못된 commit을 삭제할 수 있는 좋은 도구이다. 하지만 reset을 사용할 때는 이러한 reset 작업들을 local 저장소에서만 해야한다. 만일 이 저장소에 commit이 github와 같이 공개된 저장소로 전송이 되어 있다면 github에는 이 모든 comiit의 기록들이 다 남아져있다. 그리고 이 기록들을 누군가는 또 다른 local 저장소에서 작업을 하고 있겠죠. 그런데 A라는 사람이 commit 2개를 삭제하고 3개만 남겨져 있는 상태에서 github로 전송을 했다면 github는 5개의 commit이 있어야 하는데 3개만 존재하게 된다. 하지만 B라는 사람은 5개의 commit을 가지고 자기만의 6번째 commit을 만들고 있을텐데 github에 자료를 전송할 때 commit이 3개가 있고 B는 commit 5개를 가지고 있기 때문에 불일치하여 오류가 발생한다. 자기 저장소가 github로 공개가 되어 있을 때는 reset을 이용하여 삭제하면 안된다. 대신 이러한 경우에는 5개의 commit이 있을 때 만일 이전상태로 돌아가고 싶다면 이전 상태의 commit을 새로 만들어서 github로 전송을 해줘야한다. 취소를 할 수 있는 commit을 revert라고 한다.
$ git revert [취소할 위치]
취소를 하고자 하는 commit의 위치를 지정해준다. revert를 할 때는 reset과 달리 마지막 commit을 가리키고 있는 HEAD를 취소할 거기 때문에 HEAD만 입력한다.
revert에 대한 commit 메세지를 작성하라는 vi 에디터가 실행된다. 마지막 commit을 가리키는 HEAD가 취소된 새로운 commit이 생성된다.
문제 1. 브랜치에 대한 설명으로 옳은 것은?
1. test 브랜치는 소스코드 원본, master 브랜치는 새롭게 생성한 브랜치이다.
2. 브랜치는 가상의 저장 공간을 통해 코드 수정, 버그 수정, 이력 관리 등을 할 수 있다.
3. 브랜치 기능을 이용하면 코드 수정은 할 수 있지만 다시 커밋은 할 수 없다.
4. 브랜치는 전체 프로젝트 중에서 딱 한 번만 할 수 있다.
문제 2. 로컬과 원격저장소로 구분되며, 안전한 소스코드 관리 및 협업이 가능한 것으로 알맞은 것은?
1. MIT 라이선스
2. 오픈소스
3. 브랜치
4. GIT 저장소
문제 3. 리셋에 대한 내용으로 옳은 것은?
1. 리셋은 새로운 작업을 위해 새로운 작업 환경을 구축하는 것을 일컫는다.
2. 리셋은 작업한 코드를 가상의 저장 공간에 저장하는 것을 일컫는다.
3. 리셋은 그동안 작업하였던 모든 코드를 삭제하는 것을 일컫는다.
4. 리셋은 잘못된 설계로 오류가 발생하였을 때 특정한 시점의 코드로 이동하고 그 이후의 코드는 삭제하는 것을 의미한다.
문제 4. Git 상태에 대한 내용으로 옳지 않은 것은?
1. Git의 상태는 효율적으로 코드 이력을 관리하기 위한 것이다.
2. 워킹 디렉토리는 바로 저장소에 기록 즉, 커밋을 할 수 있는 영역이다.
3. 저장소는 모든 코드의 이력을 저장하고 관리할 수 있다.
4. GIT 상태는 워킹 디렉토리(작업 폴더), 저장소, 스테이지 영역이 있다.
문제 5. Git과 Git 저장소에 대한 내용으로 옳지 않은 것은?
1. 로컬저장소를 통해 다른 사람들과 프로젝트 및 소스코드를 동기화, 불러오기 등을 실행할 수 있다.
2. git 저장소는 로컬저장소와 원격저장소로 구분할 수 있다.
3. git은 소스코드의 모든 변경사항을 관리할 수 있다.
4. git은 변경된 내용을 git저장소(=레파지토리)에 저장한다.
24421