git: a motivating introduction

Post on 21-Jan-2018

146 Views

Category:

Software

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Git : A Motivating introduction

Jongwook Choi

2013. 10. 25.

A distributedversion control system.

/bin/cpCVS

SubversionMercurial

Git…

• GIT 을 간략하게 소개합니다.

• 프로젝트에서 git을 사용해서 효과적인 작업을 할 수있었으면 좋겠어요.

• 컨셉, 사용법, 실전 전략들 모두…

About this seminar.

• GIT 을 간략하게 소개합니다.

• 프로젝트에서 git을 사용해서 효과적인 작업을 할 수있었으면 좋겠어요.

• 컨셉, 사용법, 실전 전략들 모두…는 할 수 없어요ㅠㅠ

About this seminar.

이미 세상에는 수많은 git 관련 입문 자료들이 있지만..

어려워요읽어도이해가잘안가요

도구를 차근차근 배우기에는 시간이 많이 없어요

-­‐-­‐ main  porcelain  command  -­‐-­‐add                      -­‐-­‐ add  file  contents  to  indexam                        -­‐-­‐ apply  patches  from  a  mailboxarchive              -­‐-­‐ create  archive  of  files  from  named  treebisect                -­‐-­‐ find,  by  binary  search,  change  that  introduced  a  bugbranch                -­‐-­‐ list,  create,  or  delete  branchesbundle                -­‐-­‐ move  objects  and  refs  by  archivecheckout            -­‐-­‐ checkout  branch  or  paths  to  working  treecherry-­‐pick      -­‐-­‐ apply  changes  introduced  by  some  existing  commitscitool                -­‐-­‐ graphical  alternative  to  git  commitclean                  -­‐-­‐ remove  untracked  files  from  working  treeclone                  -­‐-­‐ clone  repository  into  new  directorycommit                -­‐-­‐ record  changes  to  repositorydescribe            -­‐-­‐ show  most  recent  tag  that  is  reachable  from  a  commitdiff                    -­‐-­‐ show  changes  between  commits,  commit  and  working  tree,  etc.fetch                  -­‐-­‐ download  objects  and  refs  from  another  repositoryformat-­‐patch    -­‐-­‐ prepare  patches  for  e-­‐mail  submissiongc                        -­‐-­‐ cleanup  unnecessary  files  and  optimize  local  repositorygrep                    -­‐-­‐ print  lines  matching  a  patterngui                      -­‐-­‐ run  portable  graphical  interface  to  gitinit                    -­‐-­‐ create  empty  git  repository  or  re-­‐initialize  an  existing  onelog                      -­‐-­‐ show  commit  logsmerge                  -­‐-­‐ join  two  or  more  development  histories  togethermv                        -­‐-­‐ move  or  rename  file,  directory,  or  symlinknotes                  -­‐-­‐ add  or  inspect  object  notespull                    -­‐-­‐ fetch  from  and  merge  with  another  repository  or  local  branchpush                    -­‐-­‐ update  remote  refs  along  with  associated  objectsrebase                -­‐-­‐ fasforward-­‐port  local  commits  to  the  updated  upstream  headreset                  -­‐-­‐ reset  current  HEAD  to  specified  staterevert                -­‐-­‐ revert  existing  commitsrm                        -­‐-­‐ remove  files  from  the  working  tree  and  from  the  indexshortlog            -­‐-­‐ summarize  git  log  outputshow                    -­‐-­‐ show  various  types  of  objectsstash                  -­‐-­‐ stash  away  changes  to  dirty  working  directorystatus                -­‐-­‐ show  working-­‐tree  statussubmodule          -­‐-­‐ initialize,  update,  or  inspect  submodulestag                      -­‐-­‐ create,  list,  delete  or  verify  tag  object  signed  with  GPG

http://www.insightforums.com/how-to-educate-your-customers-and-win-fans-for-life/

