https://blog.lockcept.kr/61

 

Git 기본 (1) : init, status, add, commit, push, track

Git을 대충 사용 할 줄은 알았지만, Git의 근본 원리부터 완벽히 알지는 못하여서 공부를 하며 알게된 점에 대해 포스팅을 작성하고자 한다. 아직 정리하여 글을 작성하지 못하여서 일단 정보를 최대한 기록한 뒤..

blog.lockcept.kr

 

기존의 Git 글에 이어서 branch, checkout, merge, diff, pull & fetch 에 대해 작성하도록 하겠다.

 

 

기존 글의 마지막 상태이다. 현재 master branch 위에 있다.

 

 

1. branch

 

branch는 마지막 커밋을 가리키는 포인터 이다.

그리고 각각의 커밋은 자신의 부모 커밋을 가리킨다.

현재 master branch는 특정 커밋을 가리키고 있을 것이다.

 

git branch 명령어를 사용하면 현재 branch 목록을 볼 수 있다. -r, -a 옵션을 통해 remote, all branches 를 볼 수 있다.

 

git branch new-branch old-branch 를 통해 새 브랜치를 만들 수 있고, 기존 브랜치와 같은 commit 을 가리킨다.

 

위의 예시에서는 git branch test master 를 통해 test 라는 이름의 브랜치를 생성하였으며 master branch 가 가리키고 있던 commit 을 가리키게 된다.

 

git branch -m 옵션으로 이름을 변경할 수 있으며, git branch -m test lockcept 이후 git branch 로 확인하자 test가 lockcept이 되어있는 모습이다.

 

git branch -d 옵션을 사용하면 branch를 delete 할 수 있다.

 

 

2. checkout

 

checkout 옵션은 내가 지금 작업할 branch를 변경하는 목적이다.

단순히 git checkout master 를 사용하면 master branch로 현재 작업 branch (HEAD) 를 변경하게 된다.

-b 옵션을 같이 사용하면 branch를 만들면서 checkout 한다. 이미 존재하면 불가능 한데, -B를 사용하면 reset 하며 이동한다.

 

-t 옵션은 기존에 언급했던 track 개념으로, git checkout -t origin/master 를 사용하면 원격 저장소 origin의 master 브랜치와 연결된 local branch master를 생성한다.

위의 예제에서는 master가 이미 존재하여 실패하였다.

-b 옵션을 추가하여 새 브랜치를 생성하며 track할 수도 있다. 위 그림의 abc branch와 같다.

 

 

3. merge

 

merge를 설명하기에 앞서, 위의 명령어들을 사용하여 branch a, b를 만들고

a branch에는 수정된 a.txt를 commit

b branch에는 추가된 b.txt를 commit

하였다.

 

 

 

merge는 두 branch를 병합하여 새로운 commit을 만든 후, 부모로 두 branch의 마지막 commit를 가리키게 한다.

만약 두 branch가 포함관계라면 fast-foward 라는 방식을 통해 새로운 commit이 생기지 않게 할 수도 있다.

 

b의 위치에서 a를 merge하면 a를 가져와 b에 붙이는 것이다.

merge 이후 log를 보면 최종 commit이 존재하고 (commit message는 merge 할 때에 변경 가능)

 

두 부모 d7acaef, 4f14126을 가진다.

 

 

4. diff

 

diff는 두 커밋, 혹은 두 브랜치의 차이점을 보기 위한 명령어이다.

git diff a b 를 통해 두 branch의 차이점을 확인 할 수 있다.

commit 간의 차이점을 확인하기 위해서는 hash 값을 적어주면 된다.

git diff HEAD^ HEAD는 HEAD^ (HEAD 직전 commit)과 HEAD의 차이를 보여준다.

 

 

5. git pull & fetch

 

git pull 은 전에 소개한 git push 의 반대 개념이다.

원격 저장소의 branch를 가져와 local 저장소의 branch에 merge 한다.

이때 branch를 가져오는 과정이 fetch이다. fetch는 원격 저장소의 branch를 가져오기만 하고, merge 하지 않는다.

 

pull은 정확히 fetch & merge 활동이다.

 

 

이렇게 Git의 기본적인 명령어들을 알아보았다.

배달의 민족 (우아한 형제들) 기술 블로그에서 Git Flow의 존재에 대해 알게 되고 간단하게 공부 및 사용 해보았다.

 

http://woowabros.github.io/experience/2017/10/30/baemin-mobile-git-branch-strategy.html

 

 

 

Git Flow는 Git을 사용하는 브랜칭기법 중 하나로 여러 개발자가 하나의 프로젝트를 개발하기 위해서 만든 브랜칭 규칙 및 모델이라고 보면 된다.

 

Git Flow는 크게 Master, Develop, Feature, Release, Hotfix로 구분된다.

 

Master : 언제든지 출시할 수 있는 상태의 브랜치

Develop : 개발자들이 주로 개발을 하게 되는 근본 브랜치

Feature : 개발자들이 하나의 기능을 추가하고 싶을 때 Develop으로부터 생성하여 작업 후 Develop으로 Merge한다.

Release : 출시 전 검사를 하기 위한 브랜치. Develop에서 생성하여 BugFix를 진행한 후 Master로 Merge 및 Develop 으로 Back Merge 한다.

Hotfix : Master에서 버그가 발생하였는데 Develop에서 다음 버전을 위한 패치가 진행 중일 경우 Master에서 생성하여 빠르게 버그 수정 후 Master로 Merge 한다.

 

 

아래는 간단한 Git Flow의 예제이다.

 

 

Linux에서 apt-get install git-flow를 통해 설치하여준다.

 

 

이미 존재하는 git 저장소에 git flow init 을 하면 git flow의 형태를 만들어 준다.

