Git 사용 가이드

Post on 22-Nov-2014

20.654 views 6 download

description

show how to use Git in developement how to merge others with mime hot to diff other with mime

Transcript of Git 사용 가이드

Git 사용 가이드KTH, 분산기술 Lab임도형

2012/03/16

2

본 문서에 대하여• Git 을 사용하여 개발할 때에 경험한 헤딩을 공유하고자 합니다 .• Git 자체를 설명하지는 않습니다 .• Git 자체에 대한 이해는 얄팍합니다 . 절대로 Git 에 대한 마스터피스가 아닙니다 .

• remote repository 로 GitHub 를 사용합니다 .• linux 환경에서의 개발입니다 .• 대상은 CVS, SVN 과 같은 버전닝 , 소스관리 툴의 개념을 알고 있다는 전제입니다 .

3

본 문서의 거짓말에 대하여• 본 문서에서 말하는 Git 의 내부적인 것들은 대부분 거짓말입니다 .

• 하지만 Git 을 사용하여 개발하는데 필요한 멘탈 모델로서는 모순됨이 없네요 .

• 단순히 Git 의 사용을 위한 학습방법으로만 받아들이시고 , 인용하거나 사실로 오해하시면 안됩니다 .

4

Git 를 사용하면서 가려웠던 사항• branch? stash? repository? remote?

local?

• 내가 수정한 것과 Remote Repository 의 것과 비교하고 싶다 .

• 내가 commit 할 변경 내용을 한눈에 보고 싶다 .

5

가장 곤란했던 헤딩 상황• 내가 무언가를 수정했고 , 이를 GitHub 에

push 하려는데 실패한다 . 다른 팀원이 변경한 것이 이미 GitHub 에 올려져 있는 상황이다 .

차분히 가봅시다 .

7

How To : 프로젝트 다운 받아 개발시작하기

(1) 프로젝트 kthcorp/mytest.git 를 mytest 라는 폴더로 다운받는다 .(2) 변경된 것을 local repository 에 commit 하겠다 .(3) local repository 에 commit 된 것을 remote repository 에 반영하겠다 .

$ git clone git@github.com:kthcorp/mytest.git(1)

$ cd mytest$ echo “first file” > first_file.txt$ git commit –a –m “add new file”(2)$ git push(3)

8

Local Repository• Local Repository 는 SVN server 로 생각하라 .

• 따로 설치하거나 구동하지 않는다 . 단지 linux 에 git 가 설치되어 있고 , git clone 으로 프로젝트를 다운받았으면 있는 것이다 .

• local 이라는 것은 로그인한 linux 박스에서의 , 로그인한 계정에서만 통한다는 것이다 .

• 그러니까 모든 개발자는 별도의 서버를 운영하고 있는 것이다 .

• 그 개별적인 서버에 혼자서 지지고 볶으면 된다 . 다른 팀원과는 관계없다 .

9

Remote Repository• 그런데 하나의 단위 개발이 끝났으면 , 이를 공유하여야 한다 .

• 이를 위한 것이 Remote Repository 이다 . 별도로 구축할 수도 있다 . KTH 는 GitHub 를 사용한다 .

• Remote Repository 의 것은 다 같이 공유되어야 하기에 , 완성도 있는 것들만 (compile 되고 , test 성공하고 , …) 올려져야 겠다 .

• 절대 SVN 의 서버가 Remote Repository 라 생각하지 마라 . 그러면 헷갈린다 . Remote Repository 에는 commit 이라는 개념도 update 라는 개념도 없다 . commit 과 update 는 오직 Local Repository 하고만 관련된다 .

10

Git 에서의 commitWork Space

LocalReposi-

tory

RemoteReposi-

tory

commit -apush

• Work Space 는 단지 개발하고 있는 파일시스템의 폴더일 뿐이다 . (‘.git’ 폴더가 존재하는 )

• SVN 의 commit 과 마찬가지로 변경사항을 Local Repository 에 적용 .• 그리고 이를 공유하기 위해 push 로 Remote Repository 에 올린다 .

개발

11

SVN 에서는• 수정하고 , update 하면 자동으로 merging해 주고 , conflict 난 경우 이를 표시해 준다 .

Work Space

SVNServer

commit

개발

update

누군가commit

12

그런데 , Git 에서는 잘 안된다 .Work Space