그래서튜토리얼 등을 보다 쉽게 소화하실 수 있도록,

당장 프로젝트에서 git을 아쉬운 대로 사용할 수 있도록그리고 git을 쓰면 도대체 무엇이 좋은지

기능 보단 핵심 개념 위주로간략히 짚어보도록 하겠습니다.

Core Concepts

저장소 repository

저장소 repository

버전관리의 대상이 되는컨텐츠/파일들이 모여 있는 곳

SVN은 저장소가 서버에 하나 있고

SVN은 저장소가 서버에 하나 있고

개발자가 자신의 PC에working copy를 내려받아 작업합니다.

그런데 Git은저장소가 내 컴퓨터에 있어요.

로컬 저장소(local repository)

협업을 위해서는 원격 저장소와 따로 동기화하는 작업이 필요해요.

로컬 저장소(local repository)

작업 사본(working copy)

원격 저장소

이렇게 저장소가 복제되고분산된 형태로존재할 수 있기 때문에, DVCS (distributed VCS) 라고 해요.

http://nvie.com/posts/a-successful-git-branching-model/

어쨌거나, 저장소는 ‘히스토리’를 저장합니다.

커밋 commit

어떤 한 시점에서의 저장소의 스냅샷.이력 변경의 단위

커밋 = 스냅샷

SVN에서는 r1, r2, r3, … 이렇게 커밋마다순차적으로 증가하는 revision이 달립니다.

대신, GIT에서는 하나의 커밋이 리비전 번호 대신SHA-1 해쉬 ID로식별됩니다.

Commit ID : SHA-1 Hash

2670d94c6abf07e787efcd1867fafc86f62b6fac

혼동이 없다면 보통 앞 7~8글자를 따서‘2670d94c’ 이렇게 간단히 부르기도해요.

그러면 순서를 어떻게 유지할까요?두 커밋이 있을 때 누가 더 나중 버전일까요?

commit은 스냅샷을 포함하여 여러가지 정보를 저장하는데이 중 바로 전의 commit을 parent commit으로 저장합니다.

부모 커밋 이 커밋의더 오래된 커밋

이렇게 커밋들이 모여 연결리스트와 유사하게‘그래프’를 이루어서 history를 유지합니다.

코딩을 한 뒤변경사항을 저장(커밋)하면새로운 커밋이 만들어집니다.

인덱스 index (stage area)

현재 커밋하고자 하는 내용(변화)들을 저장하는 곳

http://marklodato.github.io/visual-git-guide/index-en.html

코드에서 오타를 간단히 수정하는 커밋을 추가합시다.에디터를 열어 코드를 수정합니다.

git status : 어떤 파일이 변경되었는지 정보를 보여줍니다.

커밋할 내용(또는 파일)을 stage 영역에 추가합니다.(git add README.md)

README.md 를 커밋할 준비가 되었습니다.

other.txt 는 수정되었지만 커밋하지 않아요

커밋합니다.(git commit)

도대체 인덱스 개념은 왜 있을까요?

• 원하는 부분만을 커밋하여, 하나의 커밋은 독립적인 하나의 변화만을 포함해야 한다는 버전 관리의 원칙을지킬 수 있도록 도와줍니다.

Issue #1: Implement an add function.

http://www.mfranc.com/uncategorized/git-git-gui-staging-selected-lines/

도대체 인덱스 개념은 왜 있을까요?

코드를 수정하다보면같이 수정은 했는데 부득이하게지금 커밋하기는 곤란한일들이 생길 수 있어요.

만약 SVN이었다면,- 현재 파일을 어디 다른 곳에 임시 백업해두고- commit할 상태로 파일을 만들어서 커밋을 한 뒤- 다시 백업해둔 파일로 복구해야 할거에요. 아 귀찮아…

귀찮아요.인덱스를 생략하는 것도 가능합니다.

• git commit -a 명령을 사용합니다.• TortoiseGIT 등의 일부 클라이언트는 인덱스 개념이 없어서,

