Git-bash 실습해보기 

앞전에 :009.Git-bash (checkout, reset, add, rm, commit)" 과정에 이어서 설명을 하겠다.

앞전 실습에서 한 내용은


$touch add_test  를 통해서 새로운 파일을 생성하였으며

readme.txt 를 수정하였고

merge_test2.txt를 삭제한 후 commit을 하였다.


git log -n 1 을 입력하면 현재 상태에서 가장 최근 commit이 나온다

만약 branch가 test11이 아닐 경우, test11로 branch를 변경 한 후 가장 최근 commit으로 이동할 것이다.


(만약 test11 branch에서 위의 add/rm test를 진행하였으면 상관 없다. 나는 develop에서 add/rm test를 진행하였기 때문에 아래의 과정을 진행한다.)


$ git log -n 1              // 가장 최근의 1개의 커밋 ID를 확인한다.

$ git checkout test11     // tset11 branch 로 변경한다 (현재 test11은 다른 commit에 있다고 가정)

$ git reset --hard dc68e3  // test11 branch를 dc68e3 commit으로 옮긴다.


***** 주의 *****

여러분이 생성한 commit id와 내가 생성한 commit id가 다를 수 있으므로 본인의 commit id를 사용하기 바란다.

내 commit id : dc68e3c1afb28ce..........

gitk --all 에서 SHA1 ID 가 commit ID이다.

위의 내용을 통해 확인 할 사항

1. 현재 branch가 test11이 맞는지 확인한다. (여러분이 test??로 생성했다면 test??가 맞는지 확인)

2. add_test 파일이 있는지 확인

3. merge_test2.txt 파일이 삭제 되었는지 확인




1) 사전준비 git config


git push를 하기 전에 git config를 세팅한다. 여기서 user 이름과 e-mail을 등록하면, git push를 할 때 자동으로  git config 에 등록된 이름을 가져다가 쓴다. 또한 push 방법을 설정 할 수 있다. 그러면 지금부터 git config를 등록한다

만약 git config를 등록하지 않고 push를 하게 될 경우 이름, 이메일, push 방법 등을 묻는 메세지가 나올 것이다. 미리 등록하자.


$ git config --list      // git config 등록된 리스트 보기

$ git config --global user.name "이름입력"      ex) git config --global user.name "hjpark"

$ git config --global user.email "e-mail입력"    ex) git config --global user.email "hjpark@google.com"

$ git config push.default "matching"


지금부터 push를 진행합니다.




2) git push

git push넌 local저장소의 내용을 remote저장소(서버) 로 update 하는 것이다.

git push에는 여러 조건이 있지만 크게 아래 2가지만 알면 된다.


$ git push

-> 로컬의 변경된 모든 내용을 원격저장소에 올린다. (단, 매칭되는 branch만 push함)


$ git push origin <원격저장소 branch>

-> 원격저장소 branch에 push한다.

-> 만약 remote에 branch가 존재하지 않을 경우, local의 branch 명과 똑같이 써주면 원격저장소 branch생성



*** 주의 ***

원격저장소 branch명과 local의 branch명이 같아야 한다.


---- 예제 ----


만약 remote branch에 master와  develop만 있다고 가정해보자

remotes/origin/master

remotes/origin/develop

( $ git branch -r 을 통해 확인 가능 )



현재 local에는 3개의 branch가 있다고 가정하자

master

develop

test11

( $ git branch 를 통해 확인 가능)



여기서 develop과 test11에 각각 commit을 하였다고 가정하면

master > 변경 없음

develop > 변경 있음

test11 > 변경있음



이상태에서 git push를 하면 어떻게 될까?

develop branch만 서버에 push가 된다. 이유는 remotes/origin/develop 은 서버에 존재하기 때문에 local의 develop이라는 branch와 매칭이 되어서 자동으로 올라간다. 하지만 test11이라는 branch는 remote 저장소에 없기 때문에 어떠한 변화도 생기지 않는다.


master > 변경없음      ( remotes/origin/master 존재 )

develop > push 성공   ( remotes/origin/develop 존재 )

test11 > 어떠한 변화도 없음  (원격 저장소에 branch 없음)