LocalReposi-

tory

RemoteReposi-

tory

• SVN 의 update 라는 명령이나 개념도 없다 .• 변경된 사항을 덮어쓸 수 있다고 하면서 merge 가 실패한다 .• 먼저 commit 하던가 stash(?) 하라고 한다 .

개발fetch

merge

13

How To : 내가 수정한 것과 타인이 수정한 것을 merging 하여 commit 하기

(1) 파일을 수정했다 .(2) 변경된 사항 전부를 local repository 에 commit 한다 .(3) remote repository 에서 최신의 것을 local repository 로 가져온다 .(4) local repository 에 가져온 최신의 것과 내가 commit 한 내용을 merging 한다 .(5) merging 된 사항을 remote repository 에 올린다 .

$ echo “some modification” >> first_file.txt(1)

$ git commit –a –m “add first_file.txt”(2)

$ git fetch(3)$ git merge origin(4)$ git push(5)

commit 의 – a 옵션은 git add 없이 모든 변경된 것을 대상으로 하라는 의미

14

Git 에서의 commit 과 mergeWork Space

LocalReposi-

tory

RemoteReposi-

tory

fetchmerge origin

• 좀 이상하다 . merge 된 결과를 다시 commit 하고 push 해야 할 것 같은데 .• 그리고 merge 할 때의 ‘ origin’ 은 뭐지 ?

개발commit -a

push

15

브랜치Work Space

LocalReposi-

tory

RemoteReposi-

tory

fetch

• Git 는 브랜치라는 개념으로 작업본을 관리한다 .• 내가 commit 한 본은 ‘ master’ 라는 이름의 브랜치로 , Remote

Repository 에서 가져온 것은 ‘ origin’ 이라는 이름의 브랜치로 존재

commit -aori-gin

mas-ter

16

브랜치 간 mergeWork Space

LocalReposi-

tory

RemoteReposi-

tory

• merge origin 은 현재 작업중인 브랜치 master 에 origin 이라는 브랜치의 수정된 것을 병합하라는 것이다 .• merge origin 을 실행한 후에는 origin 의 수정 사항 ( 십자가 ) 가

HEAD 에 반영되었다 .• 또한 merge 된 결과는 다른 명령 없이 Work Space 에 그대로 반영된다 .

ori-gin

mas-ter

merge origin

ori-gin

mas-ter

사용자가 정의하는 브랜치

18

How To : Local Repository 에 새로운 branch 생성(1) 새로운 브랜치 ‘ test’ 를 생성하고 , 그 브랜치로 변경한다 .(2) 브랜치 리스트를 조회한다 . 별표 (*) 가 붙은 test 브랜치가 현재의 브랜치이다 .

(3), (4) 새로운 파일 test.txt를 만들었다 .

(5), (6) 기존의 브랜치 mas-ter 로 변경했다 . 브랜치 test에서 만들었던 test.txt 파일은 존재하지 않는다 .

$ lsfirst_file.txt$ git checkout –b test

(1)$ git branch(2) master* test$ echo “my test” > test.txt(3)$ ls(4)first_file.txt test.txt$ git checkout master

(5)$ ls(6)first_file.txt

19

test

branch 생성 , 수정Work Space

LocalReposi-

tory

• 브랜치가 생성될 때 Work Space( 그냥 폴더 ) 의 내용은 master 와 같다 .• 임의의 수정 ( 별표 ) 하고 commit 하면 Local repository 의 test 브랜치에 그 내용이 적용된다 . master 하고는 관계없다 .

checkout -b testmas-ter

mas-ter

mas-ter testtest

test mas-ter test

개발commit -a

test mas-ter

20

How To : 현재의 브랜치를 확인 , 다른 브랜치로 전환 , 브랜치 삭제하기

(1) 브랜치 리스트를 조회한다 . ‘*’ 표 붙은 master 가 현재의 브랜치이다 . (2) 브랜치 test 로 변경한다 .(3) 현재의 브랜치는 test 이다 .(4) 브랜치를 삭제한다 . 변경된 사항을 무시하고 강제 삭제하려면 – D 옵션을 준다 .

$ git branch(1)* master test$ git checkout test(2)$ git branch(3) master• test$ echo “some modification” > some.txt$ git checkout master$ git branch –D test

(4)

21

브랜치 전환Work Space

LocalReposi-

tory