SVN처럼 바로 변경된 파일을 커밋하도록 만들어 놨어요.

브랜치 branches

Git의최대 장점은,브랜치 연산이 매우 자유롭다는 것입니다.

브랜치 branches

저장소 이력의 서로 다른 갈래 또는 분기.

• 아직 완료되지 않은 기능이라서 main 줄기에반영하기는 좀 그런데 커밋과 이력 관리는 해야할 때

• 1.3 버전 개발이 진행중인데 갑자기 1.2 버전에서 발견된 버그를 핫픽스 해야할 때

• 두 명의 개발자가 서로 다른 기능을 동시에독립적으로 개발하고 싶을 때

• …

SVN에서는 디렉토리를 통째로 복사하여 논리적으로 브랜치를 운영할 수있었습니다.

http://www.snipe.net/2009/03/getting-started-with-subversion-part-two/

merge? 지옥이 따로 없습니다.

master 브랜치

testing 브랜치

GIT에서, 브랜치는 단순히어떤 커밋을 가리키는 이름 (named reference) 입니다.

master 브랜치

각 브랜치에서 작업할 때, 커밋을 추가하여 독립된 이력을 만들수 있고 브랜치를 자유롭게 왔다갔다할 수 있어요.

HEAD는 현재 working copy의 base가되는 커밋이나 브랜치를 의미합니다.

(git checkout)

브랜치 머지(merge)하기.

hotfix 브랜치의 변경내역을 master 브랜치에 merge합시다.(master)$ git merge hotfix

master가 hotfix의조상이므로,master브랜치의 포인터만 앞으로 옮기면 됩니다. (fast-forward)

iss53 브랜치의 변경내역을 master 브랜치에 merge합시다.(master)$ git merge iss53

안되잖아?

이때는 두 브랜치가 가리키는 커밋의 공통 조상을 찾아

master에합치는거에요

이때는 두 브랜치가 가리키는 커밋의 공통 조상을 찾아새로운 커밋(merge commit)을 만듭니다. (non-fast-forward)

master브랜치가가리키는커밋이앞으로이동합니다.

머지커밋

이런 merge commit들은둘 이상의 부모 커밋을 갖습니다.

히스토리를 봤을 때도 브랜치가 언제 뻗어나와서언제 어디로 머지되었는지가 명확하게 남습니다.(이력추적을위해 blame 해보면실제로변경된시점을찾을수 있어편리합니다)

Merge branch ‘iss53’ into ‘master’

한가지 중요한 일이 남았습니다.이제껏 로컬에 작업한 내용들을 서버에 업데이트하거나, 남들과 코드를 공유하고 싶습니다.

GIT 서버 저장소 (remote repository)

내 저장소

git.mycompnay.com/project-­‐a/test-­‐repo.git

각 개발자는 중앙 저장소를 clone한 사본인로컬 저장소(local repository)에서 작업합니다.

git clone

GIT 서버 저장소 (remote repository)

git.mycompany.com/project-­‐a/test-­‐repo.git

git clone  git.mycompany.com/project-­‐a/test-­‐repo.git

GIT 서버 저장소 (remote repository)

이 때, 원격 저장소(origin)에 존재하는 브랜치들을원격 브랜치(remote branch)라고 부르고, 구별하기 위해 로컬저장소의 브랜치를 local branch라고 부릅니다.‘origin/master’ 등의 이름으로 브랜치를 나타냅니다.

이제 몇 가지 작업을 진행해서 커밋을 추가합니다.

GIT 서버 저장소 (remote repository)

git.mycompany.com/project-­‐a/test-­‐repo.git

어떤 브랜치를 원격 저장소에 올리는 것을 푸시(push)라고 합니다.

GIT 서버 저장소 (remote repository)

git push origin master

git.mycompany.com/project-­‐a/test-­‐repo.git