그렇다면 test11 이라는 branch를 어떻게 원격저장소에 push 할 수 있을까?

만약 remote 저장소에  remotes/origin/test11 이라는 branch가 있으면 test11 도 같이 올라갔을 것이다. 하지만 그렇지 않을 경우 다음을 통해 만들 수 있다.


$ git checkout test11  // 현재 branch를 test11 로 바꾼다.

$ git push origin aaaaa   // remote에 aaaaa로 push를 하지만 local branch와 매칭이 안되서 실패

$ git push origin test11   // remote에 test11 이라는 branch가 없지만 local인 test11이라는 branch가 매칭되므로 remotes/origin/test11을 자동으로 생성하고 서버에 push하게 된다.



처음에는 원격저장소가 2개였지만 이젠 3개가 되었을 것이다.

remotes/origin/master

remotes/origin/develop

remotes/origin/test11      -> git push origin test11 을 통해 새로 생성한 remote branch


git push 와  git push origin <branch> 의 차이를 알겠는가???

git push는 원격저장소와 매칭되는 브랜치만 push할 수 있다.

git push origin <branch> 명은 remote와 local의 매칭되는 branch만 push하며, 없을 경우 새로 만들어서 push 할 수 있다.


중요한 point는 branch 명을 매칭(똑같이)해야 된다는 점이다. 




3) git pull

서버에 성공적으로 push를 하였는가?  성공적으로 push를 한 사람이 있는 반면에 실패를 한 사람도 있을 것이다. 성공한 경우는 내가 push할 branch를 다른사람이 건들지 않기 떄문에 쉽게 성공하겠지만, 실패한 경우는 내가 push를 하기전에 누군가 먼저 해당 branch를 push를 한 경우가 되겠다.


git push dvelop -> develop이  거절되었다. 이 에러를 해결하는 5가지의 hint가 있는데 4번째 hint를 보면

hint (e.g., 'git pull ...') before pushing afain.    ->   push 하기전에 git pull을 하라는 내용이 나온다.




그럴 경우 server의 내용일 다시 받은 다음 commit을 하면 된다.

$ git fetch --all        // 변경된 모든 정보를 불러온다.  (다운받지 않고 정보만 불러옴)

$ git pull            // 원격저장소로부터 변경된 정보를 다운받는다.

$ git push            // 다시 push한다.



만약 내가 작업하던 도중 git pull을 해야 되는 상황이 오면??

1. 변경된 내용들을 git add / rm 을 통해 준비영역에 저장

2. git status 를 입력하여 빨간 글씨가 없는지 확인한다.

3. git commit -m "메세지" 를 통해 작업중인 내용을 commit한다

4. git pull을 한다.



git pull을 하였는데 실패하는 경우는 다음과 같다. remote로 부터 받을 파일과 내 로컬에 저장된 파일이 충돌이 나는 경우다. 만약 서로 다른 파일을 수정하였더만 충돌이 날 이유가 없지만, 서로 같은파일에 같은 공간을 수정하였다면 이렇게 충돌이 발생 할 수 있다.

$ git pull  (위의 그림 설명)

Auto-merging readme.txt      -> remote와 local의  readme.txt를 자동으로 merge 하는 내용이다.

CONFLICT (content): Merge conflickt in readme.txt    -> readme.txt 를 merge하는 동안 오류가 났다.

Automatic merge failed: fix conflicts and then commit the result    -> 충돌 해결 후 결과를 commit 하여라.


자, 우리는 여기서 충돌 해결 후 결과를 commit 해주면 된다.

자세히 보면 제일 오른쪽 하늘색 글씨가 (develop) -> (develop|MERGING) 으로 변한 것을 볼 수 있다.

현재 git pull하면서 auto merge 중에 에러가 발생하였고 사용자가 직접 해결해줘야 하는 부분이다.


$ git status  (위의 그림 설명)

성공

 - new file: add_test

 - deleted; merge_test2.txt

실패

 - both modified: readme.txt     -> 실패한 이유는 양쪽 branch의 readme.txt가 수정되었기 때문이다.



자, Tortoise git으로 수정해주자.  아래의 "5) git 충돌 해결하기" 참조 바람.




4) git merge

merge를 하게 되는 경우는 크게 2가지가 있다. 

