Scenario


최근 git cli를 사용하려고 노력중이다보니, Source tree를 사용하지 않고 직접 cmd를 치다보면 merge를 해야할지 rebase를 해야할지, 헷갈리때가 있다. 또한 옵션에 대해서도 잘 모르고 써었는데 한번 정리해보자 한다.

 

 

Solution


기본적으로 git pull = git fetch + git merge 이다.

그러면 어느때 git merge를 쓰고 어느때 git rebase를 써야할까?

 

Merge

현재 C2 parent에서 brach가 둘로 분기되었다 가정하자
master로 checkout 한후 merge 하였다. (checkout master && merge experiment)

위의 경우가 통상적인 merge 방법이나 이렇게 되면 작업 history가 가시적일 순 있어도 branch가 많아지면 많아질수록 알아보기가 어려워진다. 사람들은 이러한 이유로 rebase를 쓴다.

 

rebase

똑같은 상황 가정

 

 

'experiment에서 master rebase (checkout experiment && rebase master) 

master 브랜치를 Fast-forward시킨다 ('앞으로 진행한' 커밋인 master 브랜치 포인터는 최신 커밋으로 이동한다. 이런 Merge 방식을 'Fast forward'라고 부른다.)

 

완료후 정리된 커밋모습

 

위와같이 c3` 커밋메세지 기반으로 history가 정리됨을 알수있다.

tip) git rebase [basebranch] [topicbranch] 처럼 인자를 준다면 일일히 checkout 하지 않고 rebase할 수있다.

위 그림같은 경우는
$ git rebase master experiment

 

 

 Merge

Rebase 

 특징

 -  branch의 최종 결과만을 가지고 합병

 - 지정한 브랜치를 베이스로 기준 삼아 합병

 - 중복수정된 로그가 남지않는다.

 - 브랜치의 변경사항을 순서대로 다른 브랜치에 적용하면서 합병

 장점

 - 이해하고 사용하기 쉬움

 - 브랜치 컨텍스트 유지

 - history가 단순해짐

 - branch가 많을때 커밋을합치는 직관적인방법

 단점

 - 히스토리가 난잡

 - 커밋 순서대로 rebase를 하는데, 각 커밋마다 충돌해소를 순서대로 해주어야하여 복잡함

 

추가유용 명령어
- FILE 되돌리기 및 삭제편

git checkout [-- 파일명]
아직 스테이징이나 커밋을 하지 않은 파일의 변경내용을 취소하고 이전 커밋상태로 돌린다. svn에서 revert와 동일하다 (그냥 git checkout branch를 할경우 현재 활성화된 브랜치를 바꾸는 명령어이다)  

git checkout -- . wd에 수정된내용 모두 되돌림

git diff [--cached]
스테이징영역과 현재 작업트리의 차이점을 뵤어준다. --cached 옵션을 추가하면 스테이징영역과 저장소의 차이점을 볼 수 있다. git diff HEAD를 입력하면 저장소, 스테이징영역, 작업트리의 차이점을 모두 볼 수 있다. 파라미터로 log와 동일하게 범위를 지정할 수 있으며 --stat를 추가하면 변경사항에 대한 통계를 볼 수 있습니다.
git diff --ours 머지이전과 머지이후 결과비교

git reset — hard HEAD^
commit한 이전 코드 취소하기

git merge --abort 머지 취소하기(커밋이나 stash 하지않는 존재시 못함)

git config — global user.name “user_name ”
git 계정Name 변경하기

git config — global user.email “user_email” 
git 계정Mail변경하기

git stash / git stash save “description”
작업코드 임시저장하고 브랜치 바꾸기

git stash pop
마지막으로 임시저장한 작업코드 가져오기

git reset HEAD [-- filesName] stage에 있는 파일 내리기

git reset — soft HEAD^ 
코드는 살리고 commit만 취소하기

git reset — merge 
merge 취소하기

git reset — hard HEAD && git pull  git 코드 강제로 모두 받아오기

git reset --hard HEAD 머지하기이전상태로 모두되돌림

git reset --[hard] [mixed] [soft] 

--hard: reset하기 전까지 했던 staging area, working directory의 작업까지 모두 reset!
(모든 게 잘못됐어! 나 돌아갈래~ 꽃피던 때부터 정갈하게 다시 해보자!)
--mixed(default): staging area은 reset, reset하기 전까지 했던 working directory의 작업은 남겨둠.
(현재 작업물은 지우긴 싫고, 이전 버전으로 돌아가서 add할지 말지 결정해야 할 때)
--soft: reset하기 전까지 했던 staging area, working directory의 작업은 남겨둠.
(reset한 버전과 현재까지의 작업을 합쳐 새로운 버전 만들 때)
git reset --hard 커밋된 파일빼고 모두삭제
git clean -df 커밋,stage 되지 않은 파일 폴더 모두삭제 [untrack 중인] (매우 유용) 

 

-- 유용한명령어들

git add .
git commint -m "{msg}"
git remote -v  --list all
git remote set-url origin "{repo-url}"
git remote add origin "{repo-url}"
git remote remove origin
git push --set-upstream origin master 초기
git config --list
git commit --author "asd<asd@gmail.com>" -m
git log --graph --oneline --all  로그를 커밋메시지는 한줄로 그래프형태로 모두보기
git log --graph --oneline --all --pretty="format:[%h]%s - %an" 커미터지정해서 보기

+git stash

stash는 다시 한번 말하지만 하고 있던 작업을 잠시 담아두는 역할을 한다.

따라서 명령어는 크게 두 가지만 기억하면 된다.

git stash(=git stash save) : 하던 작업을 저장하고 가장 최근 commit상태로 만든다.

git stash pop 또는 git stash apply : 저장되어 있는 작업중 가장 최근 stash를 가져온다.

이 외에 명령어 옵션들

git stash list : stash 목록을 봄 stash@[숫자]형식으로 보여지며 0번이 가장 최근 1,2,3... 이런식으로 밀림

git stash drop[stash@[숫자]] : stash를 따로 지정하지 않으면 최신의 stash삭제

* git stash pop은 git stash apply + git stash drop을 같이 한 것과 같은 효과임.

  즉, git stash pop은 한번 불러오면 stash 목록에 저장한 시점이 삭제되어있고 git stash apply는 해당 stash를 불러와도 여전히 list에 남아 있음.

 

+ Recent posts