Git 입문자를 위한 가이드

Post on 15-Aug-2015

359 views 11 download

Transcript of Git 입문자를 위한 가이드

Git 입문자를 위한 가이드

김 종 민

����������� ������������������  Profile����������� ������������������  !

•이름 : 김종민!

•現 자바카페 커뮤니티 강사 준비 2기 참여•現 (주)나루씨큐리티 팀장 •前 (주)모비젠•前 위즈정보기술(주)•前 (주)코리아링크

순서I. 개요!

II. Git클라이언트 설치!

III. 지역 저장소!

IV. 원격 저장소!

V. 브랜치(Branch)!

VI.내부 구조

실습환경• JDK 1.7!

• Eclipse(eclipse-jee-luna-SR2) + Egit(3.7.0)!

• maven(3.2.1)!

• Spring 4.1!

• Mac OS X 10.9 Mavericks!

• git version 1.9.5 (Apple Git-50.3) - 2013/12!✓ latest version 2.4.1(2015-05-13)

I. 개요

I. 개요1. Git 이란?!2. 버전 관리 시스템!3. Git 의 특징!4. Git 의 역사!5. 강의 목표

소스 코드 버전 관리 시스템

Git 이란?

버전 관리

개발 생산성 향상에 대한 요구 증대

소스 코드의 변경 이력을 관리소프트웨어 형상 관리의 일부분

SVN, Git, ClearCase, CVS, !Visual Source Safe

버전 관리 - Dark Age

•파일 이름에 날짜, 버전(v1,v2..)를 붙여서 복사!• tar등으로 압축하여 통재로 복사!•변경된 부분에 대해서 소스코드 비교!•실수로 인한 코드 유실!• \rm -rf!•사장님은 그져 백업이 중요하다고만 하셨어~

버전 관리 시스템

• VCS(Version Control System)!• SCM (Source Code Management System)!•특정 시점 및 변경 추적!•다양한 버전 관리!•협업을 위한 코드 공유!•접근 제한

버전 관리 시스템

소스 코드의 변경 이력을 관리

• 소스코드 추가/수정/삭제에 대한 기록을 저장

!

!

• 즉, 별도로 파일을 카피해 놓거나 백업하지 않아도 됨

• 언제든지 원하는 시점으로 파일의 상태 변경이 가능함으로 파일 내용 변경에 대해서 유연성을 제공함

• 변경 내용에 대한 소스코드의 비교 가능

Git 이란?

소스 코드 버전 관리 시스템분산형 소스 코드 버전 관리 시스템

중앙 집중형 VS 분산형

computer A

file

repository

computer B

file

repository

Server Computer

repository

computer A

file

Central VCS Server

repository

computer B

file

분산형 소스 코드 버전 관리 시스템• 지역 저장소와 원격 저장소로 구분!

• 지역 저장소에서 개별 버전 관리!

• 원격 저장소로 내용 공유!

• 원격 저장소 장애나 인터넷 연결이 되

지 않아도 버전 관리 가능함!

• 원격 저장소 장애로 내용물 유실시에

도 지역저장소에서 복구 가능함

computer A

file

repository

computer B

file

repository

Server Computer

repository

Git vs SVN

GitHub

네이버 트렌드

네이버 트렌드

Java Tools & Technologies

Git의 역사• 1991-2002 - 리눅스 커널 개발 관련 하여 파일로 패치 관리!

• 2002 - 분산 버전 컨트롤 시스템인 Bitkeeper를 사용하게 됨!

• April 2005 - Bitkeeper 라이센스 이슈로 인하여 , Linus Torvalds는 직접 개발(0.0.1)하게 됨(약 2주)!

• GitHub(2008년경)로 인해서 폭발적으로 성장함!

• Latest Version 2.4.4(2015/06/16)

Git의 특징• 단순한 구조!

• 브랜치 모델 (비 선형적 개발 지원)!

• 빠른 성능 (Speed and Performance)!

• Git 특유의 분산환경 지원(지역 저장소, 원격 저장소)!

• 데이타 무결성 보장!

• 스테이징 영역 모델을 채용하여 커밋전 오류를 줄여줌!

• 리눅스 커널 같은 대형 프로젝트에 유용

강의목표

• 지역저장소와 원격저장소의 개념을 이해합니다.!

• Git의 가장 큰 장점이라할 수 있는 브랜치에 대해서 알아봅니다.!

• Git의 동작 원리에 살펴 봅니다.!

• CLI(Command Line Interface) 명령과 이클립스(Eclipse)를 주로 사용해서 설명합니다.

페이지 우측 상단에 나오는 아이콘은 의미는?

이클립스 CLI DAG

II. Git 클라이언트 설치

II. Git 클라이언트 설치1. CLI Git 클라이언트 설치!

2. EGit Plugin 설치

설치

• CLI(Command Line Interface) Client 설치!