1. 다른 branch와 작업 내용을 합칠 때

2. git pull 할 때. (앞에 git pull 에서 auto-merge를 의미함)



branch 끼리 merge하기

test11과 develop이라는 branch를 합치고 싶다면???

$git checkout test11     -> test11로 checkout 한다. (main이 됨)

$git merge develop      -> test11의 branch에 develop branch를 합친다.

아무런 충돌이 없을 경우 잘 합쳐질 것이다. gitk --all 을 통해 직접 확인해 보기 바란다.



merge를 취소하고 싶다면???  (4가지 방법 중 택 1)

1. $ git merge --abort       // merge 취소하는 명령어 git이 merge 중이여야 가능한 명령어.

2. $ git merge reset --hard HEAD~     // merge를 아예 취소하고 가장 마지막에 commit한 HEAD로 이동

3. $ gitk --all 을 한다음 원하는 commit으로 누르고 Reset <branch> to here / Hard 체크

4. TortoiseGit으로 Merge abort 선택





5) git 충돌 해결하기 (git conflict solve)

git pull 또는 git merge 도중 충돌이 생기기 마련이다. git merge를 해결하기 위한 git merge tool들이 있다.

$ git mergetool 을 입력하면 되지만 인터페이스가 매우 후지다.

만약 입력했다면 < Esc + : + q + Enter >  를 연달아 반복해서 빠져나오자. 우리는 Tortoise git을 이용할 것이다.


먼저 해당 충돌이 생긴 폴더로 이동한 뒤에 마우스 우클릭 하여 diff 를 선택한다.




Diff를 선택하면 아래와 같은 창이 나온다. 검정 글씨는 충돌이 나지 않은 파일들이고 빨간글씨가 충돌이 난 파일들이다. 우리는 이 빨간 글씨를 해결해줘야 한다. 만약 빨간글씨를 해결하지않고 commit을 해버리는 경우, 해당 파일의 충돌부분에 이상한 글자들이 들어가게 된다.


Conflict가 발생한 파일을 더블클릭하거나 마우스 우클릭하여 Edit Conflicts를 눌러준다.

( 만약 기존의 Branch 혹은 Local을 내용으로 덮으쓰고 싶다면 Resolve conflict using 'mine'을 선택하라. 반대로 앞으로 합칠 branch 혹은 Remote의 내용으로 덮으쓰고 싶다면 Resolve conflict using 'theirs'를 선택하라)




각각의 상황에 따라 Theirs와 Mine이 가리키는게 차이가 있다.


git push로 충돌해결할 경우   

 -> (왼쪽상단 Theirs - Remote)  (오른쪽 상단Mine - Local) 


local에서 git merge 중 충돌해결할 경우  

 -> (Theirs - 합치고자 하는 branch) ( Mine - 현재 checkout된 branch)

위의 그림을 보면 가장 밑에 부분이 최종적으로 저장할 파일의 내용이다. 해당 부분을 마우스로 드래그하여 마우스 우클릭하여 어떠한 내용을 쓸 것인지 직접 선택하면 된다. 

Use 'mine' test block 을 선택하게 될 경우 Mine에 있는 내용으로 덮어쓰게 된다.


상단 중앙에 Previous conflict / Next conflict 버튼을 눌러서 또 다른 충돌이 없는지 찾아보고, 더 이상 충돌이 없으면 Mark as resolved 를 누른후 저장하고 종료한다.




왼쪽 그림을 보면 빨간색이였던 readme.txt가 파란색으로 변한 것을 볼 수 있다. 충돌이 해결된 것이다!! (올레~)

이제 최종적으로 merge한 내용을 commit 하면 된다. 하단에 있는 commit 버튼을 누르면 오른쪽 창이 나타난다.

Commit Message 가 자동으로 작성되었다. 밑에 OK 버튼을 눌러주자.



이렇게 충돌이 생길 경우 TortoiseGit 으로 직접 해결해 주면 된다.



---------------------------------------  끄읕  -------------------------------------------------


git 강좌를 진행 중 미비한 부분을 보완하였습니다. 잘 보고 본인이 직접 실습해서 본인 것으로 만들길 바랍니다.



+ Recent posts