깃 git 활용/사용/응용 팁 기술 이야기 2017.07.24 22:17

깃 git에 대해서는 이미 잘 정리된 글이 많지만, 경험을 바탕으로 깃 git 활용/사용/응용 팁을 간단하게 정리해 본다. 누군가에게 도움이 되길...(뭐라 표현해야 할지 고민하다 3개를 나란히 썼다.ㅋ)


목차

  1. 도움말을 확인하자
  2. track 옵션
  3. 되돌리기
  4. 커밋 commit id
  5. add 할때 -p 옵션!
  6. rebase 로그를 이쁘게
  7. grep 파일 내용 검색 기능
  8. git에서 HEAD란
  9. reflog 든든한 이정표
  10. branch 만들기
  11. remote branch 다루는 방법
  12. stash 간편 저장
  13. log 검색
  14. bash prompt에 git branch 이름 표시하기
  15. blame 수사반장
  16. remote의 HEAD 변경하기
  17. gerrit용 push 설정
  18. gerrit 사용방법
  19. 명령어 정리
  20. git GUI 프로그램 추천
  21. 기타

도움말을 확인하자

문제가 발생하거나 옵션을 확인하고 싶을때는 git help 를 활용하자 정리가 넘 잘되어 있다. git help [command] 치면 html 마크업 된 문서를 확인 할 수 있다.

[]안의 내용은 옵션이고 <>안의 내용은 필수 항목이다.

track 옵션

브랜치 만들때나 체크아웃 할 때 track 옵션을 설정할 수 있다. 설정 후에는 push/pull 할 때 브랜치명 생략 가능하다.
(checkout 하면 자동으로 로컬 브랜치 생성됨)

git checkout --track origin/dev
git branch --track feature1 origin/master

되돌리기

강제로 체크아웃, 현재 HEAD가 가리키는 커밋으로 돌아가며 작업 내용은 복구 불가~

git checkout -f

HEAD가 가리키는 곳을 변경하여 최종 커밋을 취소. 작업내용 보존됨

git reset HEAD^ //마지막 1개 최소
git reset HEAD~2 //마지막 2개의 커밋을 취소
//--hard 옵션을 추가하면 작업내용 삭제됨

git reset --hard HEAD~2    // 마지막 2개의 커밋을 취소. index 및 작업내용 모두 원복

원격에 있는 것을 없애고 싶을 때는 reset HEAD^로 원복하고 push -f 로 적용하면 되지만 다른 유저가 이미 내려받았을 경우 저장소간의 내용이 꼬이게 된다. 풀면되지만 비추.

add 할 때 -p 옵션으로 한번 더 체크!

보통 로컬에서 작업하고 staging 할 때 일괄적으로 staging 하거나 한번에 커밋하는 경우가 많은데, add 할 때 수정 사항을 한 번 체크 하면서 불필요한 코드나 스페이스 등이 딸려 들어가지는 않았는지 확인하는 것이 좋다.

이때 -p 옵션으로 수정 사항을 확인해서 선택적으로 staging 할 수 있고, 같은 파일이라도 수정 부분을 분리해서 staging 할 수 있다! 오!! 즉, 작업 내용을 2개 이상의 커밋으로 나눌 때 매우 유용하다.

사실 git을 처음 쓸 때는 staging 단계가 왜 필요한지 잘 몰랐다. 이게 익숙해지면 불편하게만 느껴졌던 staging 과정이 얼마나 유용한지 새삼 느끼게 된다. 아마 처음엔 -A 옵션만 쓰겠지만…ㅋ

-p 옵션을 사용하면 아래와 같은 수정사항마다 명령어를 입력해서 처리할 수 있는데, 아래와 같은 명령어가 있다. 제일 많이 사용하는게 y, n와 a 이 파일의 내용 모두 적용인데, s도 유용하다.

y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help

관련해서는 정리를 잘한 글을 소개하고 넘어간다.
git add -p 와 git commit -v 의 사용

커밋 commit id

커밋 ID 40자 160bit 인데(SHA-1), 몇 개만 입력해도 알아먹는다. :) 만약 중복되는게 있으면 조금 더 입력해 보면 된다.

git checkout <commit_id> //id를 조금만 입력해도 알아먹는 똑똑한 녀석.

rebase 로그를 이쁘게

간단하다. merge 같은 놈인데 merge 할 때 기존 commit 을 basebranch 기준으로 새로운 commit으로 변경해서 merge 하는 것이다! 최종 결과물보다는 히스토리의 수려함을 위해 사용되는데, 공동작업 할 때 필요하다.