• 새 브랜치 test 에 적용한 사항을 master 에 적용하려면 master 브랜치로 변환한 후 ‘ merge test’ 를 한다 .

checkout mastermas-tertest

mas-ter testmas-

ter

mas-ter

mas-ter test

test

merge test

Index

23

Index, Git 의 구성 하나 더Work Space

LocalReposi-

tory

RemoteReposi-

toryIndex

• 앞의 예에서 ‘ commit –a’ 라 한 것은 변경된 사항 전부를 commit 의 대상으로 한다 .• 정확히는 commit 의 대상은 오직 Index 에 포함된 것만이다 .• ‘commit –a’ 는 변경된 사항 전부를 add 하고 나서 commit 을 실행한 것과 같다 .• 앞의 예에서는 전부 commit –a 를 사용하였다 . 설명의 간편함을 위한 것이다 . 선별적으로 commit 할 대상을 add 하는 것이 바람직하다 .

commitadd

24

$ git checkout master$ lsold_app.py$ echo “print ‘hello’” >> old_app.py$ echo “print ‘hi’” > new_app.py$ touch to_be_ignored.txt$ git status (1)# Changes not staged for commit:# old_app.py# Untracked files:# new_app.py, to_be_ignored.txt$ git add old_app.py new_app.py

(2)$ git status (3)# Changes to be committed:# old_app.py, new_app.py# Untracked files:# to_be_ignored.txt

How To : 변경된 상태 보기 , 특정 파일만 commit 대상으로 포함하기

old_app.py 를 생성하고 , new_app.py, to_be_ignored.txt 를 새로 만들었다 .

(1) 상태를 조회한다 . old_app.py 는 수정되었지만 commit 되지 않을 파일이라 보여주고 , 나머지 2 파일은 관리되지 않는다고 보여준다 .(2) old_app.py 와 new_app.py 를 commit 대상으로 포함한다 .(3) old_app.py 와 new_app.py 는 이제 변경되었고 commit 될 것임을 보여주고 있다 .

25

How To : 특정 파일을 ignore 하기

• Index 에 add 되지 않은 파일은 commit 에서 제외되기 때문에 , 따로 ignore 차리 하지 않아도 된다 .

• 만약 git status 에서도 보이지 않게 하려면 다음과 같이 한다 .(1) ignore 대상을 명시한 파일을 생성한다 . 본 예에서는 .svn 폴더와 확장자 pyc 의 파일로 하였다 .(2) 생성한 파일을 적용하도록 설정한다 .

$ vi ~/.gitignore(1).svn*.pyc$ git config --global core.excludesfile ~/.gitignore(2)

diff 하기

27

How To : 현재 작업된 것과 Local Reposi-tory 과의 차이를 비교하기

(1) Local repository 에 commit 된 것과 현재 Work Space 의 차이를 보여준다 .

$ git commit –m “old change”$ echo “hi” >> test.txt$ git diff(1)…+hi

28

How To : 좀더 다양한 diff

• git diff 에 사용되는 옵션은 브랜치 이름이거나 revision 이다 . 똘똘하게 알아서 찾아 준다 .• Remote Repository 와 현재의 것을 비교하려면 우선 fetch 명령으로

Local Repository 로 가져온 다음 diff origin 으로 비교할 수 있다 .

$ git diff : Local Repository 의 최근 commit 된 상태와 $ git diff --cached : Index 와 Local Repository 간 차이$ git diff HEAD : git diff 와 동일$ git diff HEAD^ : Local Repository 의 바로 전 revision 과$ git diff HEAD^^ : Local Repository 의 바로 전전 revision과$ git diff master test : 브랜치 master 와 test 간 차이$ git diff a1b2c3 : revision “a1b2c3” 간 차이$ git diff HEAD^ a1b2c3 : Local Repository 의 바로전 revision과 revision ‘a1b2c3’ 간 차이$ git diff origin : fetch 해서 가져온 origin 과 비교

29

branch, HEAD, revision, master, origin• Git 는 revision 에 순차적인 번호을 사용하지 않는다 .• 특정 revision 에 숫자와 문자가 섞인 7 character 를 사용한다 .• 그렇기 때문에 어떤 브랜치의 어떤 리비전이라고 하지 않고 , diff 시에 그냥 리비전만 주면 된다 .• 만약 브랜치의 이름이 주어지면 , 가장 최근의 리비전을 사용한다 .

