'merge'에 해당하는 글 4건

git conflict 해결

Tool/Git 2017. 2. 4. 22:30

merge 시 주로 발생하는 충돌, conflict 는 길게 말할 것도 없다.


<<<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
cs


1. 일반적으로 위와 흡사한 형태의 충돌인데, 일단 동일한 부분을 함께 작업한 팀원과 상의하여 코드를 수정한다.

2. <<<<<<<<<, =======, >>>>>>> 라인 역시 삭제한다.

3. 수정이 끝났다면, 다른 기존 파일들과 마찬가지로, add 명령으로 index(staged) 상태로 변경하고, commit 하고 push 한다.



끝이다.


주로 2번 까지만 진행하고 3번을 생략한 채 계속해서 push 를 하려고 해서 '충돌이 해결되지 않았다'는 메시지를 보게된다.

아주 간단하다는...


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

git branch & merge

Tool/Git 2017. 2. 2. 21:36

브랜치 작업을 하거나 충돌날 때마다 도움을 요청하는 중생들을 줄이고자, git 세미나를 준비하면서 정리한 내용들이다.


* 목표

- 쫄지말고 브랜치(branch) 사용하기.

- 충돌(conflict)이 나더라도 쫄지 않기.


(기본적인 push, pull 정도는 할 줄 안다는 가정하에 불필요한 내용은 생략한다.)



1. 우리는 이럴 때 branch 를 사용한다.


다음 케이스를 보자.

master 브랜치 하나만 가지고 있으면서 이 작업물로 운영서버에 배포를 한다.

이 프로젝트에 [기능] 추가 요청이 들어왔고 팀원들과 협업이 필요하다.

협업이 필요하기 때문에 원격 저장소에 소스를 공유해야 한다.

기능 추가 작업중에 심각한 [버그] 를 발견하여 수정하고 다시 배포를 해야 한다면, 아직 완료되지 않은 [기능] 추가 작업이 같이 배포되어 버린다.

이를 방지하기 위해 필요한 것이 바로 branch 이다.


2. branch 란?


현재 브랜치(예를 들어 master) 에서 해오던 작업은 branch 를 추가하는 순간 별도의 공간에서 추가적으로 개발할 수 있다.

branch 는 이름 그대로 나뭇가지 처럼 작업을 분리시키는 것이다.

master iss53 이라는 브랜치가 있다면 master 에서 작업하는 내용은 iss53 에 영향을 미치지 않으며, iss53 에서 작업하는 내용 역시 master 에 영향을 미치지 않는다.


위 케이스에서 [기능] 추가 작업시 iss53 이라는 브랜치를 새로 생성해서 작업한다면,

또 [버그] 수정 역시 hotfix 라는 브랜치를 새로 생성해서 작업한다면, master 에서 bugfix 를 merge 하고 배포하면 끝이다.

다시 iss53 브랜치를 checkout 하여 [기능] 추가 작업을 계속 하면 된다.


3. merge 란?


branch 가 작업을 분리시키는 명령이라면, 반대로 분리한 작업을 다시 합쳐주는 명령이 바로 merge 이다.

우리는 이미 pull 을 수도 없이 사용하면서 자동 merge 를 사용해 왔다. (pull 명령은 fetch + merge 를 한번에 실행해 주는 명령이다.)

master 브랜치에서 git merge hotfix 명령으로 수정된 버그를 해결하고, git merge testing 명령으로 기능까지 추가한다면,

master 브랜치는 최신 상태의 소스가 되고 배포할 준비가 된다.


branch 와 merge 는 이게 끝이다.


이제 실제로 위 케이스를 실행해 보자.


최종적으로 위와 유사한 결과를 도출할 수 있어야 한다.


[기능] 추가 요청에 대한 iss53 이라는 브랜치 생성.


$ git checkout -b iss53
cs


위 명령은 아래 두개의 명령을 한번해 실행해 줌.


$ git branch iss53
$ git checkout iss53
cs


작업 및 커밋진행


$ git commit -m 'description'
cs


도중에 [버그] 수정 요청에 대한 hotfix 라는 브랜치 생성.

