Git branch + merge 사용하기 예제

|

Git의 branch 및 merge에 대해 공부한 내용을 예제를 통해 설명하고 요약해봅니다.(With SourceTree)
잘 설명된 원본 내용은 아래 링크를 참고하세요
Git 브랜치 - 브랜치와 Merge의 기초

Branch 생성

보통 프로그램의 별도 기능을 작성하거나, Bug,Issue 등을 따로 처리할 경우 사용하게 됩니다.

예를 들어 다음과 같이 생성된 프로젝트가 있습니다.

$ git init   
$ echo 'v1' > origin.txt    
$ git add .    
$ git commit -m 'v1'    

SourceTree를 통해 그래프를 보면 master노드에 ‘v1’ 내용을 담은 origin.txt 파일이 존재합니다.

step1

신규기능인 feature.txt 개발을 위해 branch를 생성후 파일을 만들어 commit합니다.

$ git branch feature1     
$ git checkout feature1
$ echo 'f1' > feature.txt
$ git add .
$ git commit -m 'f1'    

step2

위와 같이 feature1이라는 branch가 생성되고 feature.txt가 ‘f1’내용으로 개발된 것을 볼 수 있습니다.
다시 master 노드로 돌아가 origin.txt를 ‘v2’로 변경해 봅니다.

$ git checkout master
$ echo 'v2' > origin.txt
$ git commit -a -m 'v2'

step3

이제 좀 더 branch 가지가 분명하게 보이기 시작했습니다.

Master노드에 Merge

feature1 branch의 기능 개발이 끝났으니 master에 merge 해보도록 하겠습니다. master에 feature1 branch 내용을 가져올 예정이니 실행은 master 노드에서 해야합니다.

$ git checkout master
$ git merge feature1 -m 'merge f1'   

step4

위와 같이 master노드와 feature1 branch노드가 merge되었습니다.

Reset으로 되돌리기

이번엔 노드간 충돌예제를 만들어 보기 위해 merge전으로 다시 돌아가 보겠습니다.
reset 명령을 사용합니다. reset관련 정보는 아래 링크를 참고하세요
Git 도구 - Reset 명확히 알고 가기

$ git reflog
8ee26d8 HEAD@{0}: merge feature1: Merge made by the 'recursive' strategy.
9e75da8 HEAD@{1}: commit: v2
23fa160 HEAD@{2}: checkout: moving from feature1 to master
73aa9b3 HEAD@{3}: commit: f1
23fa160 HEAD@{4}: checkout: moving from master to feature1
23fa160 HEAD@{5}: checkout: moving from feature1 to master
23fa160 HEAD@{6}: checkout: moving from master to feature1
23fa160 HEAD@{7}: commit (initial): v1

git reflog명령을 통해 히스토리를 확인할 수 있습니다. ‘v2’를 commit한 ‘HEAD@{2}’ 시점으로 돌아가 보겠습니다.

$ git reset --hard HEAD@{2}

reset의 옵션은 아래와 같습니다.

옵션 설명
–soft Repository이력만 되돌립니다.
[–mixed] Stage영역까지만 되돌립니다.
–hard Working Directory까지 되돌립니다.

위와 같이 hard옵션으로 되돌리고 SourceTree를 확인해보면 다시 merge전으로 돌아온 것을 확인할 수 있습니다.

step5

Merge 충돌 해결하기

master노드와 feature1 branch노드간의 충돌을 만들기 위해 origin.txt파일을 수정해보겠습니다.

$ git checkout feature1
$ echo 'v2-f1' > origin.txt
$ git commit -a -m 'conflict origin.txt'

step6

master노드와 feature1 branch노드의 origin.txt파일이 각각 달라졌습니다. 이제 merge를 합니다.

$ git checkout master
$ git merge feature1 -m 'conflict merge'
Auto-merging origin.txt
CONFLICT (content): Merge conflict in origin.txt
Automatic merge failed; fix conflicts and then commit the result.

origin.txt파일의 내용을 merging하다가 충돌이 나있는 상태입니다.

step7

충돌난 내용은 위와 같이 구분하여 표시되고 위 내용을 알맞는 값으로 변경한 후 다시 commit하면 merge가 완료됩니다.