basebranch 는 일반적인 상황에서 origin/master branch 정도가 되겠다~

git rebase [basebranch] 
git rebase [basebranch] [topicbranch]

pull 은 fetch and merge 니까 rebase 를 제대로 하려면, 일단 fetch 한 다음 rebase를 하거나 Pull에 --rebase 옵션을 주면 merge 대신 rebase로 진행된다.

grep 파일 내용 검색 기능

보통 프로젝트에 여러 종류의 파일이 같이 있는데 한방에 빠르게 검색 할 수 있는 부분이 매력적이다. Java, C, js, html, xml, txt 모~~두.

git grep -l <keyword> //-i 는 case ignore option, -l은 파일명 옵션

'HEAD' 란 현재 사용 중인 브랜치의 선두 부분을 나타내는 이름입니다. 기본적으로는 'master'의 선두 부분을 나타냅니다. 'HEAD' 를 이동하면, 사용하는 브랜치가 변경됩니다.누구나 쉽게 입문할 수 있는 Git 입문

위에 설명이 잘되어있지만 하나 추가하자면~ HEAD가 특정 브랜치가 아닌 commit을 가르키고 있을때 detached HEAD 라고 한다.

reflog 든든한 이정표

문제가 생겼을 때 한 줄기 빛을 내려주는 존재. reflog에 남아있다면 그곳으로 돌아갈 수 있다니…진짜…헐 대박~ㅎㅎ

되돌리기에 설명된 부분으로 되돌리기 해서 작업내용이 날라가도 다시 복구 할 수 있다.

HEAD가 가리키는 커밋이 바뀔 때마다 Git은 자동으로 그 커밋이 무엇인지 기록한다. 새로 커밋하거나 브랜치를 바꾸면 Reflog도 늘어난다. "Git 레퍼런스" 절에서 배운 git update-ref 명령으로도 Reflog를 남길 수 있다. 이 것이 git update-ref를 꼭 사용해야 하는 이유중에 하나다.9.7 Git의 내부 - 운영 및 데이터 복구

branch 만들기

git branch [branch A] <branch명> //새로운 branch를 만들어서 branch A로 checkout
git branch -d <branch명> //브랜치 삭제

remote branch 다루는 방법

git push [remote명] --delete <branchName> //원격 브랜치 제거
git push [remote명] :<branchName> //원격 브랜치 제거
git push [remote명] [branch명] //local branch의 내용을 remote 저장소에 push 한다. 
git push <remote명> <local branch>:<remote branch> // 내가 최초로 서버에 브랜치 만들기

stash 간편 저장

수정사항A를 commit하고 다른 부분B를 수정하고 있는데, 급하게 A를 서버에 push해달라는 요청을 받았다. 워킹트리(로컬 작업 공간)는 이미 어지러운데, 워킹트리를 그대로 두고 간단하게 A만 push하고 싶을때! stash가 필요하다.

git stash save -u //-u 옵션은 unstaged 파일까지 백업, save는 생략 가능

위와 같이 저장하면, 워킹트리의 작업 내용을 모두 백업(저장)하고 워킹트리를 비웁니다. 바로 pull & push 하면 된다! 와우~

git stash pop //저장내용을 복구하고 stash 내역에서 삭제
git stash apply //저장내용을 복구하고 stash 내역에서 삭제 안함 

pop이나 apply 명령어로 다시 복구할 수 있고, list를 관리 할 수도 있다. 자세한 내용은 다른 블로글를 찾아봐도 되지만, git help stash를 확인해 보길 권한다.

log 검색

솔직히 아래 커맨드 들은 사용해본 적이 거의 없음. 자세한 로그 확인은 툴을 보통 사용하기에...

git log --oneline --grep <keyword>
git log --oneline -G <keyword> //-G 옵션은 델타 기준으로 검색
git log -p -2 //변경내역 포함하여 최근 2개 보여줌
git log --stat  // 수정파일 리스트
git log --name-only //git log와 git log --stat 중간의 느낌 
git log --name-status //git log --name-only 결과에 수정/삭제/추가 여부만 알려줌
git log --pretty=oneline //commit 내용을 한줄로 표시. commit 번호와 commit 로그만 출력

bash prompt에 git branch 이름 표시하기

~/.bashrc 에 아래처럼 $(__git_ps1)을 추가한다.
PS1='[\w\e[0;36m \t\e[0;32m$(__git_ps1)\e[m]\$'