새로 추가한 커밋들이 원격 저장소에도 추가되고,원격 저장소의 master 브랜치가 앞으로 이동합니다.

git push origin master

반대로 다른 사람이 작업한 것을 받아올 수도 있습니다. (fetch)

git.mycompany.com/project-­‐a/test-­‐repo.git

git fetch origin

중앙 GIT 저장소 서버

git fetch origin

git.mycompany.com/project-­‐a/test-­‐repo.git

원격 저장소에 있는 커밋들과 브랜치를 가져오고,origin/master 등의 remote branch가이동(동기화)됩니다.

이 때 로컬 브랜치는 변화하지 않았습니다.

마지막으로 master에 origin/master를 merge 하면 됩니다.(이 때는 merge commit을 만들지 않는 fast-forward를합니다)

그런데, 나의 작업을 push하려고 할때,이미 남이 먼저 push했다면 오류가 발생합니다.

머리가 아파옵니다.

중앙 GIT 저장소 서버

Fast-forward 가안되기 때문에 push가 실패합니다.

원격 저장소에 push하려면,브랜치를 앞으로 당기는 fast-forward가가능해야 합니다.

다른 사람들이 작업한 내용을 먼저 받아야 합니다.merge 나 rebase 작업이 필요합니다.

중앙 GIT 저장소 서버

git fetch

master 브랜치에, 'origin/master' 브랜치를 merge합니다.

이건 로컬에서내가 만든 커밋이고

이건 다른 사람이 먼저 푸시한 커밋이에요

master 브랜치에, 'origin/master' 브랜치를 merge합니다.(git merge origin/master)

이 때, 보통 아래와같은커밋메시지가만들어집니다.Merge remote-tracking branch ‘origin/master’ into ‘master’

이렇게 합치고 난뒤, push 하면 됩니다.

이제 origin/master 브랜치의 입장에서는fast-forward가가능하므로 push가 성공합니다.

서로 다른 사람이 동시에 커밋을 만들면

자동으로 브랜치가 갈라집니다.

뭔가 복잡한 것 같아요.

Fetch & Merge를 함께 해주는 Pull 명령도 있습니다.그러나 fast-forward가 안 되는 경우 의도하지않은merge commit이생겨버릴 수 있어 조심해야 합니다.

기능이 나뉘어지는 부분이 없어서 특별히 브랜치가 필요 없고단순히 코드를 공유하고 싶었을 뿐인데,쓸데없이 복잡한 히스토리가 만들어질 수 있어요.

히스토리를 (SVN처럼) 선형으로 만들 수는 없을까요?

rebasebase를 새로이 하다

사실 다소 어려운 개념일 수있지만,git의진가를 발휘하기 위해서 매우 유용한 기능입니다.

rebase: master와 origin/master의 작업 내용을 합치되(머지하지 않고) fast-forward가 가능하도록 만들고 싶어요.

이건 로컬에서내가 만든 커밋이고

이건 다른 사람이 먼저 푸시한 커밋이에요

내가 추가했던 커밋을 origin/master (fbff5) 뒤로 옮긴 다음에..

내가 추가했던 커밋을 origin/master (fbff5) 뒤로 옮긴 다음에master 브랜치를 push하면 fast-forward가 가능하겠죠?

experiment 브랜치에서 작업하고있고, 커밋 C3은 C2에서 뻗어나왔어요. experiment를 master로 rebase하여, C3 커밋을 C4 뒤에다가얹고 싶습니다. ( (experiment)$ git rebase master )

Rebase란, 브랜치의 base를옮김으로써커밋 히스토리를 다시 쓰는 작업입니다. 좀 더자세히 살펴보아요.

rebasing : experiment(C3)과master(C4)의 공통조상(C2)을 찾아, experiment 브랜치에서 C2 이후의 커밋과 동일한 변경내역을 갖는 커밋을master(C4)의 뒤에 만들어 달고 experiment 브랜치를 이동합니다.