$ git add .
$ git commit -m 'finished merge'

step8

Git 기초

|

Git의 기초에 대해 정말 잘 설명되있는 페이지를 읽고 요약만 정리하고자 합니다. 원본은 아래링크를 참고하세요.
시작하기-Git-기초

SVN vs Git

SVN은 Commit 시점에 변화된 파일만 관리합니다.
SVN-Flow

Git은 Commit 시점의 스냅샷을 관리합니다. 변화되지 않은 파일도 해당 스냅샷의 링크로 저장합니다. Git-Flow

Git 특징

  • 거의 모든 명령을 로컬에서 실행합니다.
  • 데이터를 저장전 SHA-1 해시를 구하고 그 체크섬으로 데이터를 관리합니다.(무결성)
  • Commit한 데이터는 추가하기만 하고 삭제하지 않습니다.

Git의 저장구조, 상태, 상태전이

git 명령어에 따른 상태전이표입니다.

Git-Structure

상태 설명
Modified 작업 폴더에서 수정후 Stage에 올리지 않은 상태
Staged 수정한 파일을 Stage에 올려 Commit할 스냅샷을 만든 상태
Committed Stage의 파일을 git 저장소에 commit한 상태

예제

아래 명령어를 통해 두 파일을 저장소에 만들었습니다.

$ echo 'v1' > 1.txt | echo 'v1' > 2.txt
$ git add 1.txt
$ echo 'v2' > 1.txt

git status로 현재 저장소의 상태를 볼 수 있습니다.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   1.txt

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:   1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        2.txt

1.txt는 새로 생성되어 ‘v1’이란 내용으로 stage에 올라가 있는 상태이고 로컬엔 ‘v2’로 수정되었습니다.
2.txt는 새로 생성되어 아직 로컬에만 있는 상태로 ‘Untracked files’로 표시됩니다.

위 상태에서 stage의 1.txt파일을 unstage하려면 git reset HEAD 1.txt로 실행가능합니다.
위 상태에서 1.txt의 내용을 다시 ‘v1’으로 돌리려면 git checkout 1.txt로 실행가능합니다.

1.txt를 commit하고 나머지 파일을 stage에 올린 후 1.txt를 다시 수정해보겠습니다.

$ git commit -m '1.txt commit'
$ git add .
$ echo 'v3' > 1.txt

다시 상태를 보면 아래와 같습니다.

$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   1.txt
        new file:   2.txt

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:   1.txt

현재 1.txt의 각 내용은 저장소별로 아래와 같습니다.

Working Directory Staging Area Git Repository
v3 v2 v1

git diff 명령을 통해 아래와 같이 확인할 수 있습니다.

$ git diff 1.txt
diff --git a/1.txt b/1.txt
index 8c1384d..29ef827 100644
--- a/1.txt
+++ b/1.txt
@@ -1 +1 @@
-v2
+v3
warning: LF will be replaced by CRLF in 1.txt.
The file will have its original line endings in your working directory.

$ git diff HEAD 1.txt
diff --git a/1.txt b/1.txt
index 626799f..29ef827 100644
--- a/1.txt
+++ b/1.txt
@@ -1 +1 @@
-v1
+v3
warning: LF will be replaced by CRLF in 1.txt.
The file will have its original line endings in your working directory.

(vi 명령어) 알아두면 유용한 set 명령어

|

vi 편집기 사용시 알아두면 좋을 set 명령어를 요약해 보았습니다.
자주 쓰는 명령어는 계정의 home 디렉토리에 “_vimrc” 라는 파일을 만들고 set 옵션 내용을 저장하면 vi편집기 실행시마다 자동으로 적용됩니다.

명령어 축약 설명
:set ignorecase :set ic 검색/치환시 대소문자를 구분하지 않습니다.
:set number :set nu 문서에 줄 번호를 보여줍니다.
:set showmatch :set sm 괄호 입력시 자동으로 대응되는 괄호를 표시해줍니다.
:set autoindent :set ai 자동으로 들여쓰기를 합니다.
:set hlsearch   검색한 단어를 하이라이팅 합니다.

(vi 명령어) 문자열 치환하기

|

세미콜론을 입력 후 아래 명령어를 통해 내용 치환이 가능합니다.

