반응형
도서명 | 쪽수 | 저자, 출판사 | 발행일 | |||||
Git 교과서 : 코드 이력, 하나도 놓치지 마라! |
432 | 이호진 저, 길벗 | 2020년 03월 16일 |
1. 깃과 버전 관리
- 깃 : 현재 가장 널리 사용하는 분산형 버전 관리 시스템 (Distributed Version Control System)
- 깃허브 : 깃을 이용하여 서비스를 운영하는 호스팅
2. 깃과 소스트리 설치 및 환경 설정
- 깃 설치
- https://git-scm.com/
- Latest source Release 2.43.2
- https://git-scm.com/
- 깃 실행 → git
- 터미널에서 git 명령어를 통해 사용 → git help -all
- 여러 명령어 묶어서 입력할 때는 세미콜론(;) 로 구분
- 사용자 등록
- git config -global user.name "사용자영문이름"
- git config -global user.email "이메일주소"
- 경로 확인 → ls ~/.gitconfig
3. 깃 개념 잡기
- 깃 저장소 생성
- 디렉토리 생성 → mkdir 디렉토리명
- 디렉토리 이동 후 깃 저장소로 변경 → cd 디렉토리명; git init
- 깃 상태 확인 → git status
- 워킹 디렉터리 (working) : 작업을 하는 공간, untracked 상태
- 스테이지 (stage) : 임시로 저장하는 공간. git add 명령어 를 통해 tracked 된 상태.
파일이 수정되면 modified 상태가 되고 스테이지에서 떨어져 나와 unstage 상태가 됨. - 레파지토리 (repository) : 실제로 저장하여 기록하는 공간
- 깃에서 관리하지 않는 파일들의 목록은 .gitignore 로 관리 (저장소 폴더의 최상위 디렉터리에서)
- 깃 저장소 복제 → git clone 원격저장소URL 새폴더이름
4. 커밋
- commit : 의미 있는 변경 작업들을 저장소에 기록하는 동작
- 스테이지에 등록되지 않은 unstage 상태의 파일들은 커밋할 수 없음
- git add 명령어 로 추가한 스테이지 영역의 파일 등록 취소 → git rm -cached 파일명
한번이라도 커밋 된 파일일 경우 리셋으로 삭제 → git reset HEAD 파일명 - HEAD 란 최종적인 커밋 작업의 위치를 가리키는 묵시적 참조 포인터
- 깃은 스냅샷 방식을 이용 (파일에서 변경된 부분을 찾아 수정된 내용만 저장하여 버전을 관리)
- 스테이지 파일 커밋 → git commit or git commit -m "커밋메시지"
- 파일 등록과 커밋 동시에 → git commit -a or git commit -am "커밋메시지"
- 로그 기록 확인 → git log
- 수정한 파일을 커밋 전 마지막 내용으로 되돌리기 → git checkout - 수정파일이름
- 마지막 커밋 메시지 수정 → git commit -amend
- 특정 커밋 상세 정보 확인 → git show 커밋ID
- 특정 파일의 로그 → git log 파일명
- 워킹 디렉터리와 스테이지 영역 간 변경 사항 확인 → git diff
- 스테이지 영역과 최신 커밋 내용 비교 → git diff head
5. 서버
- 새 저장소 생성 : 깃허브 → repositories → new
- HTTP 프로토콜 : 기존 아이디와 비밀번호만으로 접속자 인증 처리
- SSH 프로토콜 : 깃에서 권장하는 프로토콜, ssh://계정@주소, 공개키는 서버에 개인키는 로컬에 저장
- 원격 저장소에 연결 → git remote add 원격저장소별칭(origin) 원격저장소URL
- 원격저장소별칭 변경 → git remote rename 변경전 변경후
- 원격저장소 상세 정보 조회 → git remote show 원격저장소별칭
- 원격저장소 삭제 → git remote rm 원격저장소별칭
- push (로컬 저장소의 커밋을 원격 저장소로 업로드) → git push 원격저장소별칭 브랜치이름
- clone (기존 저장소를 이용하여 새로운 저장소를 생성) → git clone 원격저장소URL
- pull (원격 저장소의 갱신된 내용을 현재 브랜치로 자동 병합하여 내려 받음) → git pull
- fetch (원격 저장소의 갱신된 내용을 현재 브랜치에 수동으로 내려 받음) → git fetch 원격저장소URL
여러 개발자와 협업으로 코드를 작성할 때는 충돌 문제가 있을 수 있어서 fetch 방식을 사용하는게 좋음 - merge (fetch는 데이터를 내려받기만 할 뿐 자동병합하지 않기에 merge 병합을 실행해줘야 함) → git merge 원격저장소별칭/브랜치이름
- 충돌 방지 작업 순서 : pull (fetch) → coding → commit → pull (fetch) → push
6. 브랜치
- branch : 나뭇가지, 지사, 분점 등 줄기 하나에서 뻗어 나온 갈림길을 의미. 저장 공간 하나에서 가상의 또 다른 저장 공간을 만드는 것 (개발 분기점)
- 깃은 기본적으로 master 브랜치를 가지고 있음
- 브랜치 생성 (현재 HEAD 포인터를 기준으로 생성) → git branch 브랜치이름 커밋ID
브랜치 이름은 중복해서 사용하지 못함 - 브랜치 조회 → git branch -v
- 원격 저장소 브랜치 조회 → git branch -r
- 모든 브랜치 조회 → git branch -a
- 복제한 트래킹 브랜치 조회 → git branch -vv
- 브랜치 해시 확인 → git rev-parse 브랜치이름
- 다른브랜치로 위치이동 → git checkout 브랜치이름
- 이전브랜치로 위치이동 → git checkout -
- 특정 커밋 해시키로 이동 → git checkout 커밋해시키
HEAD 포인터를 사용하여 이동도 가능
체크아웃을 사용하여 브랜치를 이동할 때는 현재 작업하고 있는 워킹 디렉터리를 정리하고 넘어가야 함 (커밋 또는 스태시) - 브랜치 생성과 위치이동 동시에 → git checkout -b 브랜치이름
- 브랜치 로그 확인 → git log -graph -all
- AHEAD : 서버로 전송되지 않은 로컬 커밋 존재 / BHEAD : 로컬 저장소로 내려받지 않은 커밋 존재
- 로컬 저장소의 브랜치를 원격 저장소에 푸시 → git push -u 원격저장소별칭 선택한브랜치명
이름 다르게 푸시 할 경우 → git push -u 원격저장소별칭 선택한브랜치명:다른브랜치명 - 기존에 있는 브랜치를 원격 저장소로 트래킹 브랜치 설정 (업스트림 연결) → git branch -u origin/브랜치이름
- 브랜치 삭제 (다른 브랜치로 이동 후) → git branch -d 브랜치명 ( 커밋까지 강제 삭제 시 : -D )
- 원격저장소 브랜치 삭제 → git push origin -delete 리모트브랜치명
7. 임시 처리
- 스태시 : 현재 작업 중인 내용은 임시 저장되고, 수정 전 마지막 커밋 상태로 돌아감 워킹 디렉터리에 커밋되지 않은 변경 사항들이 남아있을 경우 작업 브랜치를 변경할 수 없는데, 이때 스태시에 임시 저장하고 작업 브랜치를 변경 할 수 있음. 스태시를 사용하지 않을 경우 강제 커밋 후 다시 리셋해서 복원해야함.. 스태시 사용 추천
- 스태시 저장→ git stash
- 스태시에 저장된 스택 확인 → git stash list
- 스태시 내용 비교 확인 → git stash show -p 스태시이름
- 임시저장된 스태시 불러오기-이동 (불러오는 동시에 저장된 스태시 삭제함) → git stash pop
- 임시저장된 스태시 불러오기-복사 (저장된 스태시 삭제하지 않음) → git stash apply
- 새로운 브랜치 생성 후 스태시 불러오기 → git stash branch 브랜치이름
- 스태시 삭제 → git stash drop
사용한 스태시는 그때그때 삭제하여 정리하는 것이 좋음 - 워킹 디렉터리 청소 (추적되지 않는 모든 파일 삭제) → git clean
8. 병합과 충돌
- 병합 : 분리된 각각의 브랜치에서 수정된 사항을 하나의 브랜치로 병합 현재 브랜치를 기준으로 다른 브랜치의 모든 커밋을 병합 → git merge 브랜치이름
- 병합 방식
- Fast-Forward (빨리감기)
- 브랜치가 분기되지만 전체 커밋 그림으로 보면 모든 변경 사항은 순차적으로 진행됨. 일반적으로 혼자 개발할 때 사용. 원본에 추가된 내용이 없다는 가정하에 변경한 파일을 대체하는 것.
- 3-way
- 여러 개발자와 협업으로 작업할 경우. 기준 커밋에서 서로 다른 브랜치의 커밋이 연결됨. 병합 시 병합 메시지가 필요함, 병합한 후에 새로운 커밋을 하면서 동시에 메시지가 자동 생성됨.
- Fast-Forward (빨리감기)
- 깃 플로 (git flow) : 브랜치 관리 기법. master, feature, develop, release, hotfix 브랜치
- 병합 후 삭제 → git branch -d 브랜치이름 ( 병합을 완료하지 않은 브랜치 삭제 시 -D )
- 충돌 : 여러 사람과 개발 시 같은 위치의 코드를 수정 할 경우 발생 (Merge Conflicts) git status 확인 시 “Unmerged” 메시지 출력
- 충돌 해결 방법
- 수동으로 충돌 해결
<<<<<<<<<<<<<< HEAD
master 브랜치 내용
===================
병합하고자 하는 브랜치 내용
>>>>>>>>>>>>> 브랜치이름
위와 같은 충돌 내용을 확인한 후 코드를 직접 수정하고 저장 후 커밋
- 수동으로 충돌 해결
- 브랜치 병합 여부 확인 (병합한 브랜치는 * 기호로 표시 됨) → git branch --merged
- 병합하지 않은 브랜치 확인 → git branch --no-merged
- 리베이스 : 커밋 순서를 재배열하여 브랜치를 합치는 병합 방법 → git rebase 브랜치명
- merge 는 두 브랜치를 순차적으로 커밋을 비교하면서 마지막 최종 커밋을 생성하지만, rebase 는 두 브랜치를 서로 비교하지 않고 순차적으로 커밋 병합을 시도함
- merge 는 현재의 기준 브랜치에서 다른 브랜치를 읽어와 결합하지만, rebase 는 병합되는 브랜치 방향이 반대임
- rebase 충돌 시 → git rebase -continue
- rebase 취소 시 → git rebase --abort
- 여러 커밋을 한개의 커밋으로 묶을 경우 → git rebase -i HEAD~3
- 저장소를 외부에 공개했다면 커밋은 rebase 를 사용하지 않는 것이 원칙이다. (커밋 위치와 해시 값이 변경되기 때문에 혼란스러울 수 있음)
9. 복귀
- 리셋(reset) : 커밋을 기준으로 이전 코드로 되돌리는 방법, 기록한 커밋을 취소 → git reset --옵션 커밋ID
- reset 옵션
- soft : 스테이지 영역을 포함한 상태로 복원 (커밋 실행 직전)
- mixed : default, 생략 가능, unstage 상태 (커밋하려면 add 먼저 실행 해야 함)
- hard : 실제 파일이 삭제된 이전 상태로 복원, 워킹 디렉터리 내용도 함께 삭제 됨
- 저장소를 외부에 공개했거나 공유하고 있다면 reset 작업을 하지 않음. 작성된 커밋이 reset으로 삭제되면 함게 작업하는 개발자에게 혼란을 줄 수 있기 때문
- 리버트 (revert) : 기존 커밋을 남겨두고 취소에 대한 새로운 커밋을 생성 → git revert HEAD or git revert 커밋ID
- 리버트로 병합 취소 → git revert --mainline 숫자 병합커밋ID
10. 배포 관리와 태그
- SemVer (Semantic Versioning) 방식 : 각 자리 마다 메이저 버전, 마이너 번호(기능), 패치(버그수정) 버전 을 표기함
ex) 1.0.3 , 정식 버전은 1부터 시작 - 태그 (tag) : 특정 커밋의 해시 값을 가리키는 꼬리표, 코드 버전 구별
- 태그 조회 → git tag -l --list
- 태그 상세 조회 → git show 태그이름(버전)
- Annotated 태그 (추가 정보 포함) 생성 → git tag -a 태그이름(버전) or git tag -a 태그이름(버전) -m "메시지"
- 태그 삭제 → git tag -d 태그이름(버전)
- Lightweight 태그 (커밋의 체크섬만 존재) 생성 → git tag 태그이름(버전)
- 특정 커밋 태그 생성 → git tag -a 태그이름(버전) 커밋ID
- 브랜치 대신 태그이름으로 특정 커밋 위치로 체크아웃 가능 (조회용) → git checkout 태그이름(버전)
- 태그로 브랜치 생성 → git checkout -b 브랜치이름 태그이름(버전)
- 원격저장소로 태그 전송 → git push 태그이름(버전) or git push origin --tags
다른이름으로 전송 → git push origin 태그이름:원격저장소태그이름 - 태그 삭제 → git tag -d 태그이름(버전) or git push --delete 서버이름 태그이름 (원격)
11. 서브모듈
- 서브모듈 : 저장소 하나가 다른 깃 저장소를 포함하는 형태, 2개 이상인 저장소를 부모와 자식 관계로 연결
- 메인 저장소에 자식 저장소 연결 → git submodule add 원격저장소URL 폴더이름
- 설정 파일 : 서브모듈 등록 시 생성 됨, 메인 저장소와 연결된 자식 저장소들을 관리 ( .gitmodules )
- 하위 저장소에 새로운 커밋이 생성되면 메인 저장소는 이를 반영함. 추가 커밋 발생, 주기적으로 pull 해주어야 함
- 메인 저장소를 복제할 때는 서브모듈 정보만 같이 복제할 뿐, 실제 하위 저장소는 같이 복제하지 않기 때문에 직접 명령어를 실행하여 가져와야 함 → git submodule init -> git submodule update
12. 고급 기능
- refs
- 커밋은 고유의 SHA1 해시 값 (여러 기능에서 참조) 을 가지고 있으며, 이 값을 refs 목록으로 가지고 있음.
- .git/refs 폴더 안에 저장
- reflog
- 내부적으로 작업한 모든 HEAD 와 브랜치 포인터를 기록 → git reflog
- 현재 로컬 저장소에서 작업한 모든 로그의 참조 기록, 원격으로 옮길 수 없음.
- 파일 애너테이션
- blame: 잘못된 코드를 쉽게 찾을 수 있도록, 커밋의 메타 정보를 코드 라인별로 같이 결합하여 출력 → git blame 파일이름
- 누가 코드의 어느 라인을 수정했는지 파악할 때 유용
- replace
- 기존 커밋을 다른 커밋인 것처럼 변경하는 기능
- 가비지 콜렉트
- 깃은 이력을 추적할때 객체의 생성과 변경을 반복하면서 (대표적으로 reset 또는 rebase 등) 시간이 지남에 따라 연결고리가 없는 고립된 객체들이 생겨 비효율적인 자원 상태가 됨. pack 파일 형태로 압축하여 저장.
- 가비지 정리 명령어 → git gc --auto
- prune
- 고립된 객체를 정리하는 내부 유틸리티 기능
- 실행하지 않고 작업할 내역 출력 → git prune --dry-run --verbose
- 완전히 삭제 → git prune --expire now -v
- 오래된 브랜치 정리 → git fetch --prune
- rerere (reuse recorded resolution)
- 어떤 문제로 충돌이 발생할 때 이를 기록, 충돌을 해결할 때마다 해결한 문제의 유형을 기록, 기록한 유형의 문제와 비슷한 문제가 향후 다시 발생하면 자동으로 적용
- 기능 활성화 → git config rerere.enabled true
반응형
'Version Control System > Git' 카테고리의 다른 글
[Github] README.md 생성, 마크다운 문법, 작성 예시 (0) | 2024.06.29 |
---|---|
[Github] Repository private public 차이, private 유료 여부 (0) | 2024.06.28 |
[Github] Repository private / public 변경 방법 (0) | 2024.06.28 |
[Git] 커밋 메시지, 브랜치 네이밍, 브랜치 작업순서, 레파지토리 네이밍 Convention (0) | 2024.05.30 |