Git을 사용하기 위한 기초 정리 2

ybear90·2020년 2월 13일
4

Git_fundamental

목록 보기
2/3

git branch의 개념 및 관련 명령어

소프트웨어 개발 프로젝트를 진행 하고자 할 때 한 명이서 모든 프로젝트를 전담해서 개발할 수 있다지만 대형 프로젝트 같은 경우엔 여러 개발자들이 모여서 그 역할을 나눠서 개발을 진행해야 한다. 개발 프로젝트를 해 나가며 서로 의논하에 맞춰서 진행하겠지만 각 부분을 나눠서 개발 할 경우 단일 이력에서 같은 선상에서 작업을 진행할 경우 서로에게 영향을 주게 되어 충돌 및 버그의 늪에서 헤어나지 못할 수 도 있다. 이를 예방하고 개발 프로세스를 효율적으로 만들어 나가기 위해 한 메인 스트림(master 브랜치)를 기준으로 가지를 쳐 내려가 한 프로젝트 내에서 각자의 개발 영역을 갖고 개발할 수 있게 하는 개념이 branch 다.

이 branch 개념에서 기준이 되는 줄기를 master branch라고 하며 이 branch에 checkout 한 다음 여기의 각 스냅샷 시점에 새로운 branch를 생성하여 작업을 하는데 이를 feature branch라고 한다.

feature branch에서 작업을 마치고 다시 master branch에 합치게 되는 과정을 merge 라고 한다.