:[range]s/old/new/[option]

위 영역별 옵션은 아래와 같습니다.

range

커맨드 설명 예제
s 현재 행에서 치환 :s/old/new/
%s 모든 행에서 치환 :%s/old/new/
.,$s 현재부터 끝까지 치환 :.,$s/old/new/
D1,D2s D1 ~ D2행까지 치환 :10,20s/old/new/
-N,+Ms 현재 커서위치 기준으로 -N ~ +M행까지 치환 :-3,+5s/old/new/
g/pattern/s pattern에 해당하는 모든 행을 치환 :g/veryold/s/old/new/

old 영역은 정규표현식을 사용가능하며 new영역은 바뀔 내용을 씁니다.

old

vi에서 지원하는 old영역 정규표현식은 아래와 같습니다.
※ vim에서는 좀더 많은 정규표현식을 지원합니다.

표현식 기능 예제코드 변경케이스
. 문자 하나 :s/t.e/XXX/ the -> XXX
there -> XXXer
* 0개이상 문자 :s/t*e/XXX/ the -> XXX
test -> XXXst
^ 시작 :s/^The/XXX/ The test -> XXX test
test The -> test The
$ :s/$The/XXX/ The test -> The test
test The -> test XXX
\ escape 문자 :s/\[test\]/XXX/ [test] -> XXX
[] 대괄호 안의 문자중 하나 :s/[a-z]*1/XXX/ test1 -> XXX
\{n,m\} 문자 반복횟수가 n ~ m개인 가능한 많은 문자와 매칭
\{n,\} \{,m\} 과 같이도 사용 가능
:s/b\{2,3\}/x/g ababbabbba -> abaxxaxxxa
\{-n,m\} 문자 반복횟수가 n ~ m개인 가능한 적은 문자와 매칭
\{n,\} \{,m\} 과 같이도 사용 가능
:s/b\{2,3\}/x/g ababbabbba -> abaxxaxxxa
\(\) 괄호안의 패턴을 1~9까지 버퍼에 저장, new영역에서 사용 :s/\(aaa\)\(bbb\)/\2\1/ aaabbb -> bbbaaa
\<\> 문자의 앞뒤를 매칭 시킴 :s/\<The\>/XXX/ The There -> XXX There

\{n,m\}\{-n,m\}의 차이는 가능한 많이 / 가능한 적게 적용하는 것입니다.
예를 들어
x xx xxx xxxx xxxxx
와 같은 문장을 치환 하면 아래와 같습니다.
:s/x\{2,\}/y/ -> x y y y y
:s/x\{-2,\}/y/ -> x y yx yy yyx

new

new영역에서의 교체패턴은 아래와 같습니다.

표현식 기능 예제코드 변경케이스
\d \(\)로 지정된 d번째 버퍼를 사용 :s/\(aaa\)\(bbb\)/\2\1/ aaabbb -> bbbaaa
\ escape 문자 :s/test/\[test\]/ test -> [test]
& 찾기패턴 :s/test/_&_/ test -> test
~ 이전 교체패턴을 사용 :s/aaa/xxx/
:s/bbb/_~_/
aaabbb -> xxxbbb -> xxxxxx
\u 교체패턴의 첫문자를 대문자로 변경 :s/aaa/\ubbb/ aaa -> Bbb
\U 교체패턴의 모든문자를 대문자로 변경 :s/aaa/\ubbb/ aaa -> BBB
\l 교체패턴의 첫문자를 소문자로 변경 :s/AAA/\uBBB/ AAA -> bBB
\L 교체패턴의 모든문자를 대문자로 변경 :s/AAA/\uBBB/ AAA -> bbb

option

옵션 설명
g 한 줄 내의 모든 패턴 변경
i 대소문자 구분 안함
c 변경여부 확인

(vi 명령어) 라인번호(줄번호) 보기, 라인이동, 맨위/맨밑 이동

|

vi 편집기에서 라인을 자유롭게 이동하기 위한 몇 가지 커맨드들을 외워둡시다.

기능 커맨드
라인번호(줄번호) 보기 :set number
라인이동 숫자입력후 Shift + g
맨위 이동 gg
맨밑 이동 Shift + g, :$

라인보기