폴리텍 광명융합원 정수영

GIT & GITHUB 0419 commit & status 발표

01. GIT

01.01. 깃이란?

분산형 버전 관리 시스템 (중 하나)

소스 코드의 변경 사항을 추적하고 저장하는 도구

01.02. 깃의 역할

소스 코드의 모든 변경 사항 이력을 관리

깃이 파일 변경 내역을 저장 관리하는데, 이는 깃 저장소를 통해서 한다.

02. 깃 저장소Repository와 깃 초기화

02.01. 깃 저장소

깃 저장소란?

깃으로 관리되는 파일들의 변경 이력을 저장하는 공간

깃은 변경 이력을 저장할 때마다 깃 객체를 생성하고, 이 깃 객체를 깃 저장소에 저장한다.

깃 저장소의 종류

로컬 저장소Local repository

개발자의 개발 환경에 있는 저장소

원격 저장소Remote repository

로컬 저장소와 동일한 깃 저장소를 인터넷 상의 다른 위치에 위치시킨 것

02.02. 깃 초기화 : 오늘부터 linux_suyoung 폴더는 이 깃의 저장소임을 공식 발표하는 바이다.

초기화 : git init <경로명>

깃 초기화 정의

기존 폴더를 깃 저장소로 변경

경로명 생략 시 현재 폴더가 깃 저장소로 초기화

초기화 : 이미 존재하는 폴더에 깃 초기화 명령어를 실행, 기존 폴더를 vcs(version control system)로 관리할 수 있도록 숨겨진 영역 (”.git”)을 생성하는 작업

041900

linux_suyoung이라는 기존 폴더를 깃 저장소 (로컬저장소)로 설정을 하면, 내부의 파일 상태를 추적 관리하여 이력을 기록할 수 있게 된다.

깃은 이 깃 저장소를 이용해, 자체적으로 이력을 기록 “ .git” 이라는 폴더에 버전을 관리할 수 있는 시스템을 자체적으로 구축한다. (” .git”폴더를 삭제하면 일반 linux_suyoung 폴더는 일반 폴더로 되돌아가고, 이미 기록된 버전의 이력도 같이 삭제됨)

03. 워킹 디렉토리 : 작업장

03.01. 정의

코드의 생성과 수정작업을 자유롭게 할 수 있는 상태 영역,

사용자(개발자) 작업 공간.

실제 작업 중인 파일은 모두 워킹 디렉토리 안에 존재함.

03.02. 워킹 디렉토리 내에서 파일 수정, 추가하면 git이 자동으로 관리해주나요? (진짜 모름)

우리가 워킹 디렉토리 영역 안에서 파일을 추가, 수정했다고 깃이 자동으로 관리해주지 않음.

이유

워킹 디렉토리 안에서 생성(또는 수정된) 파일의 초기 상태는 untracked 상태이기 때문에, git이 추적관리를 할 수 없음.

따라서 깃에게 추적관리 해달라고, tracked 상태로 변경해줘야함. 이 과정이 **<스테이지 영역에="" 등록="">이라는 과정**임. (**git add** 명령어 사용하여 등록, 관리할 파일 목록에 등록”해줘”)

근데 왜 tracked, untracked으로 나눌까?

워킹 디렉토리(우리의 작업공간)에서 파일의 변경은 매우매우매우 자주 일어남 & 이력을 관리할 필요가 없는 파일과 작업이 존재함 → 커밋할 파일을 명확하게 구분하고, 자원을 효율적으로 사용하기 위해 구분함

04. 스테이지 : 저장소로 가기 위한 발판

깃의 스테이지 영역

04.01. 정의

임시로 저장하는 공간

워킹디렉토리 ↔ 저장소 둘 사이의 중간 영역에 위치하는 임시 영역

“index”라고도 불린다.

04.02. 역할

컨텐츠의 추적 상태 정보만 기록

(워킹 디렉토리에서 등록 제출된 tracked 상태의 파일들을 관리, 실제 파일 내용을 직접적으로 가지고 있지는 않음)