다른 옵션들은 아래 글을 참고
Tip: Prompt magic

blame 수사반장

이름이 넘 잔인한데, 매우 직관적이다.ㅋㅋㅋ 라인별로 마지막에 누가 커밋했는지 확인 할 수 있다.
git blame -L <n,m> <file> //n라인부터 m라인까지

remote의 HEAD 변경하기

기본적으로 HEADmaster에 가있는데, clone해서 특정 브랜치로 checkout을하는 것이 일반적이지만, remoteHEAD를 특정 브랜치로 놓으면 clone했을 때 그 브랜치에 checkout되어 있다!

$ git remote set-head origin tizen //origin remote repository의 HEAD를 tizen 브랜치로 설정
$ git remote update //설정값을 remote에 업데이트

gerrit용 push 설정

gerrit 에 push 할 때 간단하게 git push gerrit 이라고 쳐서 push할 수 있게 설정 할 수 있다. remote repository 에 대한 설정을 하는 방법이며, push 할 branch에 파라미터로 리뷰어를 넣어서 한번에 push 할 수 있다.

// gerrit 이라는 remote 를 만든다. (있으면 설정 변경)
$git config remote.gerrit.url ssh://review.msalt.net:29418/project

//%r 뒤로 리뷰어를 추가해두면 한번에 리뷰어 추가가 된다.
$git config remote.gerrit.push HEAD:refs/for/master%r=salt.jeong@msalt.net,r=git@msalt.net

.git 폴더에 config 파일을 열어보면 아래와 같이 추가 되어 있는 것을 확인 할 수 있다.

[remote "gerrit"]
  url = ssh://review.msalt.net:29418/project
  push = HEAD:refs/for/master%r=salt.jeong@msalt.net,r=git@msalt.net

gerrit 사용방법

commit 메세지 footer에 change-id를 기입하고 push 하면된다.
git push origin HEAD:refs/for/<target branch>
change-id를 넣기위해서, commit-msg hook 스크립트를 다운받거나, reject message 안의 메세지를 긁어서 commit 메세지에 복사해서 붙인 다음 다시 push 해도 된다. 리뷰어 추가는 브라우저로 gerrit 접속해서 해도 되고 push 파라미터로 넣어도 된다.

**gerrit은 change-Id 로 커밋을 관리하기 때문에 I로 시작하는 change-ID가 꼭 필요

그외 명령어 정리

기본적인 명령어와 사용법이 잘 정리된 페이지 링크를 하나 붙인다. 잘 정리되어 있고, 만드신 분 정말 대단한것 같다.
http://kwonnam.pe.kr/wiki/git/cheatsheet

사실 명령어 정리된 글은 많은데, 실제 본인이 사용하게 되는 명령어는 제한적이고 새롭게 알게되는 응용법도 제한적이다. 이 글이 후자를 해소 하는데 도움이 되길...ㅎ

git GUI 프로그램 추천

git은 커맨드로 사용하는 것이 빠르고 편리하지만 로그나 머지merge, 차이diff 확인은 GUI 툴이 간절히 생각나게 된다. 나는 주로 로그 볼때 사용ㅎ

스마트깃SmartGit
강력하고 편리한 툴이다. 윈도우, Mac, 리눅스 버전이 모두다 제공된다. 최고의 단점이라면 유료라는것. 상업적 이용이 아니라면 무료이니 개인 사용자에게 적극 추천한다.

깃익스텐션GitExtensions
강력하고 편리한 툴이다. 윈도우, Mac, 리눅스 버전이 모두다 제공된다. 단점이라면 좀 느리다. GPLv3 라이센스의 오픈소스 프로젝트이다.

기타

아래와 같은 권한 에러 날 경우.

insufficient permission for adding an object to repository database .git/objects

여러 방법이 있지만 나는 간단하게 아래 방법을 사용

sudo chmod 777 -R .git/objects

윈도우에서 cygwin 메모리 에러 날 경우. 음...재부팅? ㅋㅋㅋ

마치며...

그 동안 경험을 바탕으로 주절 주절 적어봤는데, 깃git을 잘 쓰고 싶다면 호기심을 갖고 탐구(?)하면 된다. '이런것도 될까?' 라는 생각에서 시작해서 알게된 내용 들이 대부분이다. 여기에 적힌 것보다 훨~~~씬 많은 팁과 응용법이 있다. 알면 알수록 감탄이 나오는 강력한 툴이다! 깃git 개발자들에게 고마운 마음을 전하며 글을 마친다.