git config --global core.autocrlf true
협업 시 윈도우와 맥에서의 엔터 방식 차이로 인한 오류를 방지해 줌
배울 땐 CLI로 최대한 익히고, 숙련되면 GUI랑 혼용해서 쓰면 됨
GUI로 하는게 더 편한 작업들도 분명히 있음
다만 섬세한 작업은 CLI로 해야하기 때문에 반드시 CLI를 숙련시켜놔야함
git 전역으로 설정하는 사용자 이름과 이메일임
github 계정과는 별개임
git으로 협업하면서, 누가 커밋했고 그 사람 연락처는 뭔지 파악할 수 있음
전역에 기초로 셋팅해두는거고, 추후 프로젝트마다 따로 다르게 설정할 수도 있음
git 관점에서 프로젝트 폴더의 상태 관찰 (업뎃된 내용, 추가된 파일 등)
.gitignore (확장자 안 적어도 됨) 라는 이름의 파일 생성 후, 여기에 배제할 파일명들 적어주면 됨. 그럼 알아서 적용됨
이 .gitignore 파일을 작성하는 규칙이 있는데
https://git-scm.com/docs/gitignore
여기를 참고하면 됨
# 이렇게 #를 사용해서 주석
# 모든 file.c
file.c
# 최상위 폴더의 file.c
/file.c
# 모든 .c 확장자 파일
*.c
# .c 확장자지만 무시하지 않을 파일
!not_ignore_this.c
# logs란 이름의 파일 또는 폴더와 그 내용들
logs
# logs란 이름의 폴더와 그 내용들
logs/
# logs 폴더 바로 안의 debug.log와 .c 파일들
logs/debug.log
logs/*.c
# logs 폴더 바로 안, 또는 그 안의 다른 폴더(들) 안의 debug.log
logs/**/debug.log
reset : 원하는 시점으로 돌아가고 그 이후 내역들을 지움
revert : 특정 커밋을 수행 이전 상태로 역작업(추가, 삭제 등등)을 수행한 새로운 커밋을 하나 만든다. (이 때 특정 커밋 이후의 커밋의 내용은 그대로 유지. 특정 커밋 그 내용만 되돌리는거임)
만약 특정 커밋에서 적용된 내용을 이후 커밋 어딘가에서 이어서 뭔가 또 변경했다면 revert에서 충돌이 발생함. 이는 수작업으로 해결 후 continue 하면 됨
팀에서 이미 공유되버린 커밋은 reset을 하면 심각한 충돌이 발생할 수 있으므로, revert를 쓰면 된다.
만약 revert로 특정 커밋을 쏙 빼내고, 다른 변경 사항도 추가해서 커밋을 만들고 싶다면, --no-commit 옵션을 통해 revert 커밋을 바로 생성해내지않게할 수 있다. 취소하려면 가장 최근 커밋으로 돌아가기 위해 git reset --hard 해주기
push할 때 rebase는 가급적 사용하지말기. 그러너 pull할 때는 써도 됨!
HEAD는 항상 브랜치의 가장 최신 커밋에 위치함. 그런데 git checkout HEAD~2로 두 단계 이전 커밋으로 돌아가면 그 때는 최신 커밋에 위치한게 아니게 되는데?
이는, 실제로는 두 단계 이전 커밋을 최신 커밋으로 가지고 있는 또 다른 브랜치로 이동하게 되는 원리로 동작한다.(익명 브랜치) 그래서 터미널에서도 보면 브랜치 이름이 웬 첨보는 해시값으로 돼있다.
그래서 만약 HEAD를 다시 원래 브랜치 최신 커밋으로 옮기고싶으면, 브랜치와 브랜치 간의 이동이므로 git switch 로 이동해주면 된다.
원격의 어떤 브랜치를 로컬에 옮기고, 원격과 커밋 주고받게 연결도 해두고 싶으면 git switch -t 를 활용하면 된다.
git add -p : 파일 내 hunk별로 직접 확인 후 hunk 단위로 부분적으로 스테이징가능 (즉, 파일의 일부분만을 add 할 수가 있음)
커밋을 한 직후에 뭔가 깜빡한 변경 사항이 하나 더 생기고 이걸 수정했는데 직전 커밋에 넣었어야 할 내용이었다면, git commit --amend로 넣어줄 수 있음
git rebase -i 를 쓰면 된다.
왜 rebase인지는 원리를 보면 이해할 수 있다.
만약 과거 특정 커밋을 수정하고싶다면, 그 이후 커밋들에게도 영향이 갈 수 있다.
그래서 git은 과거 특정 커밋을 최신으로 하는 브랜치를 따로 임시로 만들고, 거기에 수정을 반영한 후, 원래 있던 이후 커밋들을 해당 브랜치에 rebase로 이어붙이는 식으로 진행한다. 그래서 rebase인 것이다.
만약 공통 자식 커밋을 가지고 있는 두 브랜치에 대해, 뒤처져있는 브랜치를 앞선 브랜치에 merge 해주면 이건 fastforward임. 이후 합친 다른 브랜치는 제거해주기. 근데 이러면 브랜치 하나가 없어지긴함. 만약 이게 싫고 앞서있던 브랜치를 남겨두고 싶다면 git merge --no-ff (브랜치명) 을 해주면 됨.
특정 커밋으로부터 분기된 두 브랜치가 각각이 커밋들을 갖고 있다면, merge시 충돌은 나지 않는지, 충돌이 났다면 어디서 났고 어떤 내용이 충돌한건지 파악하기 위해 git은 두 브랜치의 공통 조상 커밋과 두 브랜치의 두 커밋을 비교함. 이래서 3-way merge라고 부름
다른 브랜치의 특정 커밋을 복제해서 내 브랜치에 최선 커밋으로 똑같이 하나 만들어내는 것
git rebase --onto (도착 브랜치) (출발 브랜치) (파생 브랜치)
이걸 쓰면 된다.
만약 그냥 rebase로 하게 될 경우에는, 파생 브랜치에 더하여 그 조상인 A 브랜치의 분기 커밋까지 포함될 것이다.(제대로 이해한게 맞나?)
git merge --squash (가져올 브랜치) 를 쓰면 된다.
수행 후, 대상 파생 브랜치의 커밋들 모든 내용이 스테이지에 올라오게 된다. 이걸 커밋해주면 비로소 파생 브랜치의 모든 커밋 내용이 내 브랜치의 한 커밋에 합쳐서 복제되게 되는 셈이다.
이 때, 파생 브랜치는 없어지지않고 그대로 남아있다.
main : 사용자에게 실제로 배포되는 브랜치
develop : 기능 추가 등 다음 배포를 위한 개발을 진행하는 브랜치
feature branches : 굵직한 기능들을 develop에서 또 따로 브랜치 파서 작업하고, 이걸 develop에 병합
release branches : develop 브랜치가 현재 커밋까지 기준으로 이제 배포할만한거같다 싶으면, 우선 release branches를 먼저 파서, 테스터들이 이걸 보고 검증을 수행함. 그렇게해서 버그도 없고 괜찮다고 검증 되면 그제서야 main에 병합. 만약 검증 도중 이상이나 버그가 관측되면, 다시 develop 브랜치로 파서 수정 후 다시 release branches로 가서 검증
hotfixes : 기존의 출시된 main에서 버그가 생겼는데 빨리 고쳐야만 하는 사항일 때, hotfixes 브랜치를 파서 고치고 바로 main 브랜치에 병합
git blame 을 쓰거나, vscode의 gitlens 익스텐션을 활용하자. 인텔리제이같은 IDE에도 이런 확장 있음. 검색해보면 됨
메인에서 서브모듈 프로젝트 폴더 내의 파일 변경에는 관여하지 않는다. (git status에서 내역은 보이지만 add나 commit 시 그 파일은 제외)
그런데 서브모듈 프로젝트 내의 git에 의해 어떤 커밋을 수행한 후, 다시 메인 git에서 add해보면 이 때는 뭔가 추가가 됨. 이 것은 나중에 메인을 클론땡겼을 때, 서브모듈의 커밋 변경 사항들을 같이 알려줘서 써먹을 수 있도록 하기 위함임.
OctoTree : 레포 폴더 탐색을 더 쉽게 할 수 있는 크롬 확장 프로그램
GitHub CLI : 깃헙 웹 페이지에서 하던걸 CLI에서 할 수 있음.
https://cli.github.com/manual/gh_pr
이 매뉴얼을 참고하자. 명령어는 직관적이라 러닝커브가 높지 않아서 쓰기 좋고 편함