experiment 브랜치를 master 브랜치 위에 rebase 합니다.

여기서 C3' 은 C3과는 (변경 내역과 커밋 메시지는 같지만)다른새로운커밋입니다.(SHA-1 해시 ID가 다르다)

• 공통점 : 두 브랜치가합쳐진 상태(커밋)를만들어줍니다.• merge– 새로운 merge commit 을 만들되,기존의 commit 객체들을건드리지 않습니다.

• Rebase– 기존의 수정 내용이 담긴 commit을 ‘복제’해서다른 새로운 commi을만들어줍니다.

– 따라서 History를 일직선으로 깔끔하게유지할 수 있어요.

• 자세한 건 레퍼런스 참고 및 다음에…

rebase, merge 무엇이 다른가요?

뭔 소린지 잘 모르시겠다구요?아직 push하지 않은 커밋이 있는데, 이미 서버에올라온 변경내역을합쳐야 한다면git pull --rebase 를 사용하면 좋습니다.

다른 사람들과 코드 공유를 하기 위해 왜이리 복잡한 과정을 거쳐야 할까요?

자, 지금까지 git을 사용하여프로젝트를 진행하기위한최소한의 기본 개념들만살펴 보았어요.

아쉽게도 더 편리하고 강력한 기능들에대한 이야기는아직 꺼내놓지도 못했답니다…(?)

서버에 올리지 않고도, 로컬 저장소에서마음대로 실험하고테스트하고 여러가지 일을 할 수 있습니다.

• 중간/임시 커밋을 맘대로 할수 있습니다.• 작업이 완료되면 그 때커밋을 합치고 다듬어서 올릴 수 있습니다.• 때로는 올릴 필요가 없어지면 그냥 버려도 됩니다.

유연한Workflow 및 Code Review

그래서, 이제 뭘 어떻게 해야 하나요?

이제 튜토리얼을 보면 이해가 됩니다.직접 구르면서 몸으로 익힙니다.

Try Git : 15-minute introduction by github

http://try.github.io

Atlassian’s Git Tutorials

https://www.atlassian.com/git/tutorial/

Pro Git : the official book

http://git-scm.com/book/kohttp://dogfeet.github.io/progit/progit.ko.pdf

여기에 수록된 많은 git 관련 그림들은 pro-git (git-scm.com/book)에서 발췌했습니다.

Other References

• Git 간편 안내서• http://rogerdudler.github.io/git-guide/index.html• (KO) http://rogerdudler.github.io/git-guide/index.ko.html

• A Visual Git Guide• http://marklodato.github.io/visual-git-guide/index-en.html• (KO) http://marklodato.github.io/visual-git-guide/index-ko.html

• SVN 사용자를 위한 Crash Course• http://git.or.cz/course/svn.html

• Interactively learn Git Branching• http://pcottle.github.io/learnGitBranching/

어떤 Git 도구와 클라이언트를 사용하면 될까요?

• Git command-line shell

• Editors (vim : fugitive.vim, Sublime text : SublimeGit)• IDE (Eclipse : EGit, IntelliJ IDEA : idea-git)

어떤 Git 도구와 클라이언트를 사용하면 될까요?

TortoiseGit Atlassian SourceTree

Github and Bitbucket : Web Tools

https://github.comhttps://bitbucket.org

이것만은 기억해 주세요

commit = 스냅샷.

branch = commit 의 레퍼런스Git은 branch를적극적으로 만들고 활용하는 것을 좋아합니다.

merge, fetch, push

rebase : 커밋들을재정렬한다.

git pushgit pull --rebase

기회가 된다면 다음 시간에는,

• 사용하면 유용한 여러가지명령어와 팁• Rebase로 저장소 이력 주무르기• 협업 제대로 하기 : Workflow 및 브랜치 활용 전략• 개발이 아닌 다른 용도로 git 사용하기

THE END.

Thank You

top related