master 에 기반한 브랜치를 생성해야 하므로 master 브랜치를 이동하여 브랜치를 생성.


$ git checkout master
$ git checkout -b hotfix
cs


버그를 수정한 후 커밋을 진행.


$ git commit -m 'description'
cs


수정한 버그를 master 에 합치기 위해 master 브랜치로 이동하여 merge 실행


$ git checkout master
$ git merge hotfix
cs


master 브랜치는 hotfix 브랜치를 생성한 이후에 커밋을 진행하고 있지 않았으므로 단순히 브랜치 포인터만 hotfix 의 최신 커밋으로 이동함. (fast-forward 방식)

다시 iss53 으로 이동하여 [기능] 추가 작업 마무리 하고 커밋하고 master 와 합치기 위해 merge 실행.


$ git checkout iss53
$ git commit -m 'description'
$ git checkout master
$ git merge iss53
cs


master 브랜치는 iss53 브랜치를 생성한(조상) 이후에 커밋이 진행되었으므로 그림처럼 두개의 브랜치가 합쳐지는 3-way merge 처리.

3-way merge 의 결과로 별도의 커밋이 만들어진다.


추가적으로 브랜치를 변경할 때는 기존의 staged 를 깨끗하게 정리하는 것이 좋다. 

commit 이나 staged 를 사용하여 충돌을 체크 및 예방한다.




WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

merge scenario

Tool/Git 2013. 3. 24. 00:17

Fast-forward

 

  1. A branch 에서 B branch 생성
  2. checkout B
  3. B branch commit
  4. checkout A
  5. A merge B

 

이 경우 A branch로부터 생성된 B branch가 commit 을 실행하면서 A branch 보다 앞서갑니다.
A branch 는 변경된 것이 없습니다.
A branch 가 B branch 를 병합하면서 A branch 의 포인터(HEAD)는 B branch 로 이동하게 됩니다.
합쳐진다기 보다 포인터(HEAD)만 B branch 의 최근 commit 위치로 이동하는 것입니다.
이 때 Fast-forward 방식의 merge 라고 메시지가 나타납니다.
Fast-forward 란 병합(merge)할 branch 의 최근 commit 이 현재 branch 보다 앞서 있다는 뜻입니다.

 

 

이번에는 A branch도 commit해 보겠습니다.

 

 

 

3-way Merge

 

  1. A branch 에서 B branch 생성
  2. checkout B
  3. B branch commit
  4. checkout A
  5. A branch commit
  6. A merge B

 

이 경우 A, B 모두 branch 생성 후에 변경점(commit)이 생성 되었기 때문에 포인터(HEAD)의 이동만으로는 병합될 수 없습니다.
이 경우에는 병합시 A가 자동으로 하나의 commit 을 더 생성하며(3-way Merge) B와의 내용물을 병합하게 됩니다.
이 때 recursive 방식의 merge 라고 메시지가 나타납니다.
Fast-forward 방식의 경우는 A와 B의 포인터가 모두 마지막 commit을 가리키지만,
recursive 방식의 경우 B는 여전히 자신의 마지막 commit을 가리키고 있고,
A는 B와 병합하여 새로 생성된 마지막 commit을 가리키게 됩니다.
새로운 commit이 생성되었으므로 자동으로 편집기가 열리며 자동으로 commit 메시지가 담겨 있습니다.
Merge branch 'B' into A

 

 


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,

svn update

Tool/Subversion 2012. 10. 30. 23:52

저장소의 최신 리비전을 작업 사본으로 가져와 같은 리비전으로 변경됩니다.
주로 커밋전에 사용되기도 하고, update로 변경될 사항들을 svn st -u 명령으로 미리 확인할 수 있습니다.

 

 

update
usage : update [PATH...]

 

저장소에 변경된 작업물들을 작업 사본으로 가져옵니다.
리비전을 지정하지 않으면 최신(HEAD)의 리비전을 가져옵니다.
또한 특정 리비전(-r)으로 작업 사본을 동기화 시킬수도 있습니다.

 

업데이트 된 각 작업물들의 앞에는 알파벳 한 문자로 출력됩니다.
A 추가됨(Added)
D 삭제됨(Deleted)
U 갱신됨(Updated)
C 충돌함(Conflict)
G 합쳐짐(merGed)
E 존재함(Existed)

 

