코드를 짜다가 2일 전 코드로 되돌아가고 싶다면?
보통은 git이라는 버전관리 소프트웨어를 쓴다.
구글에 git window 버전 다운받아서 설치하면 끝

이 2개를 잘 체크해야 한다. 그래야 나중에 깃 사용할 때 편해진다.
구글에 homebrew를 검색해서 설치
시키는대로 터미널에 설치 명령어를 입력하면서 진행하면 된다.

설치 후에 이런 식으로 명령어를 입력하면 기본 브랜치 이름을 main으로 바꾸거나, 기본 깃의 에디터를 빔이 아닌 vs코드로 바꿀 수 있다.
1.아무 폴더 만든 후에 시프티 + 우클릭을 하고 powerShell 창 열기를 누른다.
2.터미널을 연 후

이런 식으로 이메일과 이름을 입력해준다.
지금 깃을 누가 쓰고 있는지 아이디 등록을 하는 것이다.
git의 commit 기능을 쓰면 쓰면 파일의 현재상태를 매일매일 기록해둘 수 있다.
정확히 말하면 파일의 스냅샷을 저장해준다.
그럼 원할 때 쉽게 되돌아가거나 그럴 수 있다.
오늘은 파일의 현재상태를 기록해줄 수 있는 git commit 명령어를 알아보자.

vs코드의 터미널을 열어서 git init 부터 입력하고 시작
이제 git이 내가 파일생성하는 거, 코드작성하는걸 추적하기 시작한다.
보통 간단한 기능 하나를 추가, 수정할 때마다 커밋한다.

만약 오늘 짠 코드가 마음에 들었다면
이렇게 영구적으로 기록해서 나중에 이 상태로 되돌리거나, 히스토리 조회도 할 수 있다.
왜 굳이 2개를 입력하는지?
모든 파일을 기록할 필요가 없으므로
ex) 이미지 파일이 있을 경우 굳이 버전을 기록할 필요가 없다.
다음 항목을 참고하자.

1.작업폴더에서 기록을 남기고 싶은 파일을 gid add라는 명령어로 고른다.
2.gid commit 명령어로 저장소에 옮긴다.
사실 웬만한 에디터에는 깃 기능이 내장되어 있다.

VSCode 에디터의 경우 왼쪽 git 처럼 생긴 메뉴 들어가보면 지금 어떤 파일이 변경되고 추가되었는지 쭉 알려준다.
체크마크 누르면 git commit 한거랑 똑같다.
파일이 많고 복잡하면 이거 쓰는게 더 나을 수도 있다.
ex) 코드 조금 수정 후 터미널에 git diff 입력

그럼 현재 파일이 최근 commit과 어떤 부분이 달라졌는지 알려준다.
근데 Vim 에디터가 오픈되어서 스크롤은 j, k / 종료는 q 연타해야 한다.
하지만 터미널의 한계로 차이점보기가 힘들고 설정 안만지면 쓸데없이 엔터키나 스페이스바 변동사항도 다 알려주기 때문에 보통은 git diff를 쌩으로 사용하진 않는다.
git diff 커밋id
최근 commit과 비교하는게 아니라 과거의 특정 commit과 현재 파일을 비교하고 싶으면 커밋ID를 명시
git log --oneline 이런거 입력하면 보이는 노란 글자들git diff 커밋id1 커밋id2
과거의 특정 commit 2개 간의 차이점 비교도 가능
비주얼적으로 훌륭하게 차이점을 분석해줌
이것도 Vim 에디터가 뜨는데 hjkl 키로 이동가능하고 :q 여러번 입력해야 나갈 수 있습니다. 아니면 :qa 입력하자.
실은 Vim 에디터와 터미널의 한계로 그렇게 편리하진 않다.git difftool을 Vim 말고 VSCode로 열고 싶으면
git config --global diff.tool vscode
git config --global difftool.vscode.cmd 'code --wait --diff $LOCAL $REMOTE'
터미널에 차례로 2개 입력하면 된다.
SCode 에디터의 경우 좌측 Extensions 메뉴에서 Git 관련 부가기능 설치 아무거나 해주면 더 편리하게 git diff 할 수 있다.

VSCode 에디터 extension 메뉴에서 git 검색해서 아무거나 설치(사진에선 Git graph 부가기능)

왼쪽 Git 메뉴 - Git graph 버튼 누르면
commit 내역을 한 눈에 쭉 살펴볼 수 있고 파일명 우클릭하면 git diff도 가능하니
과거 내역을 살펴보고 싶으면 이런 GUI 툴을 주로 활용해보자.
커밋하면서 계속 코드짜다보면 갑자기 새로운 기능을 추가하는 등의 경우가 있다.
이럴 때 원본파일에 커밋하는 것도 좋지만 프로젝트의 복사본을 만들어서 거기에 먼저 개발해보는게 안전하다.

git branch 브랜치이름
프로젝트 사본이 하나 생성
git switch 브랜치이름
브랜치 이동
예를 들어 방금 만든 coupon 브랜치로 이동하고 싶으면 git switch coupon 하면 된다.
이제 이동한 새로운 branch에서 개발을 하면 된다.