이 때 -f를 사용하면 이미 git flow가 존재하더라도 강제하여 만든다.

 

 

원래 master, develop 등 branch들의 이름을 설정할 수 있는데 -d를 사용하면 default 상태로 설정해준다.

 

 

git flow 사용법은 기본적으로 다음과 같다.

 

git flow <feature/release/hotfix> <start/finish> <name>

 

git flow feature start addtxt 를 통해 feature/addtxt  branch를 만들었다.

 

이후 사진에는 없지만 a.txt를 추가한 후 commit, git flow feature finish addtxt를 통해 develop에 merge하였다.

 

 

릴리즈를 시작한 모습. 릴리즈는 주로 이름에 버전명을 사용한다.

 

 

릴리즈에 버그 픽스 commit을 추가한 후 log를 보면 위와 같다.

 

release 를 finish 하면 위에서 언급했듯 master에 merge, develop에 back-merge 하며 버전명을 master에 tag로 달아준다.

 

이 외에도 우아한 형제들의 블로그를 보면 원격저장소에서 git-flow를 어떻게 사용하면 좋을지 예시를 볼 수 있다.

Git을 대충 사용 할 줄은 알았지만, Git의 근본 원리부터 완벽히 알지는 못하여서

공부를 하며 알게된 점에 대해 포스팅을 작성하고자 한다.

 

아직 정리하여 글을 작성하지 못하여서

일단 정보를 최대한 기록한 뒤에 나중에 다른 사람도 편하게 읽을 수 있도록 순서를 재배치할 예정이다.

 

 

1. git init

 

폴더를 만들고 git init을 통해 git을 생성하였다.

파일 디렉토리는 리눅스 심볼릭 링크를 통해 생성하였다.

 

 

윈도우에서 폴더에 가보면 .git 폴더가 생성되어있고 안에 위의 내용이 들어있다.

 

 

이제 다시 원래 폴더로 돌아가서 a.txt를 만들고 저장하자.

 

 

 

2. git status

 

git status 는 현재 상황을 알려준다.

현재 master 브랜치에 있으며 별다른 커밋은 없고, 파일 중 a.txt 가 Untracked 상태이다.

 

따라서 이 파일을 commit 하기 위에 Stage 해주겠다.

 

3. git add

 

gid add a.txt

 

를 통해 파일을 Stage 하였고 다시 한번 git status 를 통해 상태를 확인해보니

아직 commit은 없지만  파일이 commit 되기 위해 기다리고 있다.

 

git add . 를 하면 해당 위치의 모든 파일이 add 된다. (git ignore 가 없을 경우)

 

 

작업 중에는 .git 폴더를 볼 일이 없지만, 공부를 위해 .git 폴더를 들어가보면

objects의 32 폴더 안에 8397c3 ~~ 의 파일이 생겼다.

 

이는 우리가 올린 a.txt가 328397c3 ~~의 SHA1 해시값을 가지기 때문이다.

 

앞의 두 자리는 폴더로, 뒤의 내용은 파일명으로 해서 내용을 가지게 된다.

 

 

4. git commit

 

git commit -m "add a.txt"

커밋을 추가하였고 메세지는 "add a.txt" 이다.

 

 

폴더 11과 폴더 95가 생겼다.

하나는 새로운 커밋을 나타내는 object 이고, 하나는 그 커밋이 포함하고 있는 파일들을 나타내는 tree object 이다.

 

 

진행중인 master branch를 켜보면 959c89....를 가지고 있으니 95 폴더에 있는 것이 commit일 것이다. 

 

 

5. git push

 

이제 원격 저장소에 푸쉬를 해보자. 원격저장소는 깃허브에 하나 만들어 두었다.

origin 이라는 이름에 깃허브 repo 링크를 연결시키기 위해

 

git remote add origin https://~~

 

를 사용하였다. 이후 git push로 push를 하려고 하자 branch 를 설정하지 않았다고 한다.

 

우선 git push origin master 로 branch 를 직접 지정해서 push 하였다.

깃허브의 아이디와 비밀번호를 입력하니 push가 완료되었다.

 

a.txt가 push 된 모습

 

 

이어서 git push 만으로 원격 저장소에 push 되도록 해보자.

로컬 branch 와 원격 branch 를 연결하는 방법에는 여러가지가 있다.

로컬 branch 를 생성할 때 부터 원격 저장소에서 checkout -b 를 이용하거나,

push -u 를 사용할 수도 있다.

위에서 사용 한 방법은 그냥 연결만 해주는 것이다.

 

git branch --set-upstream-to origin/master

 

를 사용 하면 연결이 된다.

이후 git push 하면 바로 원격 저장소에 올라가는 모습을 볼 수 있다. (everything up-to-date 지만)

 

이 관계를 삭제하려면 git branch --unset-upstream 하면 된다.

 

git branch -a 를 이용하여 모든 branch를 볼 수 있고,

git branch -r 을 이용하면 내 로컬 저장소에 있는 원격 브랜치만 볼 수 있다.

 

깃 공부를 하다가 궁금해져서 찾아보았는데, 짧게나마 포스팅으로 남겨서 기억하려고 한다.

 

로컬 저장소의 Branch는 크게 세 개로 나눌 수 있는데

Local Branch

Ref Branch

Remote Branch

 

이다.

이 중 Ref Branch 는 Remote Branch 를 로컬 저장소에 불러와서 캐시를 떠놓았다고 생각하면 편하다.

 

Ref Branch 만을 삭제할 일이 많지는 않겠지만, 만약 하고 싶다면 위의

git update-ref -d refs/remotes/origin/master (경로는 예시)

를 사용하면 된다.

+ Recent posts