• HEAD 는 현재 작업중인 브랜치의 가장 최근 리비전을 가리키는 예약어이이다 .• 만약 브랜치를 변경하지 않았으면 master 가 현재의 브랜치가 되고 HEAD 대신

master 로 하여도 결과는 같다 .

• master 는 기본 브랜치의 이름이다 .• origin 은 Remote Repository 에서 가져온 브랜치의 이름이다 .

Stash

31

당황스런 상황• 타 팀원이 무언가를 수정한 것 같다 .• 그 것을 확인하고 나서 내가 작업한 것을 commit 하고 싶다 .

• 다른 곳에 파일 카피를 해서 백업해 둘 수는 있는데 , 그렇게 하면 일일이 손으로 하나씩 확인하며 merging 작업을 해야만 한다 .

32

How To : 작업 하던 내용을 백업하고 ,다운받은 최신 버전에 나중에 적용하기

(1) 변경된 사항이 있다 .(2) 변경된 사항을 Stash 에 보관해 두고 , 현재의 상태를 Local Reposi-tory 의 최근 commimt 상태로 변경한다 .(3) 변경된 사항이 없음을 확인(4) Remote Repository 에서 최신 것을 가져온다 .(5) Stash 에 보관된 변경사항을 적용하여 머징한다 .(6) 변경된 사항을 Local Repository 에 commit 한다 .

$ git diff (1)# Changed …. : ….$ git stash (2)$ git diff (3)$ git pull (4)$ git stash pop (5)$ git commit –a –m “my modification”

(6)

33

Stash 를 사용한 작업 백업Work Space

LocalReposi-

tory

RemoteReposi-

tory

pull

• 작업 해둔 사항 ( 별 ) 을 Stash 에 보관해 둔다 .• 보관해 둔 변경 사항은 stash pop 을 사용하여 merging 할 수 있다 .• 이때의 merging 은 단지 Work Space 에서만 진행된다 .

개발Stash

stash

stash popadd, commit

34

How To : Stash 에 보관된 것과 비교하고 싶다 .

(1) Stash 에 저장된 것을 조회한다 . 현재 2 개가 있다 .(2) 최신의 것과 비교한다 . –p 옵션을 주면 내용까지 확인 한다 .(3) 이름 ‘ stash@{1}’ 로 저장된 것과 비교한다 .(4) 최신의 것으로 merging 한다 . ‘stash pop’ 을 사용할 경우 merging하고 삭제한다 .(5) Stash 에 저장된 것을 전부 삭제한다 .

$ git stash list(1)

stash@{0}: WIP on master: …stash@{1}: WIP on master: …$ git stash show -p (2)…$ git stash show –p stash@{1}

(3)…$ git stash apply (4)$ git stash clear (5)

다시 정리

36

머징 , 브랜치 , 커밋• 핵심 기능 merging 은 오로지 Local Repository 에서만 이루어 진다 . 따라서 merging 을 하고 싶으면 우선

commit 하여야 한다 . 이점이 SVN 과 가장 큰 차이이고 , 헤딩하게 만든 원인이다 .• 무언가를 해보고 싶으면 우선 branch 부터 만들고 시작하자 . 하다 관두고 삭제해도 좋고 . 그곳에서 commit된 것은 그 branch 만의 문제이다 . 세세한 commit 으로 구성된 전체 작업이 끝나면 master 로 merging 하자 .

• SVN 에서는 소소한 것들을 commit 하기 거시기 했다 . 이제는 branch 만들고 마구마구 소소하게 commit 하자 .

37

다시 보는 Git 의 구성 요소들

• Stash : 작업한 내용의 백업 용도 . merging 기능을 사용할 수 있다는 그 이유 때문에• Work Space : 작업하는 폴더 그것 . 다른 브랜치로 변경하면 , 자동으로 폴더의 내용가지 변환된다 .• Index : 사용자 입장에서는 반길 것 없는 . 덕분에 매번 add 해주어야 한다 .• Local Repository : 모든 브랜치와 변경된 사항은 여기서 관리된다 .• Remote Repository : 타인과 공유하기 위한 공간

Work Space

LocalReposi-

tory

RemoteReposi-

toryIndexStash

기타 팁들

39