워킹 디렉토리에서의 파일이 add 명령을 통해 “변경이력을 등록해라”라고 하면, 해당 파일은 untracked → tracked 상태로 변경 & stage상태가 됨.

해당 파일이 워킹 디렉터리 내에서 변경이 되면 다시 untracked & unstage 상태가 됨.

04.03. 존재 이유

커밋을 빠르게 처리하기 위해서 존재

워킹 디렉토리에 추가된 파일과 수정된 내용을 스테이지에 등록, 이런 스테이지 등록은 최종 저장소에 기록되기 전 준비 단계

041901

05. 커밋 COMMIT

버전 : 의미있는 변화를 의미.

05.01. 정의

파일 변경 이력을 저장하는 작업. 파일을 수정하거나 새로 추가한 후, 해당 변경 내용을 Git 저장소에 기록하는 것

06. GIT ADD (등록)

06.01. 정의

워킹 디렉토리에 있는 파일을 스테이지로 복사하는 것

무얼 복사하냐면 —> 깃 내부의 기록들을 복사

06.02. 사용

git add <파일명>

//전체 파일 및 폴더 등록
git add .

07. 실습 : gistory를 이용해서 뜯어보기

git add의 원리 - 생활코딩

07.01. “.git”폴더에는 뭐가 있을까?

사용자 JungSuyoung이란 폴더 안에 gitfth2란 폴더를 만들고,

git init

git init으로 초기화한다. ( “.git”이라는 폴더가 생김)

gitfth2안에 생긴 .git폴더 경로에서 안에 뭐가 들었는지 확인하면

041902

HEAD, config, description, hooks, index 등등이 파일들이 나온다.

041903

(이런식으로도 확인 가능)

gitfth2 폴더 안에 f1.txt을 만들고 내용은 “a”라고 적어 본다.

041904

이렇게 git 저장소 내에서 뭔 짓을 해도

041905

Gistory는 변하지 않는다. 왜?

git add를 통해 워킹 디렉토리 → 스테이지로 옮기지 않았으니까, 변한게 없음

git add f1.txt

git add f1.txt를 해보자

그러면 gistory가 변함

index파일이 다음과 같이 변경됨 :

(index : 파일의 이름이 담긴다)

041906

생성한 파일의 제목 f1.txt는 2e 65efe~란 파일에 담겨있음

object : 파일의 내용이 담긴다

(object 폴더에 새로운 파일이 추가된다.)

041907

이렇게 objects 안에 잇는 2e65efe~란 파일은 객체, 또는 오브젝트라고 불린다. (사실 2e란 디렉토리 내 65~란 파일)

gitfth2란 폴더에 f2.txt(내용은 z)을 새로 만든다.

041908

.

041909

git add를 해보자

그리고 gistory를 확인하면

041910

index가 바뀌고, 오브젝트가 추가됐음을 알 수 있음

041911

각각의 파일명은 index라는 곳에 적혀있다.

f1.txt.를 f3.txt로 복사하고, add해보자

041912

gistory를 확인해보면

041913

인덱스에는 f1.txt, f2.txt, f3.txt 3개가 있고,

오브젝트는 변한게 없다.

클릭해보면

041914

.

041913

f1.txt와 f3.txt가 같은 오브젝트를 가리키고 있음 → git은 파일을 저장할때, 파일의 이름이 달라도 내용이 같으면 같은 오브젝트 파일을 가리킴

(파일이 100만개가 있어도 내용이 같다면, 인덱스에는 파일 이름만 다르게 적혀있고 같은 오브젝트를 가리킴 → (100만 - 1)의 중복을 제거할 수 있음!!!!!!!)

07.02. git은 파일의 내용 기반으로 object 파일의 이름을 만든다

내용이 같으면 파일의 이름이 같다. 즉, 내용을 기반으로 오브젝트 파일의 이름이 결정된다.

sha1 online에 들어가보자.

041915

“hi”라고 입력하고 “hash”버튼을 누르면

c22b5~라고 뜸!

041916

“hello”라고 쳐도 이렇게 뜸