첫번째 컬럼의 문자는 실제 파일이 변경됨을 뜻합니다.
두번재 컴럼의 문자는 파일의 속성에 대한 변경을 뜻합니다.
세번째 컬럼에 B 는 잠긴 파일이 깨지거나(Broken) 사라졌음(Stolen)을 뜻합니다.

 

$ svn up
A    txt.c
D    txt.h
U    ext.c
G    abc.c
C    bar.c
Updated to revision 10.

 

txt.c(A) 파일은 작업 사본에는 없었지만 저장소에 추가된 파일이라 가져왔습니다.
txt.h(D) 파일은 작업 사본에는 있었지만 저장소에서 삭제된 파일이라 작업 사본에서도 삭제되었습니다.
ext.c(U) 파일은 저장소의 내용으로 작업 사본이 갱신되었습니다.
abc.c(G) 파일은 작업 사본에서 수정한 파일이지만 저장소에 수정된 부분과 겹치지 않아서 파일 내용에 알맞게 합쳐졌습니다.
bar.c(C) 파일은 작업 사본에서 수정한 부분과 저장소에서 수정된 부분이 겹쳐져서 충돌이 생겼습니다.

 

충돌(C)을 제외한 나머지 상태들은 크게 신경쓸게 없지만, 충돌의 경우 약간 작업이 필요합니다.
누군가 커밋한 파일을 업데이트 받지 않고 해당 파일의 겹치는 부분을 수정하여 커밋하려 할 때 커밋 실패 메시지가 출력됩니다.

 

$ svn ci -m 'modify by oops4u' test.txt
svn: Commit failed (details follow):
svn: File or directory 'test.txt' is out of date; try updating
svn: resource out of date; try updating

 

이 때는 최신 리비전으로 update 해야 하며 update할 때는 충돌을 예상할 수 있습니다.

 

$ svn up
Conflict discovered in 'test.txt'.
Select: (p) postpone, (df) diff-full, (e) edit, (r) resolved,
        (mc) mine-conflict, (tc) theirs-conflict,
        (s) show all options:

 

충돌 메시지가 나타나며 진행 방법을 선택할 수 있습니다.
충돌이 발생한 원본 파일(위에서는 test.txt)에는 충돌에 대한 내용이 포함되어 있습니다.
(df) 는 충돌이 발생한 부분을 확인할 수 있습니다.
확인 후에 (e) 로 편집기를 열어 바로 수정할 수 있습니다.
수정 후에는 (r) resolved 옵션이 추가되는데 편집기에서 충돌을 정상적으로 해결했다면 (r) 입력하여 해결할 수 있습니다.
무조건 내 작업물을 남기려면 (mc)를 입력하고 커밋을 하면 저장소에 본인의 작업물로 갱신됩니다.
당장 해결할 수 없는 문제라면 (p) 버튼을 눌러 파일을 충돌 상태(C)로 남기며 update를 완료합니다.
postpone 이 선택되면 file, file.mine, file.r21, file.r22 등 3개 파일이 더 생성됩니다.
(p)가 아닌 (r)을 입력하면 원본 파일을 제외한 *.mine, *.r21, *.r22 등의 파일들은 생성되지 않으며 상태는 G(merGe) 상태가 됩니다.
머지 상태는 두 버전의 내용이 절충되어 충돌이 해결된 상태라고 생각하면 됩니다.
고장날 일 없으니 각 옵션 별로 테스트를 해보면 이해가 빠를 겁니다.

 

file.r21 은 마지막으로 저장소에서 받은 file 원본
file.mine 은 r21을 작업 사본에서 수정한 file 작업물
file.r22 는 저장소의 최신 file 작업물
file 은 r21 원본위에 충돌난 부분이 <<<<<< .mine ======== >>>>>>> .r22 등으로 표시

 

작업자와 상의하여 파일을 합친 후 생성된 3개 파일을 삭제하고 커밋하여 충돌을 해결합니다.


WRITTEN BY
손가락귀신
정신 못차리면, 벌 받는다.

,