‘fast forward’• 실패하는 대부분은 fast forward 와 관련되어 있다 .• 버전을 관리하자는 것은 최신의 것에 자신의 수정 부분을 적용하자는 것이고 , 그런 상태를 ‘ fast forward’ 라는 용어로 표현한다 .

• 만약 어떤 이유로 최신 버전에 적용할 수 없는 경우 fat forward 하지 않다고 하고 , 작업한 결과를 읽어 버릴 수 있다고 하여 동작이 실패한다 .

• commit 하지 않은 상태에서 pull 할 경우가 fast for-ward 하지 않은 상태이며 , 이때 pull 동작은 실패한다 .

40

How To : 파일 삭제 , 파일 명 변경

(1) 파일명을 변경 .(2) 파일을 삭제• SVN 과 마찬가지로 Git 는 파일명의 변경을 일일이 알려 주어야 한다 . 지우고 새로 만든 것인지 , 파일명만 변경되었는지 파악하지 못한다 .• 그래서 파일시스템의 rm, mv 를 사용하면 곤란하다 .

$ git mv old.txt new.txt (1)$ git rm useless.txt

(2)

41

How To : 로그 보기

(1) 최근 5 개의 리비전을 그래프로 보여준다 .(2) 저자가 dhrim 인 리비전을 5 개 보여준다 .(3) 주어진 기간내의 리비전만 보여준다 .(4) commit 메시지에 “ some message” 가 포함된 것만 보여준다 .

$ git log -5 --decorate --graph –oneline (1)

$ git log -5 --author=dhrim –oneline(2)

$ git log --before={3.weeks.ago} --after={2010-04-18} (3)$ git log --grep=“some message”

(4)

42

How To : commit 취소하기

(1) Local Repository 의 최신 commit 리비전을 바로전 리비전(HEAD^) 로 설정한다 . Index 와 Work Space 는 건드리지 않는다 .

$ git reset --soft HEAD^ (1)

43

How To : 특정 리비전 다운 받기

(1) 새로운 브랜치 ‘ new’ 를 생성하고 그 곳에 리비전 ‘ a1b2c3’ 을 내려받는다 .

$ git checkout –b new a1b2c3(1)

44

How To : 매뉴얼 보기

(1) stash 명령에 대한 man 페이지를 보여준다 .(2) 위 (1) 명령과 동일한 액션을 취한다 .

$ git help stash(1)

$ man git-stash(2)

45

How To : GitHub 에 브랜치 만들기

• GitHub 에서의 branch 는 지금껏 얘기한 것과 약간 다른 용도로 사용됩니다 . 대표적인 것이 release 를 위한 branch 이죠 . SVN에서의 branch 와 tag 의 용도와 거의 유사합니다 .• linux 상에서도 만들 수 있는 것 같은데 web 으로 만드는 것을 설명합니다 .

46

How To : GitHub 에 브랜치 만들기

• ‘Forks’ 아이콘을 클릭합니다 .

47

How To : GitHub 에 브랜치 만들기

• ‘Fork Queue’ 탭을 클릭합니다 .

48

How To : GitHub 에 브랜치 만들기

• ‘change it’ 을 클릭합니다 .

49

How To : GitHub 에 브랜치 만들기

• ‘create a new branch’ 에 새 브랜치의 이름을 입력하고 ‘ change branch’ 버튼을 클릭합니다 .

50

How To : GitHub 에 브랜치 만들기

• 브랜치 리스트에 생성한 new_branch 가 보입니다 .

51

Reference• git 홈 : http://git-scm.com/• 한글과 그림으로 설명 . 길지 않음 . : http://

kimseunghyun76.tistory.com/116• SVN 과 비교한 설명 : https://

git.wiki.kernel.org/articles/g/i/t/GitSvnCrashCourse_512d.html• 무엇 무엇 하기로 정리된 . 한글 : http://

poongcha.blogspot.com/2009/06/git.html• 자세한 . 그러나 긴 . 한글 : http://shinji.springnote.com/pages/2055296• 브랜치의 활용을 설명한 . 한글 : http://

dalinaum-kr.tumblr.com/post/15516936704/git-work-flow• Git 공식 reference : http://gitref.org• 치트시트 모음 : http://devcheatsheet.com/tag/git/• 추천 online 치트시트 . html :

http://ndpsoftware.com/git-cheatsheet.html#loc=local_repo;