어떤 사람이 입력을 하던간에, “hash”라는 매커니즘(sha-1)을 거치면 똑같은 결과를 얻게 됨.

041917

.git > objects 밑에 “2e”라는 디렉토리를 만들고, (f1.txt인 경우),

041918

65efe~라는 파일을 만들었음, 여기다 내용을 저장 (사실 추가적으로 더 저장되는게 있지만, 대략적인 메커니즘이 이렇다는 말)

07.03. 정리 : git add f1.txt를 하면 이런 일이 일어난다.

1 먼저 add 한 f1.txt를 본다.

2 내용이 “a”라고 적혀있으면, “a”라는 정보와 몇가지 정보를 추가해서 압축함

3 압축한 결과를 sha1이라는 방법으로 해쉬를 통과시킨 값을 만든다.

4 이 값에 해당하는 디렉토리와 파일 (여기서는 2e 디렉토리, 65efe파일)을 objects라는 파일 밑에 만든다.

5 그리고 65efe~라는 파일 안에 “a”라는 정보를 저장한다.

6 인덱스에는 파일의 이름을 (f1.txt)을 적고, 생성한 디렉토리와 파일을 적어줌.

041919

07.04. commit 도 해보자

3개의 파일을 커밋

041920

3개 텍스트 파일을 커밋함

gistory를 살펴보자

041921

041922

041923

커밋도 오브젝트 내의 객체

커밋할때 적은 정보 (-m “1”)가 오브젝트 안에 저장이 되어 있음. (6b 디렉토리 내에 5d5b~란 파일에 )

(버전의 파일 내용처럼 오브젝트 내에 들어감! → 커밋도 내부적으로는 오브젝트 내의 객체라고 할 수 있다)

커밋 안의 정보는 다음과 같음 :

tree 1d3452~라고 적혀있음.

1d 3452라고 적힌 바로 위 오브젝트를 들어가 보면

041924

이런 내용이 나옴.

이 [tree]는 f1.txt, f2.txt, f3.txt 내용이 무엇인가, 라는 정보가 담겨있음

(위 파일들의 오브젝트 디렉토리, 오브젝트 파일은 같다 → 파일이 수정되지 않았으니까)

정리 :

커밋을 하고, 그 커밋을 한 결과 그 버전(커밋)은 오브젝트 파일로 저장이 됨.

그리고 커밋이 저장된 오브젝트 파일의 tree가 있고, 그 tree의 값을 보면 우리가 보는 버전의 파일들의 이름과 내용이 링크가 되어 있음.

버전을 한번 더 만들어서 살펴보자 (변경사항 만들어보기)

041925

f2.txt의 내용을 “yz”로 바꿔봄

그리고 add해봄

041926

gistory에 변경 내용이 반영이 된다.

041927

041928

f2.txt의 내용이 저장된 오브젝트가 바뀌었다.

(나머지 f1.txt, f3.txt는 변화 없음)

커밋을 해보면

041929

커밋이 담겨있는 오브젝트

041930

parent를 클릭하면 이 커밋 이전의 커밋을 볼 수 있음

041931

부모 트리를 타고 타고 가면 과거 자신의 커밋한 내용을 확인할 수 있다.

041932

현재 트리에서도 방금한 커밋 확인 가능

정리

커밋에는 주요한 2가지가 있음

1 이전 커밋이 누구인가, 부모를 나타내는 parent값이 있음

2 커밋이 일어난 그 시점에 , 작업 디렉토리의 파일 이름과 내용이 담겨져 있음(tree로 확인 가능)

각각의 버전마다 서로 다른 트리를 가리키고 있고, 각 트리에는 파일의 이름과 내용이 담긴 링크(오브젝트)가 존재

버전이 만들어진 시점의 프로젝트 폴더에 대한 상태를 얻을 수 있음. 이러한 걸 사진을 찍었다, 이를 스냅샷이라 부른다.

Git에서 파일이나 디렉토리를 커밋(commit)하면, Git은 해당 시점의 파일 및 디렉토리의 상태를 스냅샷으로 저장