(이미지 출처 : https://backlog.com/git-tutorial/kr/stepup/stepup1_5.html)

git branch 관련 명령어

branch 관련 명령어는 다음과 같이 정리 할 수 있다.

# branch 확인
$ git branch
(화면전환 후)
  feature/test
* master
(END)

# branch 만들기
$ git branch <branch-name>

# branch 삭제
$ git branch -d <branch-name>
<branch-name> 브랜치 삭제 (과거 adf9c1d).

# 만든 branch로 이동
$ git checkout <branch-name>
<branch-name> 브랜치로 전환합니다

branch에서 작업을 마치고 master branch에 PR하는 과정

$ git checkout feature/test
(test2.txt 수정 후)
$ git add test2.txt
$ git commit -m "branch commit/push test"
[feature/test 0f95c3f] branch commit/push test
 1 file changed, 1 insertion(+)
 create mode 100644 test2.txt
$ git push origin feature/test
오브젝트 나열하는 중: 4, 완료.
오브젝트 개수 세는 중: 100% (4/4), 완료.
Delta compression using up to 4 threads
오브젝트 압축하는 중: 100% (2/2), 완료.
오브젝트 쓰는 중: 100% (3/3), 290 bytes | 290.00 KiB/s, 완료.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'feature/test' on GitHub by visiting:
remote:      https://github.com/ybear90/git_test/pull/new/feature/test
remote:
To https://github.com/ybear90/git_test.git
 * [new branch]      feature/test -> feature/test

Create a full 밑줄에 언급된 주소로 가게되면 실제 pull request를 할 수 있게 되어 있고 master branch를 통해 실제 master branch에 반영된다.

오른쪽 아래에 보이는 Create pull request 버튼을 누르면 PR을 할 수 있다

master 브랜치에서 Merge pull request를 진행해 주면 실제 remote repository master branch에 반영되게 된다.

remote repository와 연동하여 local repository 최신화

이리하여 feature branch에서 작업한 내역을 master branch에 반영해 보는 테스트 까지 진행해 보았는데 이상한 점이 하나 있었다

$ ls -la
total 0
drwxr-xr-x   4 YB  staff   128  2 12 22:27 .
drwxr-xr-x+ 89 YB  staff  2848  2 12 22:28 ..
drwxr-xr-x  12 YB  staff   384  2 12 22:28 .git
-rw-r--r--   1 YB  staff     0  2 12 20:53 test.txt

local repository의 master branch에는 변경 사항이 적용이 되지 않았다 왜 그런 것일까 ? 답은 위에 명령어에 나타나 있다.

$ git push origin feature/test

실제로 master branch에 push를 진행했지만 local repository가 아닌 remote repository(origin/master)에 push를 한 것이다. 따라서 local repository에는 아직까지 push한 상황이 반영되지 않았을 뿐이다. 그래서

$ git pull origin master
오브젝트 묶음 푸는 중: 100% (1/1), 628 bytes | 628.00 KiB/s, 완료.
https://github.com/ybear90/git_test URL에서
 * branch            master     -> FETCH_HEAD
   adf9c1d..2a75c6f  master     -> origin/master
업데이트 중 adf9c1d..2a75c6f
Fast-forward
 test2.txt | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 test2.txt

위와 같이 pull을 이용하여 remote repo에서 최신 상태로 업데이트 해주면 push한 파일이 local에도 적용이 된다. 꼭 master branch가 아니더라도 다른 branch에서도 같은 방식으로 최신화가 가능하다.

git clone vs git pull 개념 및 차이점

  • git clone : 주로 git 저장소가 아닌 local에서 새롭게 프로젝트를 복제해 올 때 많이 쓰인다. 예외 없이 현재 remote repository에 특정 branch에 있는 모든 프로젝트 파일 일체를 복제해 온다.
  • git pull : git fetch + git merge 가 합쳐진 개념이며 주로 기존에 있던 local repository에서 remote repository와 연동 하여 최신 상태를 유지하고자 할 때 많이 쓰인다. 협업하거나 여러 곳에서 작업할 경우 작업 상태를 꾸준히 갱신하고자 할 때 많이 쓰인다.

git은 특정 커밋 시점을 기준으로 스냅샷의 형태로 각 버전별 데이터를 관리한다. 즉 변화된 파일들만 복제를 해 두고 그렇지 않은 파일들은 가장 마지막으로 바뀐 시점의 커밋에서 링크를 가져와 관리하는 방식이다. 이런 세부적인 원리로 git은 스냅샷의 형태로 버전별 파일들을 관리한다고 보면 된다.

이 개념을 토대로 생각해보면 git pull을 하더라도 모든 파일들을 다 가져올 때도 있고 local과 비교했을 때 변동 사항이 없는 파일에 대해선 가져오지 않기도 한다.

merge를 할 때 tree구조와 conflict가 발생하는 시점 및 해결 방법

git에서 branch라는 개념을 익혔고 어떤 방식으로 프로젝트를 발전시켜 가는지 또한 대략적으로 개념을 짚어 봤다. 그런데 항상 분기를 적시에 나눠서 협업하는 사람들에게 영향을 주지 않으면서 프로젝트를 진행 하려고 해도 항상 원활하게 진행 되지 않는다. 특히 같은 부분을 서로 나눠 구현하다가 겹치는 부분이 생기면 conflict 문제가 발생할 수 있는데 다음과 같은 상황을 가정해보자.

파란색 원은 master branch이고 빨간색과 노란색은 거기에서 파생된 각각의 branch 영역이라고 둔다. 먼저 노란색 branch 영역에서 파일 생성 후 commit을 하고 master branch에 merge를 진행하여 반영 시켜둔 상태에 같은 시점에 다른 빨간색 branch 영역에서 같은 파일에 같은 부분은 수정했고 이후에 master 브랜치에서 같은 부분을 수정하고 commit했을 때 conflict 에러가 발생하는 순간이 만들어 진다.

위 상황을 실습을 통해 정리해 보았다.

충돌을 일으킬 파일 하나를 master에서 생성 및 commit 후 각각의 yellow branch와 red branch에서 작업을 해 보겠다.

처음 파일을 열어보면 이렇게 생겨있다.

# conflict_test.py
def test1():
    pass

yellow branch로 전환한 다음 위 파일을 다음과 같이 수정하였고 add와 commit을 진행하였다.

$ git checkout -b yellow
$ vi conflict_test.py
# conflict_test.py
def test1(yellow):
  	pass
$ git commit -m "conflict_test.py yellow added."
[yellow 22323aa] conflict_test.py yellow added.
 1 file changed, 1 insertion(+), 1 deletion(-)

그리고 우선적으로 yellow 브랜치에서 commit 했던 내역을 master에서 merge를 진행해 주었다.

$ git merge yellow
업데이트 중 dfcdb42..22323aa
Fast-forward\
 conflict_test.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

이제 red 브랜치로 전환하여 같은 부분을 아래와 같이 수정해 주고 add, commit을 하였다

# conflict_test.py
def test1(red):
  	pass
# commit -am <- add와 commit 을 한번에 가능하게 해주는 명령어
$ git add conflict_test.py
$ git commit -am "conflict_test.py red added."
[red 1f7227d] conflict_test.py red added.
 1 file changed, 1 insertion(+), 1 deletion(-)

그와 동시에 master 브랜치에서 red의 결과물을 합쳤을 때 충돌(conflict)이 발생하였다

$ git checkout master
$ git merge red
CONFLICT (add/add): Merge conflict in conflict_test.py
자동 병합: conflict_test.py
자동 병합이 실패했습니다. 충돌을 바로잡고 결과물을 커밋하십시오.

충돌난 파일을 열어보면 아래와 같이 나오게 되는데 현재 checkout한 브랜치에서 이 충돌 부분을 (협업이면 합의하에) 하나 선택해서 수정한 후 다시 add commit을 진행해야 한다

# conflict_test.py
# HEAD ~ red 사이를 정리해 주어야 한다
<<<<<<< HEAD
def test1(yellow):
=======
def test1(red):
>>>>>>> red
    pass
# conflict_test.py 수정본
def test1(red):
    pass

여기선 red의 수정사항을 반영한다 가정하고 위에 yellow부분을 제거 한 뒤 다시 add, commit을 진행하였다.

$ git add conflict_test.py
$ git status
현재 브랜치 master
브랜치가 'origin/master'보다 1개 커밋만큼 앞에 있습니다.
  (로컬에 있는 커밋을 제출하려면 "git push"를 사용하십시오)

모든 충돌을 바로잡았지만 아직 병합하는 중입니다.
  (병합을 마무리하려면 "git commit"을 사용하십시오)

커밋할 변경 사항:
	수정함:        conflict_test.py
$ git commit -m "conflict_test.py conflict modified"
[master 575dc58] conflict_test.py conflict modified

이런 식으로 충돌의 경우도 해결 할 수 있다.

Reference

profile
wanna be good developer

0개의 댓글