yesdoing
Frontend Developer
19.07.13
이 장 희
Git Tools
리비전 조회하기
리비전이란 다른 버전 관리 시스템에서도 사용되는 용어로써,
추적되어지는 프로젝트의 상태를 뜻하는 단어 입니다.
Git 안에서의 모든 리비전은 자기를 위한 1개의 SHA-1 값을 가지며, SHA-1 값으로 참조될 수 있습니다.
Git 안에서는 1개의 커밋을 리비전이라고 표현할 수 있습니다.
리비전 조회하기
Commit 기록을 확인하기 위해서는 git log 라는 명령어를 통해 확인 할 수 있으나, 각 Commit이 가지는 SHA-1 값을 통해서도 커밋을
확인 할 수 있습니다.
리비전 조회하기
리비전 조회하기
리비전 조회하기
혹시라도 SHA-1값이 중복이 되면 Git은 이전의 Commit된
결과를 반환한다.
SHA-1 값은 20 Byte(160 Bit)의 값을 가지며, 이 값이 중복이 될 수 있는 확률이 50%가 되려면 필요한 커밋의 수는 2^80 이다.
즉, SHA-1 해쉬 값이 충돌날 확률은 그냥 동료가 사무실에서
지나가던 늑대에게 물려 죽을 확률보다 낮다.
리비전 조회하기
리비전 조회하기
어떤 특정 브런치(🍱) 의 최신 commit 을 확인 하고 싶으면
브랜치 명으로 검색하면 된다.
리비전 조회하기
리비전 조회하기
각각의 branch 는 자신의 가장 최신 commit의 SHA-1 값을
가리키는데 이것은 rev-parse 라는 Git의 내부 기능을
사용해서 유지한다.
(자세한 내용은 Git 내부 발표해주시는 분이 이어서 해주실 겁니다.)
리비전 조회하기
Git은 자동으로 브랜치와 HEAD가 지난 몇 달 동안에 가리켰었던 commit을 모두 기록하는데 이 로그를 “Reflog” 라고 합니다.
이 "Reflog"를 사용해서도 커밋을 확인 할 수 있습니다.
리비전 조회하기
리비전 조회하기
Git은 브랜치가 가리키는 것이 달라질 때마다 그 정보를
임시 영역에 저장합니다.
그래서 예전에 가리키던 것이 무엇인지 확인해 볼 수 있는데,
@{n} 규칙을 사용하면 HEAD가 n번 전에 가리켰던 것을
알 수 있습니다.
리비전 조회하기
리비전 조회하기
Reflog의 일은 모두 로컬의 일이기 때문에
내 Reflog가 동료의 저장소에는 있을 수 없습니다.
이제 막 Clone 한 저장소는 아무것도 한 것이 없어서 Reflog가
하나도 없으며 "git show HEAD@{2.months.ago}" 같은 명령은
적어도 두 달 전에 Clone 한 저장소에서나 사용할 수 있습니다.
그러니까 이 명령을 5분 전에 Clone 한 저장소에 사용하면
아무 결과도 나오지 않습니다.
리비전 조회하기
branch 관계로도 커밋을 표현할 수 있습니다.
이름 끝에 "^" 기호를 붙이면 Git은 해당 커밋의 부모를 찾습니다.
리비전 조회하기
리비전 조회하기
리비전 조회하기
branch로 표현하는 방법으로 "~" 라는 것도 있습니다.
HEAD~ 와 HEAD^ 는 똑같이 첫 번째 부모를 가리키지만,
그 뒤에 숫자를 사용하면 달라집니다.
HEAD~2 는 명령을 실행할 시점의 “첫 번째 부모의 첫 번째 부모”,
(같은 branch의 부모) 즉 “조부모” 를 가리킵니다.
하지만, HEAD^2 는 "Reflog"의 순서를 가져와서 표현합니다.
리비전 조회하기
지금까지는 하나의 commit 을 확인하는 방법을 알아보았습니다.
이제부터는 범위를 주고 여러개의 commit들을 확인하는 방법들을
알아보겠습니다.
리비전 조회하기
Double Dot
리비전 조회하기
Double Dot
리비전 조회하기
리비전 조회하기
Double Dot을 사용하면 원격 저장소의 브랜치에는 있고
현재 checkout 중인 로컬 브랜치에는 없는 commit
또한, 쉽게 알수 있습니다.
리비전 조회하기
리비전 조회하기
Triple Dot
리비전 조회하기
대화형 명령
Git은 대화형 명령어도 제공해서 좀 더 쉽게 사용할 수 있습니다.
대화형으로 커밋할 파일을 고를 수도 있고 수정된 파일의 일부분만 커밋할 수도 있습니다.
대화형 명령
Stashing & Cleaning
어떤 프로젝트에서를 작업하고 있는데, 다른 요청이 들어와서
잠시 브랜치를 변경해야 할 일이 생겼다.
그런데 이런 상황에서 아직 완료하지 않은 일을 커밋하는 것이
문제가 될 때, 커밋하지 않고 나중에 다시 돌아와서 작업을 하기 위해
현재 변경사항을 저장하고 싶으면 git stash 라는
명령으로 해결할 수 있다.
Stashing & Cleaning
Stashing & Cleaning
저장된 내용은 "git stash list"를 통해 확인 할 수 있으며,
다른 브랜치로 이동해서 해당 내용을 적용 할 수 도 있습니다.
Stashing & Cleaning
내용을 적용 할 때, "git stash apply" or "git stash pop" 를 통해
저장된 내용을 적용 할 수 있습니다.
"pop"과 "apply"의 차이점은 pop은 list에서 내용을 삭제하면서
저장된 내용을 추가하고 apply는 저장된 내용을 유지합니다.
Stashing & Cleaning
"stash" 명령어를 사용할 때 staging 된 내용도 옵션을 적용하지 않으면 unstaging 상태로 내용이 반환 됩니다.
저장된 내용을 다시 가져올 때"--index" 명령을 주면
staging을 유지하면서 내용을 다시 가져옵니다.
Stashing & Cleaning
"stash" 명령어를 사용할 때 "--patch" 옵션을 주면 모든 수정사항을
저장하는게 아니라 일부분만 저장할 수 있습니다.
Stashing & Cleaning
"stash" 명령어로 내용을 저장한 후 다른 작업을 하다가 저장된 내용을 불러오려고 할때 충돌이 발생 할 수 있습니다.
이럴 때, git stash branch <branch_name> 을 사용하면
stash할 당시의 commit을 checkout 한 후 새로운 브랜치에
stash 내용을 가져옵니다.
Stashing & Cleaning
"clean" 명령을 사용하면 working directory에 있는
불필요한 파일들을 지울 수 있습니다.
"checkout" 명령어와의 차이점은 checkout은 기존의 modified된
파일이나 "status" 에서 확인되는 처리해야 할 작업을 완료 한 후
사용할 수 있지만 "clean" 명령어의 경우 "-f" 명령을 적용하면
working directory에 있는 파일들을 정리 할 수 있습니다.
Stashing & Cleaning
"clean" 명령을 사용하면 working directory에 있는
불필요한 파일들을 지울 수 있습니다.
"checkout" 명령어와의 차이점은 checkout은 기존의 modified된
파일이나 "status" 에서 확인되는 처리해야 할 작업을 완료 한 후
사용할 수 있지만 "clean" 명령어의 경우 "-f" 명령을 적용하면
working directory에 있는 파일들을 정리 할 수 있습니다.
검색
Git은 데이터베이스에 저장된 코드나 커밋에서 원하는 부분을 빠르고 쉽게 검색하는 명령어로 "grep"이 있습니다.
이 명령어는 일반적인 unix의 grep 이나 ack 명령어보다
훨씬 빠르며, 워킹 디렉토리만이 아니라 Git 히스토리 내의
어떠한 정보라도 찾아낼 수 있습니다.
검색
"grep" 명령어를 사용할 때 -n이나 -l 같은 옵션을 사용하면
검색하고자 하는 함수명의 라인 넘버나
파일명 만을 검색할 수 있습니다.
검색
"grep" 명령어를 사용할 때 -n이나 -l 같은 옵션을 사용하면
검색하고자 하는 함수명의 라인 넘버나
파일명 만을 검색할 수 있습니다.
검색
어떤 변수가 어디에 있는지를 찾아보는 것 뿐만 아니라,
Git history 에서 언제 추가되거나 변경됐는지 찾아볼 수도 있습니다. "git log" 명령어를 사용하면 Diff 내용도 검색하여
어떤 커밋에서 찾고자 하는 내용을 추가했는지 찾을 수 있습니다.
검색
히스토리 단장하기
Git으로 일하다 보면 어떤 이유로든 로컬 커밋 히스토리를 수정해야 할 때가 있습니다. 커밋 후 사소한 오타 수정이나 추가되는 코드 등등
원격저장소로 커밋을 내보내기 전까지 최종 결정을 나중으로 미룰 수 있던 것은 Git의 장점입니다.
히스토리 단장하기
단 커밋의 수정은 원격 저장소로 자신의 커밋을 내보내기 전에
해야합니다. 대부분의 수정은 기존의 커밋이 가지고 있던 SHA-1
해쉬 값은 변경하기 때문에 원격 저장소에 있던 해쉬값과 달라지면
큰 문제가 발생할 수 있습니다.
히스토리 단장하기
히스토리를 단장하는 일 중에서 마지막 커밋을 수정하는 것은
가장 자주 하는 일입니다.
히스토리 단장하기
기본적으로 두 가지로 나눌 수 있는데 하나는 단순히 커밋 메시지만을 수정하는 것이고 다른 하나는 나중에 수정한 파일을 마지막 커밋 안에 밀어넣는 것입니다.
히스토리 단장하기
히스토리 단장하기
만약 여러 개의 커밋들을 수정해야 할 경우 "rebase" 명령어를
사용해야 합니다.
히스토리 단장하기
히스토리 단장하기
갑자기 누군가 생각 없이 "git add . " 같은 명령을 실행해서
공룡 똥 덩어리(💩💩💩)를 커밋했거나 실수로 암호가 포함된 파일을 커밋해서 이런 파일을 다시 삭제해야 하는 경우 어떻게 해야할까요?
히스토리 단장하기
이런 상황은 생각보다 자주 발생합니다.
이 때 filter-branch 명령어는 히스토리 전체에서 필요한 것만
골라내는 데 사용하는 도구입니다.
filter-branch 의 --tree-filter 라는 옵션을 사용하면 히스토리에서
특정 파일을 아예 제거할 수 있습니다.
히스토리 단장하기
히스토리 단장하기
--tree-filter 옵션은 프로젝트를 Checkout 한 후에 각 커밋에 명시한 명령을 실행시키고 그 결과를 다시 커밋합니다.
이 경우에는 각 스냅샷에 passwords.txt 파일이 있으면
그 파일을 삭제합니다.
히스토리 단장하기
이 명령은 모든 파일과 커밋을 정리하고 브랜치 포인터를
다시 복원해줍니다.
이런 작업은 테스팅 브랜치에서 실험하고 나서 master 브랜치에 적용하는 게 좋습니다.
By yesdoing