• Eclipse + EGit Plugin(https://eclipse.org/egit/) 설치!

✓ Eclipse에서 Git기능을 사용하기 위한 Plugin!✓ JGit(https://github.com/eclipse/jgit) 라이브러리 기반!✓ 3.7.1.201504261725-r!✓ Luna contains EGit 3.4.2

Install CLI Git Client

CLI Git Client 설치 http://git-scm.com/

CLI Git Client 설치

CLI Git Client 설치

CLI Git Client 설치

CLI Git Client 설치

CLI Git Client 설치

CLI Git Client 설치

CLI Git Client 설치

git init --help

Install EGit Plugin

• CLI(Command Line Interface) Client 설치!

• Eclipse + EGit Plugin(https://eclipse.org/egit/) 설치!

✓ Eclipse에서 Git기능을 사용하기 위한 Plugin!✓ JGit(https://github.com/eclipse/jgit) 라이브러리 기반!✓ 3.7.1.201504261725-r!✓ Luna contains EGit 3.4.2

설치

Git perspective

Git perspective

Install EGit Plugin:!Marketplace

Install Egit Plugin

Help > Marketplace

Help > Marketplace

Help > Marketplace

Help > Marketplace

Help > Marketplace

Help > Marketplace

Help > Marketplace

Install EGit Plugin:!Install New Software

Help > Install New Software

Help > Install New Software

http://download.eclipse.org/egit/updates

Help > Install New Software

Help > Install New Software

Help > Install New Software

III. 지역 저장소

III. 지역 저장소1. init - 지역 저장소 생성!

2. status - Working directory 상태!

3. add - Staging Area에 추가!

4. commit!

5. .gitignore!

6. 수정 후 커밋!

7. log - 히스토리

지역 저장소 !(local repository)

Git 저장소

file

computer A

file

repository

computer B

file

repository

Server Computer

repository

Git command flow

Working Directory

Staging Area

local repository

remote repository

commit -a

add

checkout

checkout HEAD

commit

pull(fetch + merge)

fetch

push

지역 저장소 구조나의PC

Working Directory

Staging Area

local repository

Project .git

지역 저장소 구조나의PC

Working Directory

Staging Area

local repository

Project .git Working Directory

Staging Area

local repository

Project .gitWorking Directory

Staging Area

local repository

Project .gitWorking Directory

Staging Area

local repository

Project .git

Git command flow

Working Directory

Staging Area

local repository

remote repository

commit -a

add

checkout

checkout HEAD

commit

fetch

push

pull(fetch + merge)

Create Local Repository

init

Working Directory

Staging Area

local repository

git init [name]

git init

Initialized empty Git repository in !!/Users/jw0201/Desktop/spring4programming/spring4fs-master/sp4-chap02/.git/

$

create local repository

create local repository

Create local repository In !Git Repositories View

create local repository

create local repository

create local repository

create local repository/Users/jw0201/Desktop/spring4programming/spring4fs-master/sp4-chap02

create local repository

create local repository

Team > Shared Project

create local repository

create local repository

create local repository

create local repository

create local repository

create local repository

Working directory Status

working directory status

working directory status

• Working directory에 존재하는 파일들의 상태!

• 스냅샷 포함 유무!✓ Tracked File - 이미 스냅샷에 포함되어 있는 파일로써

Repository 에 의해서 관리 되고 있는 파일이다.!

✓ Untracked File - 스냅샷에 존재하지 않으므로 등록되지 않아 삭제되면 복구할 수 없다.(add를 통하여 Tracked File)

Status

Tracked File status LifecycleTracked File은 Modified, Staged, Committed 상태로 관리

Working Directory

Staging Area

Commit

repository

Checkout the project

Staging

repository status

git status [filename]

git statusOn branch master!!Initial commit!!Untracked files:! (use "git add <file>..." to include in what will be committed)!!! .classpath!! .project!! .settings/!! pom.xml!! src/!! target/!!nothing added to commit but untracked files present (use "git add" to track)

$

Add File at Staging Area

Tracked File status LifecycleTracked File은 Modified, Staged, Committed 상태로 관리

Working Directory

Staging Area

Commit

repository

Checkout the project

Staging

add

Working Directory

Staging Area

local repository

add

Working Directory

Staging Area

local repository

staging

staging물품리스트Working

Directory주문내역Staging

Arealocal

repository

commit

스테이징 영역• 커밋될 예정인 파일의 내용을 준비하는 곳입니다.(곧 커밋할 것이라는 표시)!

• 커밋할때 의미적인 단위(atomic) 로 하는 것이 바람직하다. 다른 VCS에서는

골라서(in working directory - 고르는 비용 절감) 할 수 도 있지만 Git에서는

스테이징 영역에 등록하고 커밋을 한다.

“쇼핑몰에서 물건을 구매할때 먼저 장바구니에 넣는것과 유사하다”

물품리스트 주문내역담기 구매

스테이징 영역• 커밋될 예정인 파일의 내용을 준비하는 곳입니다.(곧 커밋할 것이라는 표시)!

• 커밋할때 의미적인 단위(atomic) 로 하는 것이 바람직하다. 다른 VCS에서는

골라서(in working directory - 고르는 비용 절감) 할 수 도 있지만 Git에서는

스테이징 영역에 등록하고 커밋을 한다.

“쇼핑몰에서 물건을 구매할때 먼저 장바구니에 넣는것과 유사하다”

git add filename

add file at staging area

add file at staging area

add file at staging area

add file at staging area

add file at staging area

add file at staging area

git statusOn branch master!!Initial commit!!Changes to be committed:! (use "git rm --cached <file>..." to unstage)!!! new file: .classpath!! new file: .gitignore!! new file: .project!! new file: .settings/org.eclipse.core.resources.prefs!! new file: .settings/org.eclipse.jdt.core.prefs!! new file: .settings/org.eclipse.m2e.core.prefs!! new file: pom.xml!! new file: src/main/java/chap02/Greeter.java!! new file: src/main/java/chap02/Main.java!! new file: src/main/java/chap02/Main2.java!! new file: src/main/resources/applicationContext.xml

$

Commit

Tracked File status LifecycleTracked File은 Modified, Staged, Committed 상태로 관리

Working Directory

Staging Area

Commit

repository

Checkout the project

Staging

commit

Working Directory

Staging Area

local repository

commit

Working Directory

local repository

Staging Area commit

git commit -m “commit msg”

Commit

Commit

Commit

Commit

Commit

git에서 관리하지 않을 파일이 존재함

Commit

Commit

git에서 관리하지 않을 파일을 지정합니다.

Commit

Commit

Commit

Commit

Commit

Commit

Commit

NO_HEAD가 master로 변경되었음

Commit

git status

On branch master!!nothing to commit, working directory clean

$

파일명 규칙으로 관리 예외 처리

.gitignore

.gitignore•  관리하지 않는 파일의 규칙을 정의한다.!

• #은 주석이다.!

•  표준 Glob패턴을 사용한다.!

•  디렉터리는 슬래시를 끝에 사용하는 것으로 표현한다.!

•  ! 로 시작하는 패턴의 파일은 무시하지 않는다.

.gitignore‘#’ 으로 시작하면 주석이므로 적용되지 않습니다.!

# 확장자가 .a인 파일 무시!

*.a!

# 윗 줄에서 확장자가 .a인 파일은 무시하게 했지만 lib.a는 무시하지 않는다. 순서상 뒷 부분에 위치 해야함!

!lib.a!

# 루트 디렉토리에 있는 TODO파일은 무시하고 subdir/TODO처럼 하위디렉토리에 있는 파일은 무시하지 않는다.!

/TODO

관리하지 않는 파일의 규칙을 정의

.gitignore# build/ 디렉토리 하위에 있는 모든 파일 및 디렉터리를 은 무시한다.(tree object가 상위부터 생성)!

build/!

# `doc/notes.txt`같은 파일은 무시하고 doc/server/arch.txt같은 파일은 무시하지 않는다.!

doc/*.txt!

# `doc` 디렉토리 아래의 모든 .txt 파일을 무시한다.!

doc/**/*.txt

관리하지 않는 파일의 규칙을 정의

.gitignore

/target/!

settings/!

.project!

.classpath

파일 수정 후 커밋하기

파일 수정 후 커밋하기

git status

On branch testing!Changes not staged for commit:! (use "git add <file>..." to update what will be committed)! (use "git checkout -- <file>..." to discard changes in working directory)!!! modified: src/main/java/chap02/Main.java!!no changes added to commit (use "git add" and/or "git commit -a")

$

git add .$

출력 메시지 없음

!!!!!!!

git status

On branch testing!Changes to be committed:! (use "git reset HEAD <file>..." to unstage)!!! modified: src/main/java/chap02/Main.java

$

git commit -m “Main.java에 테스트 코드 추가”$

[master 269f3d3]Main.java에 테스트 코드 추가! 1 file changed, 4 insertions(+)

파일 수정 후 커밋하기

파일 수정 후 커밋하기

파일 수정 후 커밋하기

파일 수정 후 커밋하기

커밋 기록 살펴보기

커밋 기록 살펴보기

커밋 기록 살펴보기

커밋 기록 살펴보기

git log [commit-hash]

!commit 269f3d322be155f5178bd9d0656211720a507911!Author: Jongmin Kim <jw0201@gmail.com>!Date: Sat Apr 25 19:58:53 2015 +0900!! Main.java에 테스트 코드 추가!!commit 886230b26f9cac8de763099da03547390e9fcaec!Author: Jongmin Kim <jw0201@gmail.com>!Date: Sat Apr 25 16:30:12 2015 +0900!! Spring4-Chap02 Initial Commit

git log$

IV. 원격 저장소

IV. 원격 저장소1. Setup Git!

2. 원격 저장소 생성!

3. remote - 원격 저장소 연결!

4. push!

5. clone!

6. pull

원격 저장소 !(remote repository)

Git command flow

remote repository

Working Directory

Staging Area

local repository

commit -a

add

checkout

checkout HEAD

commit

fetch

push

pull(fetch + merge)

GitHub (http://github.com)

원격 저장소 호스팅 서비스

BitBucket(https://bitbucket.org/)

GitLab(https://about.gitlab.com/gitlab-com/)

On-Premise

GitHub (http://github.com)

GitHub (http://github.com)

GitHub (http://github.com)

Set up Git

config

• 환경 설정 값들을 지정하거나 조회할 수 있음!

• git commit 명령어 사용시 이메일, 이름이 설정되어 있어야 함

$ git config --global user.name "YOUR NAME"

$ git config --global user.email "YOUR EMAIL"

환경변수 설정

환경설정 > Team > Git > Configuration

환경변수 설정

config

• 적용순위 : 저장소 변수 > 사용자 변수 > 시스템 변수!

• 사용자(User) 설정 - 사용자 홈 디렉터리의 ~/.gitconfig!

• 저장소(Repository) 설정 - .git/config!

• 시스템(System) 설정 - /etc/gitconfig!

• 동일 변수가 3군데 존재할 수 있음 !

• 우선순위가 높은 값으로 override됨

git config --list $user.name=jiwon!user.email=jiwon@narusec.com!filter.media.clean=git media clean %f!filter.media.smudge=git media smudge %f!filter.media.required=true!core.excludesfile=/Users/jw0201/.gitignore_global!difftool.sourcetree.cmd=opendiff "$LOCAL" "$REMOTE"!difftool.sourcetree.path=!mergetool.sourcetree.trustexitcode=true!filter.hawser.clean=git hawser clean %f!filter.hawser.smudge=git hawser smudge %f!filter.hawser.required=true!merge.tool=vimdiff!user.name=Jongmin Kim!user.email=jw0201@gmail.com

시스템 설정

사용자 설정

저장소 설정

git config [--global] key [value]

환경 설정 값 set/get!!git config --global user.name [이름]

$

GitHub (http://github.com)

Create Remote Repository

GitHub (http://github.com)

GitHub (http://github.com)

https://github.com/jiwon-narusec/sp4-chap02.git

`

Remote Repository

remote repository

Working Directory

Staging Area

local repository

remote

!

git remote$

현재의 지역저장소에서 연결된 원격저장소 리스트

Git 저장소Server Computer

repository

computer A

file

repository

Server Computer

repository

remote

Add Remote Repository

remote

remote

git remote add origin \ https://github.com/jiwon-narusec/sp4-chap02.git

$

git remote

origin

git remote -v$

origin!https://github.com/jiwon-narusec/sp4-chap02.git (fetch)!origin!https://github.com/jiwon-narusec/sp4-chap02.git (push)

$

remote

remote

remote

remote

앞에서 미리 복사해 둔 repository url이 입력됩니다.

remote

remote

remote

Add Remote Repository

remote repository

Working Directory

Staging Area

local repository add

push

!Counting objects: 5, done.!Delta compression using up to 8 threads.!Compressing objects: 100% (2/2), done.!Writing objects: 100% (3/3), 356 bytes | 0 bytes/s, done.!Total 3 (delta 0), reused 0 (delta 0)!To https://github.com/jiwon-narusec/sp4-chap02.git! e03f9da..985026c master -> master

git push origin master$

push

push

push

push

refs/heads/master:refs/heads/master

push

push

+refs/heads/*:refs/heads/*

push

push

push

push

Remote Repository

remote repository

Working Directory

Staging Area

local repository

push

파일을 수정하고 commit과 push동시에 하기

commit and push

commit and push

commit and push

commit and push

GitHub

이클립스에서 Project를 삭제하고 !원격 저장소에서 가져오기

Clone Remote Repository

Clone Remote Repository

remote repository

cloneWorking Directory

Staging Area

local repository

delete project & local repository

delete project & local repository

clone

git clone \ https://github.com/jiwon-narusec/sp4-chap02.git

$

!Cloning into 'sp4-chap02'...!remote: Counting objects: 27, done.!remote: Compressing objects: 100% (17/17), done.!remote: Total 27 (delta 6), reused 24 (delta 3), pack-reused 0!Unpacking objects: 100% (27/27), done.!Checking connectivity... done.

git repositories view 에서 clone 하는 경우

clone

clone

clone

GitHub

GitHub

clone

clone

clone

clone

import project

import project

import project

import project

import project

import project

import 기능을 이용하여!clone하는 방법

import project

import project

import project

import project

import project

import project

import project

import project

다른 사람이(컴퓨터에서) push 한것을 pull 해보기

pull = fetch + merge

pull

Working Directory

local repository

remote repository

pull(fetch + merge)

fetchmerge

pull

pull

pull

단축 아이콘

단축 아이콘

push

fetch

pull

add

commit

stash

branch

rebase

merge

reset

V.브랜치(Branch)

V. 브랜치(Branch)

1. 정의!2. 목적!

3. 브랜치 전략!

4. Git 브랜치 장점!

5. branch!

6. checkout!

7. tag!

8. merge

정의•공통의 개발 코드에서 병행(비 선형) 개발 하기 위해서 특정 분기 생성!•사전적 의미 - 분기하다. 갈라지다.

branch

hotfix

master

목적

• 브랜치를 이용한 병행개발을 통해서 지속적이고 안정적인 소프트웨어 개발이 가능하다.!✓ 기본적으로 master 브랜치 와 topic 브랜치를 분리!

• 브랜치를 이용하여 목적에 맞는 제품 개발이 가능하다.!✓ 제품 출시 일정, 기능, 고객에 맞는 제품 개발

브랜치 전략

• 신규기능, 버그수정, 실험 적인 작업이 요구될때 사용한다.!

• 같은 기능 개발 중에서도 다양한 실험의 목적으로 브랜치에서도 새로운 브랜치를 생성한다.!

• 브랜치로 작업하고 있다면 수정된 내용을 모두 취소 하고 싶을때 브랜치만 삭제하므로 간단하다.

Git 브랜치 장점

• 규모가 큰 프로젝트에서도 빠르고 안정적이다.!

• 브랜치 이동(switch)이 매우 간편하다.(vs 중앙 집중형)!

• 브랜치 생성 비용이 낮다.(vs Mercurial)!

• 브랜치의 이력도 병합시 모두 포함 된다.

브랜치를 이해하려면 git 객체의 구성에 관한 지식이 !좀 필요합니다.

지금부터 git 의 객체간의 관계를 그림으로 같이 설명합니다.

커밋 히스토리

commit

commit size

Spring4-Chap02 Initial Commit

-tree d12825

-auther Jongmin

•commiter Jongmin

886230

Snapshot A Snapshot B

commit size

Main.java에 테스트 코드 추가

-tree 9be6b2

-auther Jongmin

•commiter Jongmin

269f3d

Git commit의 객체 데이터

snapshot

commit size

Main.java에 테스트 코드 추가

tree size

blob size

/target/ .settings/ .classpath .project

-blob 30b2b7 .gitignore

-blob 3e1dab pom.xml

•tree b7d9de src

-tree 9be6b2

-auther Jongmin

•commiter Jongmin

blob size

tree size

<?xml version="1.0" encoding="UTF-8" ?> <project xmlns="http://maven.apache.org/POM/4.0.0"

269f3d9be6b2

30b2b7

3e1dab

b7d9de

저장소의 커밋 데이터

snapshot:commit객체로 찾을 수 있는 tree 이하 부분

tree a61fb9 main

커밋 추가

commit

Snapshot C

commit size

Main.java에 테스트 코드 추가 두번째

-tree fe9cc4

-auther Jongmin

•commiter Jongmin

df0902

commit size

Spring4-Chap02 Initial Commit

-tree d12825

-auther Jongmin

•commiter Jongmin

886230

Snapshot A Snapshot B

commit size

Main.java에 테스트 코드 추가

-tree 9be6b2

-auther Jongmin

•commiter Jongmin

269f3d

Git commit의 개체 데이터

master branch

Snapshot A Snapshot B Snapshot C

886230 269f3d df0902

master

가장 최근 커밋 정보를 가리키는 브랜치

master : Git에서의 기본 브랜치명

branch

Create Branch

Create Branch

현재 나의 branch

Create Branch

Create Branch

Create Branch

!!!!!!!!

git branch testing$

No Message

branch

git branch testing$

886230 269f3d df0902

master

testing커밋 개체를 가리키는 두 브랜치

List Branches

List Branches

git branch

* master! testing

$

Checkout Branch

checkout

지역저장소의 내용을 working directory로 구성하는 것

Working Directory checkout branch

!master branch1 branch2 branch3 branch4

Check Out Branch

checkout branch

Check Out Branch

git checkout testing

Switched to branch 'testing'

$

git branch

master!* testing

$

HEAD

git checkout testing$

886230 269f3d df0902

master

testingHEADHEAD: 현재 작업 중인 브랜치

Commit on testing branch

testing branch

Commit on testing branch

testing branch

git commit -a -m ‘Greeter g1, g2 equals test’$

d9124a886230 269f3d df0902

master

testingHEAD

HEAD가 가리키는 testing 브랜치가 새 커밋을 가리킨다

Commit on testing branch

git tag v0.1 886230$

d9124a886230 269f3d df0902

master

testingHEAD

tag

v0.1

git tag [tagname [commit-hash]]$

tag

git tag$

tag

v0.1

브랜치 관련 명령어

git branch git branch -v git branch -r git branch -r -v git branch -merged git branch —no-merged git branch [branch-name] git branch -b [branch-name]

merge

merge라는 명령어는 나의 branch에서 다른 branch의 내용을 가져와

서 잘 합치는 것이다.

Merge

branch

hotfix

master

Merge

Fast-Forward Merge3-Way Merge

Merge Type

Fast-Forward commit 객체 기준으로 다른 브랜치의 커밋이 선형적으로 증가할 경우

3-Way

Auto-Merge : 내용의 충돌이 없을때

Conflict

Merge

Fast-Forward Merge3-Way Merge

d9124a886230 269f3d df0902

master

testingHEAD

Fast-Forward Merge

checkout master branch

master branch

checkout master branch

master branch

git checkout master$

886230 269f3d df0902 d9124a

master

testing

HEAD

HEAD가 Checkout한 브랜치로 이동함

Fast-Forward Merge

Fast-Forward Merge

Fast-Forward Merge

Fast-Forward Merge

Fast-Forward Merge

git merge testing$

886230 269f3d df0902 d9124a

testing

masterHEAD

Fast Forward Merge

Merge

Fast-Forward Merge3-Way Merge✓

3-way merge

C0 C1 C2

master

testing

C3

C4

C5

common ancestor

Snapshot to Merge Into

Snapshot to Merge In

Git은 Merge에 필요한 공통 커밋을 자동으로 찾음

Merge

Fast-Forward Merge 3-Way MergeNon Conflict - Auto MergeConflict - resolve Conflict

✓ Non Conflict - Auto Merge

3-Way Merge(Auto Merge)

master branch

GenericXmlApplicationContext -> ClassPathXmlApplicationContext

3-Way Merge(Auto Merge)

886230 269f3d df0902 d9124a

testing

master

7b19650

3-Way Merge(Auto Merge)

testing branch

3-Way Merge(Auto Merge)

886230 269f3d df0902 d9124a

testing

master

7b19650

b00809c

Merge on master branch

3-Way Merge(Auto Merge)

master branch

3-Way Merge(Auto Merge)

3-Way Merge(Auto Merge)

master branch

3-Way Merge(Auto Merge)

3-Way Merge(Auto Merge)

3-Way Merge(Auto Merge)

master branch

git checkout master$git merge testing$

Auto-merging src/main/java/chap02/Main2.java!

Merge made by the ‘recursive’ strategy!

!!!!!!!!src/main/java/chap02/Main2.java | 1+!

!!!!1 file changed, 1 insertion(+)

3-Way Merge(Auto Merge)

886230 269f3d df0902 d9124a

testing

master

7b19650

b00809c

git merge testing$

40c02ed

3way-Merge에서는 Merge에 대한 정보가 들어 있는 커밋(Merge Commit)를 하나 만든다.

3-Way Merge(Auto Merge)

Merge

Fast-Forward Merge 3-Way MergeNon Conflict - Auto MergeConflict - resolve Conflict

✓ Conflict - resolve Conflict

3-Way Merge(Conflict)

886230 269f3d df0902 d9124a

testing

master

7b19650

b00809c

40c02ed

다른 브랜치(master, testing)에서 같은 부분을 수정하여 !

conflict를 만들어 보자

3-Way Merge(Conflict)

master branch

3-Way Merge(Conflict)

d9124a

testing

master

7b19650

b00809c

40c02ed

8050740

3-Way Merge(Conflict)testing branch

3-Way Merge(Conflict)

d9124a

testing

master

7b19650

b00809c

40c02ed

8050740

2685e36

Merge on master branch

3-Way Merge(Conflict)

3-Way Merge(Conflict)

3-Way Merge(Conflict)

3-Way Merge(Conflict)

3-Way Merge(Conflict)

3-Way Merge(Conflict)

3-Way Merge(Conflict)

d9124a

testing

master

7b19650

b00809c

40c02ed

8050740

2685e36

3f8ac59

remote branch

Git command flow

모든 repository는 개별적으로 branch이다.

remote repository

local repository

fetch

pushlocal

repository

push

fetch

local repository

remote branch

• push도 하나의 원격 저장소 입장에서 merge 행위!• merge는 내가 다른 branch의 것을 가져오는 행위!• remote repository는 사람이 아니므로 FF만 허용됨!• push하려는 local repository는 remote repository의 최신의 상태를 가지고 있어야 함!

•따라서 push 하기 이전에 pull 명령어를 사용하여 원격 저장소에 가장 최근에 업데이트 된 내용을 모두 받아서 merge해야함

VI. 내부구조

VI. 내부구조1. Delta vs Snapshot!

2. Plumbing vs Porcelain!

3. The .git folder!

4. Git 구성 요소!

5. Reference

Delta vs Snapshot

version1 version2 version3 version4 version5r1 r2 r3 r4 r5

Delta(변화 or 차이점)case: svn

File A

File B

File C

r1 r2 r3 r4 r5

Delta(변화 or 차이점)case: svn

File A

File B

File C

version1 version2 version3 version4 version5c0 c1 c2 c3 c4

Snapshotcase: git

File A

File B

File C

File A1

File C1 File C2

File A2

File B1 File B2

File C3

Snapshotcase: git

version1 version2 version3 version4 version5c0 c1 c2 c3 c4

File A

File B

File C

File A1

File C1 File C2

File A2

File B1 File B2

File C3

Snapshotcase: git

version1 version2 version3 version4 version5c0 c1 c2 c3 c4

File A

File B

File C

File A1

File C1 File C2

File A2

File B1 File B2

File C3

Plumbing vs Porcelain

Plumbing vs Porcelain

Plumbing vs Porcelain!

• Plumbing!• Content Addressable file system!• v1.5이전에 주로 사용하던 명령어(v2.4.1 2015-05-13)!

!

• Porcelain!• VCS(Verson Control System) 사용자 인터페이스 명령어!• 예) add, commit, checkout, branch, remote

git init

Initialized empty Git repository in /Users/jw0201/git_sample/.git/

$

지역 저장소 구조Local Computer

Working Directory

Staging Area

local repository

Project .git

The .git folder

.git/ index config description HEAD hooks/ info/ objects/ refs/ logs/

저장소 내용은 .git 폴더에 있음(.git을 지우면 저장소 내용이 삭제됨)

<= git add

find .git/refs -type f

! .git/refs/heads/master!!

! .git/refs/heads/testing!

.git/refs/remotes/origin/master!

.git/refs/tags/v0.1

$

d9124a886230 269f3d df0902

master

testing

HEAD

v0.1

.git/refs

more .git/HEAD

! ref: refs/heads/master

$

more .git/refs/heads/master

! df0902………….

$

more .git/refs/heads/testing

! d9124a………….

$

more .git/HEAD

! ref: refs/heads/testing

$git checkout testing$

d9124a886230 269f3d df0902

master

testing

HEAD

v0.1

.git/refsgit checkout testing$

The .git folder• HEAD - 체크아웃된 브랜치(스냅샷 시작 포인트)!

• branches/ - 현재 사용되지 않음 !

• config - 해당 저장소에만 존재하는 git 환경 설정 파일!

• description - GitWeb 프로그램 에서만 사용 함!

• index - 스테이징 에어리어 정보를 저장(최초에는 존재하지 않음)!

• hooks/ - 클라이언트 훅이나 서버 훅 내용을 저장함(최초에는 .sample이 존재)!

• objects/ - git의 object가 저장되어 있는 데이터베이스 디렉터리(repo content)!

• refs/ - commit object의 포인터를 저장!

• logs/ - commit 명령어를 통해서 생성되고 git-log명령어를 통해서 조회

ref: ref/head/master

4가지 객체

COMMIT

TREE BLOB

TAG

• Blob - 파일이 저장되는 객체(실제 저장되는 파일)!

• Tree - Blob(또는 Tree)을 포인팅하는 디렉터리 객체!

• Commit - 커밋하면 생성되는 객체!

• Tag - 특정 commit 객체에 대한 alias

Git is a content-addressable filesystem

.git/objects

4가지 객체

commit, tree, blob

tree a61fb9 main

commit size

Main.java에 테스트 코드 추가

tree size

blob size

/target/ .settings/ .classpath .project

-blob 30b2b7 .gitignore

-blob 3e1dab pom.xml

•tree b7d9de src

-tree 9be6b2

-auther Jongmin

•commiter Jongmin

blob size

tree size

<?xml version="1.0" encoding="UTF-8" ?> <project xmlns="http://maven.apache.org/POM/4.0.0"

269f3d9be6b2

30b2b7

3e1dab

b7d9de/ 디렉터리 역할

snapshot:commit객체로 찾을 수 있는 tree 이하 부분

commit, snapshot

commit size

Main.java에 테스트 코드 추가

-tree 9be6b2

-auther Jongmin

•commiter Jongmin

269f3d

Snapshot

commit’s parents

Snapshot C

commit size

Main.java에 테스트 코드 추가 두번째

-tree fe9cc4

-auther Jongmin

•commiter Jongmin

df0902

commit size

Spring4-Chap02 Initial Commit

-tree d12825

-auther Jongmin

•commiter Jongmin

886230

Snapshot A Snapshot B

commit size

Main.java에 테스트 코드 추가

-tree 9be6b2

-auther Jongmin

•commiter Jongmin

269f3d

4가지 개체

• Blob - 파일이 저장되는 객체(실제 저장되는 파일)!

• Tree - Blob(또는 Tree)을 포인팅하는 디렉터리 객체!

• Commit - 커밋하면 생성되는 객체!

• Tag - 특정 commit 객체에 대한 alias

Git is a content-addressable filesystem

.git/objects

blob object

blob

file_name : SHA-1

content: 압축(zlib.deflate)

git add$

add = blob object생성 + staging area등록

create blob object

blob

git add test.txt$

$ echo 'version 1' > test.txt!$ git hash-object -w test.txt!83baae61804e65cc73a7201a7252750c76066a30

echo ‘version 1’ > test.txt$

.git/objects/83/baae61804e65cc73a7201a7252750c76066a30

plumbing

blob

$ git cat-file -p 83baae61804e65cc73a7201a7252750c76066a30!

version 1!

$ git cat-file -t 83baae61804e65cc73a7201a7252750c76066a30!

blob

.git/objects/83/baae61804e65cc73a7201a7252750c76066a30

blob

git add test.txt$

$ echo 'version 2' > test.txt!$ git hash-object -w test.txt!83baae61804e65cc73a7201a7252750c76066a30

echo ‘version 2’ > test.txt$

.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a

blob

$ git cat-file -p 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a!

version 2!

$ git cat-file -t 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a!

blob

.git/objects/1f/7a7a472abf3dd9643fd615f6da379c4acb3e3a

add blob object to staging area

.git/index

$ git update-index --add --cacheinfo 100644 \!

1f7a7a472abf3dd9643fd615f6da379c4acb3e3a test.txt!

git add test.txt$

.git/index (binary file)

plumbing

4가지 객체

• Blob - 파일이 저장되는 객체(실제 저장되는 파일)!

• Tree - Blob(또는 Tree)을 포인팅하는 디렉터리 객체!

• Commit - 커밋하면 생성되는 객체!

• Tag - 특정 commit 객체에 대한 alias

Git is a content-addressable filesystem

.git/objects

tree object

tree

name : SHA-1

content : permission, SHA-1, type, filename

git commit$

commit command!= create tree object!

+ create commit object

tree• Blob object를 포함하는 최소 1개 존재!

• 현재 Index된 정보에 대해서 tree생성!

• Git은 empty 디렉터리를 추적 하지 않음!

• 디렉터리에 파일이 존재하면 Tree Object를 생성하여 연결!

• Blob, Tree 에 대한 정보 포함!• Filename, SHA-1, type(blob or tree), Permission

tree

git commit -m “commit file”$

2f398 0644 blob 1f7a7 test.txt

name : SHA-1 content : 암호화된 내용

plumbing$ git write-tree!

2f39845a4a2c3ad86adebb00b1ddabd959c131c4 test.txt

$ git cat-file -p 2f39845a4a2c3ad86adebb00b1ddabd959c131c4!

100644 blob 1f7a7a472abf3dd9643fd615f6da379c4acb3e3a !test.txt!

$ git cat-file -t 2f39845a4a2c3ad86adebb00b1ddabd959c131c4!

tree

tree

git commit -m “commit file”$

• Blob - 파일이 저장되는 객체(실제 저장되는 파일)!

• Tree - Blob(또는 Tree)을 포인팅하는 디렉터리 객체!

• Commit - 커밋하면 생성되는 객체!

• Tag - 특정 commit 객체에 대한 alias

Git is a content-addressable filesystem

.git/objects

4가지 객체

commit object

commit

name : SHA-1 header : key-value pair keys=> tree, parent, author, committer content : commit message

git commit$

commit

git commit -m “commit file”$

2f398 0644 blob 1f7a7 test.txt

name : SHA-1 content : 암호화된 내용

c9432 tree 2f398 parent, author, committer commit message

plumbing

$ echo ‘commit file' | git commit-tree 2f398!

c943228932bf7a2f50d9a66423baa0bf673cd623

commit

git commit -m “commit file”$

$ git cat-file -p c943228932bf7a2f50d9a66423baa0bf673cd623!

tree 2f39845a4a2c3ad86adebb00b1ddabd959c131c4!

author Jongmin Kim <jw0201@gmail.com> 1428569090 +0900!

committer Jongmin Kim <jw0201@gmail.com> 1428569090 +0900!

!

commit file!

$ git cat-file -t c943228932bf7a2f50d9a66423baa0bf673cd623!

commit

porcelain

plumbing

• Blob - 파일이 저장되는 객체(실제 저장되는 파일)!

• Tree - Blob(또는 Tree)을 포인팅하는 디렉터리 객체!

• Commit - 커밋하면 생성되는 객체!

• Tag - 특정 commit 객체에 대한 alias

Git is a content-addressable filesystem

.git/objects

4가지 객체

! .git/refs/heads/master!!

! .git/refs/heads/testing!

.git/refs/remotes/origin/master!

.git/refs/tags/v0.1

find .git/refs -type f$

.git/refs/tags/v0.1

reference

• branch(.git/refs/heads)!

• HEAD(.git/HEAD)!

• remote branch(.git/refs/remotes)

파일이 조금이라도 변경되서 다시 객체가 계속 만들어지면 나중에 .git의 용량이 너무 커지는거 아닌가요?

packfile

• 최초에 생성된 object를 Loose 개체 포맷이라고 한다.!

• 스냅샷을 각 commit별로 별도로 생성되는데 만약 1byte라도 변경되면 새로운 스냅샷을 생성하게 된다.!

• 압축(zlib)을 하지만 그래도 중복이 많다.!

• packfile을 만들어 유사한 내용을 제거하여 관리할 수 있다.!• git gc로 수동 생성!• git push에서 자동 수행!• object의 숫자가 증가하면 자동으로 수행

packfile

git gc$

$ git gc!Counting objects: 73, done.!Delta compression using up to 8 threads.!Compressing objects: 100% (45/45), done.!Writing objects: 100% (73/73), done.!

Total 73 (delta 22), reused 0 (delta 0)

packfile

./19!

./19/db5920245f9e7344156ac28b2c779c1aaabdc5!

./9e!

./9e/ed961fc720d382dafff387689327c86ddf9685!

./c3!

./c3/113e26046d985a0e993158061e85331e469bb1!

./info!

./info/packs!

./pack!

./pack/pack-3196865a95b6050688f35ddd2cd20378afb296db.idx!

./pack/pack-3196865a95b6050688f35ddd2cd20378afb296db.pack

.git/objects

참고• 프로 Git , 스캿 사콘(인싸이트)!

• http://git-scm.com/book/ko/v1!!

• EGit 사용자 가이드!• https://wiki.eclipse.org/EGit/User_Guide!

!

• 분산 버전 관리 Git 사용설명서(제이펍)!• 협업 소프트웨어 개발을 위한 강력한 도구와 기술(제2판)!• 존 롤리거, 매튜 매컬러프 공저!

!

• 리누스 토발즈 인터뷰!• http://techholic.co.kr/archives/31767

Git 학습 방법• 점짐적 학습, 즉 쉽고 간단한 명령부터 복잡하고 정교한 명령 사용!• 직접 해 보는 것이 무엇 보다 중요!• CLI, GUI 툴 동시 사용!• 내부 동작을 이해하는 것이 많은 도움이 됨

About Conflict• local branch의 merge 또는 pull하는 과정에서 발생함!• 되도록 만나지 않으려면 최대한 자주 pull, push 하도록 권장!• 자주 커밋할 수 있도록 하려면 논리적으로 작업을 잘 분할 해야 함!• 부득이하게 pull과 checkout작업이 필요할 경우 stash할 수도 있음!• merge tool을 사용한 적극적인 resolving conflict

감사합니다.