현재의 상황은 이렇다.
이전의 branch는 main branch 또는 master branch 라고 부르고 새로만든 branch에서 작업한 내용은 원래 브랜치인 main branch에 아무런 영향이 없다.
git log --graph --oneline --all
branch 와 commit 내역을 한 눈에 그래프로 볼 수 있다.

여기서 HEAD는 나의 현재 위치다.
원본코드가 있는 master 또는 main 브랜치에 합쳐보자.
브랜치를 합치는걸 전문용어로 merge라고 한다.

git switch main
git merge 브랜치명
merge 하고 싶으면

merge 하고 나서 git log 이런거 해보면 이쁘게 합쳐줬다고 알려준다.
주의사항

master 브랜치와 coupon 브랜치에서 같은 파일, 같은 줄을 수정했을 경우 merge conflict 가 발생

둘 중 어떤 코드를 적용할지 고르면 되는데
<<<< / >>>> / ==== 이런 쓸데없는 것들은 다 지우고 원하는 코드만 남기면 된다.
(VSCode 에디터의 경우 Accept Incoming Change 어쩌구 버튼들을 제공해주는데 그거 누르면 편리)
어떤 코드를 남길지 결정했으면
브랜치 생성은 git branch 브랜치명
브랜치 이동은 git switch 브랜치명
브랜치 합치기는 main/master 브랜치로 이동한 뒤에 git merge 브랜치명
브랜치마다 commit 내역을 그래프로 보고싶으면 git log --graph --oneline --all
브랜치 합칠 때 conflict가 발생하면 파일열어서 수정하고 git add, git commit 하기
저번시간에 했던 것 처럼
브랜치에 각각 신규 commit이 1회 이상 있는 경우
merge 명령을 내리면 두 브랜치의 코드를 합쳐서 새로운 commit을 자동으로 생성해주는데

이걸 3-way merge 라고 부른다.
이게 merge의 기본 동작방식이다.
가끔은 새로운 브랜치에만 commit 이 있고
기준이 되는 브랜치에는 신규 commit 이 없는 경우가 있다.

이 경우 merge 하게 되면 "fast-forward merge 되었습니다" 라고 알려준다.
그래서 "기준이 되는 브랜치에 신규 commit이 없으면" 자동으로 fast-forward merge가 발동
싫으면 git merge --no-ff 브랜치명 해서 강제로 3-way merge 할 수도 있다.
-way, fast-forward 아무렇게나 merge 해도 브랜치를 merge 하고 나면 브랜치가 자동으로 삭제되진 않는다.
둘 중 하나 사용하면 이제 필요없는 브랜치를 삭제할 수 있다.
브랜치를 rebase 하고 나서 merge 하는 짓거리도 가능
브랜치의 시작점을 다른 commit으로 옮겨주는 행위

git switch 새로운브랜치
git rebase main
git switch main
git merge 새로운브랜치
차례로 입력하면 rebase 끝
rebase & merge를 한 줄로 쉽게 비유하자면 강제 fast-forward merge
브랜치끼리 차이가 너무 많은 경우 rebase하면 충돌이 많이 발생할 수 있는데 그거 하나하나 해결하기 귀찮다.
대충 모든 브랜치를 3-way merge 해버리면 나중에 참사가 일어날 수 있다.

왜냐면
1. 3-way merge 된 것들은 매우 복잡해보임
2. main 브랜치 git log 출력해보면 3-way merge된 브랜치들의 commit 내역도 다 같이 출력되어서 더러워짐
이런 현상이 있다.
그러기 싫으면 rebase 아니면 squash and merge 하면 된다.
그거 쓰면 새로운 브랜치에 있던 commit 들을 연결해주는게 아니라 똑 떼와서 main 브랜치에 붙여주기 때문에 1번과 2번걱정을 안해도 된다.
rebase는 아까 배웠고
squash and merge 이거 하면 어떻게 되냐면
3-way merge처럼 선으로 이어주지 않고
새 브랜치에 있던 코드변경사항들이 main 브랜치로 텔레포트한다.

그럼 이제 main 브랜치의 git log 출력해볼 때 merge 완료된 브랜치의 commit 같은 것들은 출력되지 않는다.

그냥 merge 했을 경우

merge --squash 했을 경우
결과는 둘 다 똑같은데 한 놈은 선으로 이어져있고 한 놈은 텔레포트했을 뿐
브랜치 100개 만들어놨는데 일반 merge를 잔뜩 해놓으면 나중에 git log 그래프가 매우 복잡해질 수 있다.
그게 싫으면 squash 해보자. 또는 rebase 해도 마찬가지로 해결가능하다.
초보땐 squash 할지 말지 고민하지 말고 대충하자.
나중에 코딩노예로 취직하면 중요한 브랜치마다 merge 방법 가이드라인이 있다.
없으면 퇴사하거나 기준같은 걸 하나 만들어두면 좋다.