각각의 버전은 그 버전이 만들어진 시점에 스냅샷을 트리라는 정보구조를 통해서 가지고 있음.

디렉토리 만들기

mkdir d1 //d1이라는 폴더를 만든다
cp f1.txt d1/f1.txt //f1.txt를 복사하여 d1에 붙여넣기
git add d1/f1.txt //d1에 있는 f1.txt를 스테이지 영역으로 올리기

041933

index에 추가되었음을 확인(기원/f1.txt)

d1/f1.txt, f1.txt, f3.txt는 내용이 모두 같기에 똑같은 오브젝트를 가지는 걸 확인할 수 있음

git commit -m “3”

git commit -m "3"

041934

그리고 가장 마지막에 커밋한 곳에서 parent → parent를 해보면

041935

각각의 커밋은 각각 tree를 가지고 있고, 이 트리를 그 커밋이 만들어진 시점의 파일이름과 내용이 담겨 있음.

041936

커밋의 현 트리에서 d1의 트리를 들어가면 현재 버전의 파일 이름과 내용이 담겨 있음.

정리 : 오브젝트의 3가지 형태

1 파일의 내용을 담는 blob

2 blob (디렉토리의 파일명과, 그 파일명에 해당하는 파일의 내용을 담는)에 대한 정보를 담고 있는 tree

3 commit

08. GIT STATUS

우리가 가진 파일 중에 index란 파일이 있음

041937

깃은 어떻게 커밋할게 있는지 없는지 파악할 수 있을까?

최신 커밋의 tree를 보면 다음과 같다.

041938

index를 보면 다음과 같다.

041939

위의 두 내용이 일치하면 → 커밋할게 없는 상태

041940

클린~하다

08.01. f2.txt를 또 수정해보자

041941

041942

git status를 해보면, “modified: f2.txt”라고 나옴. → f2.txt가 수정되었다.

add를 하고 비교를 해보면

041943

add전에는 “changes not staged for commit: “

add후에는 “”changes to be committed:”

수정된 것 같은데, “not staged”가 붙는다.

![041944](./img/0419/Untitled%2044.png) 오브젝트가 달라짐 ![041945](./img/0419/Untitled%2045.png) <최신 커밋의="" index=""> ![041946](./img/0419/Untitled%2046.png) 최신 커밋의 tree를 보면 위의 blob과 다름, 즉 커밋할 게 있다는 걸 알 수 있음 (커밋 대기 상태) ## 08.02. 커밋 ㄱㄱ ![041947](./img/0419/Untitled%2047.png) ![041948](./img/0419/Untitled%2048.png) 최신 커밋의 tree를 보면 f2.txt의 blob오브젝트가 add 후의 오브젝트와 같게 변경이 되었음을 알 수 있다. ## 08.03. git status를 했을 때 클린하다! 라는 건 뭘까 1 index의 f2.txt가 저장된 오브젝트 의 파일명, 파일 내용 ![041949](./img/0419/Untitled%2049.png) 2 최신 커밋의 f2.txt가 저장된 오브젝트의 파일명, 파일 내용 ![041950](./img/0419/Untitled%2050.png) 3 실제 디렉토리의 f2.txt 내용 ![041951](./img/0419/Untitled%2051.png) 이 3개가 동일! 저장소와, 인덱스와, 프로젝트 폴더(워킹 카피)가 정확하게 일치하기 때문에 git은 git status를 했을떄 더이상 커밋할게 없다, 라고 알려주는 것 ## 08.04. 결론 ![041952](./img/0419/Untitled%2052.png) workspace : .git 바깥쪽에 있는, 프로젝트 폴더(gitfth) = 워킹 디렉토리 add를 하면 index에 등록 commit을 하면 local repository에 오브젝트로 저장이 됨. commit object가 저장, tree가 저장, 파일이 저장 index 파일 (내부적), 사용자의 입장에서는 staging area라고 부르기도 함. (또는 cache) # 2023-04-19 : [깃 commit & status]
서브목차