아니 뭐, 쉽다면 쉽다고 할 수도 있겠지만 일단 이게 초보한테 쉽지 않은 게
'상황'에 따라 명령어 적용이 다 달라진다는 거.
개발을 완전 처음 해 본 사람에게 '환경변수' 잡는 게 '골 아픔 수준' 3쯤 된다면 깃은... 5? 6?
깃은 또 분명 나는 맞게 적용한 것 같은데 나도 도저히 이해할 수 없는 이유로 내 작업물을 다 날리기도 하는... <= 초반에 이런 실수 많이 했다...
깃 쓰는 게 까다로운 데 뭐 어쩔 건데?
개발자가 깃 안 쓸 거야?
svn 쓸 거야??
svn을 생각하면 git은 갓이기 때문에 깃 명령어를 열심히 배워 보자!
init, clone, add, commit... 이런 거 하나 하나 알아서 뭐 할 겁니까.
깃 명령어는 프로세스에 맞게 사용해야 한다.
그러니까 '상황극'을 한 번 해 보자.
1) 특정 브랜치에서 클론해 오고 싶어.
(브랜치명은 main으로 가정한다)
Git 저장소 URL 확인 > 터미널 열기 > 작업 디렉토리로 이동 >
git clone -b main https://github.com/yourusername/yourrepository.git
이 명령는 깃아(git)/클론해 줘(clone)/브랜치를(-b)/메인(main)/해당 repo 주소(URL)에서
이런 뜻을 가지고 있다.
왜 이런 형식인지 이해하려고 하지 말자.
언어다.
언어는 그냥 몸으로 받아 들여야 한다.
머리로 이해해도 몸으로 받아 들이지 못 하면 명령어를 칠 수 없다(컴퓨터랑 소통할 수 없다).
여튼 여기까지 했으면 clone이 다 되었을 것이다.
(하나 하나 테스트 안 하고 있어서 안 될 수도...?;)
2) 클론해 온 내용물, 작업 다 했는데 이거 클론한 곳으로 다시 푸시하고 싶어.
터미널 열면 아까 그 자리일 것이다.
클론해 온 자리.
여기서 변경 사항을 커밋하여 푸시하려면
잠깐!
근데 커밋 안 하면 푸시 안 됩니다.
터미널에서 명령어 안 치고 IDE 메뉴창에 막 PUSH 이런 거 보인다고 누르면 PUSH될 거라 생각할 수 있는데 안 됩니다.
이런 식으로 깃 명령어는 '프로세스'를 따라야 제대로 작동한다.
근데 왜 커밋 안 하면 푸시가 안 되는데?
커밋 안 해도 푸시가 되면 원격 저장소와 로컬 저장소의 상태가 일치하지 않게 되기 때문이다.
(그럼 git을 쓰는 이유가 없다...)
아주 그냥 코드 이력이 엉망진창.. 나중에 트래킹 못 한다.
다시 돌아가서,
작업 내용을 커밋한다
git add . # 변경된 파일들을 스테이징 영역에 추가
git commit -m "작업 완료: 변경 내용 요약"
저기 작업 완료 부분은 convention에 맞춰서 바꿔 주는 게 좋다.
이 부분은 다른 장소에서 언급하겠다.
잠깐!
스테이징 영역이란?
쉽게 말해 커밋 전 단계입니다.
마지막 커밋 이후로 변경된 파일들이 그 다음 커밋되기 전에 일시적으로 저장되는 곳입니다.
무대에 오르기 전, 커튼 뒤에 대기하는 곳 있죠?
그런 곳을 생각하시면 됩니다.
이 단계에서 커밋할 파일을 선택할 수 있어 git add ~ 를 쓰는 건데
파일명 일일이 입력하기 힘드니까 그냥 git add . 이런 식으로 씀.
이 다음에 커밋하면 버전이 만들어 짐. 그 다음에 푸시.
이제는 커밋한 변경 사항을 원격 저장소로 푸시하면 된다.
git push origin [branch name]
이 명령어는 git(git아)/푸시해 줘(push)/origin(원격 저장소 이름)/branch name에
이런 식이다.
여기까지 했으면 웬만해서는 푸시가 다 되었을 것이다.
3) 상황극을 3번이나 하려니 기력이 떨어져서 못 하겠다.
모르는 게 있으면 chatGPT와 구글링을 열심히 하자!
https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53
커밋 메시지에도 가이드 라인이 있다.
(commit convention으로 검색해도 좋음)
내가 준수하는 건 아래와 같다.
Feat:, Fix:, Refactor: ~ 이런 식으로 시작할 것
(현재는) 무조건 소문자로 시작할 것(e.g. feat:)
일반적으로는 아래와 같다.
1) 50자 이내로 간결하게 적으세요.
2) 명령문으로 적으세요(헤드에 Feat: 이런 거 넣는 건 알아서.).
3) 첫 글자는 대문자로 시작합니다(그러나 나처럼 소문자로 하는 경우도 있다. 다 케바케임.).
4) 시제를 구분하는 경우도 있습니다(e.g. Fixed, Added, Update).
5) 추가적인 설명도 가능합니다(이 설명은 빈 줄을 넣고 작성하며 변경한 이유, 방식, 주의 사항 등을 포함시킬 수 있다.).
6) 이슈와 연결도 가능하다(e.g. Fix #123: 버그 수정).
7) 맞춤법과 띄어쓰기를 제대로 하는 건 기본이다.
8) 한글 or 영어 중 택1하는 게 좋다(그러나 나는 섞어 쓴다.).
9) 큰 단위로 커밋하는 건 좋지 않다(한 커밋에 변경 사항이 너무 많은 건 정말 좋지 않다.).
커밋 메시지의 목적은 코드 변경 사항을 알기 쉽게 설명하는 것이므로, 다른 사람이 코드를 리뷰하거나 협업할 때 이해하기 쉽도록 명확하고 간결하게 작성하는 것이 중요하다! 이것이 핵심이다!
reset은 커밋을 조작하고 작업 디렉토리와 스테이징 영역을 변경하는 명령어다.
'reset'.
이름만 들어도 느낌이 오지 않는가.
'reset'하는 것이다.
1) Hard Reset
현재 상태의 작업 디렉토리와 스테이징 영역이 있을 것이다.
이것을 이전 커밋한 시점으로 완전히 되돌린다.
이전 커밋부터 지금까지의 변경 사항은 완전히 삭제되며, 특정 커밋 이후의 모든 작업은 사라진다.
git reset --hard [commit]
여기서 [commit]은 리셋하려는 대상 커밋의 식별자 또는 참조를 나타낸다.
이 위치에는 커밋의 해시값, 브랜치 이름, 태그 등을 사용할 수 있다.
git reset --hard abcd1234
git reset --hard main
git reset --hard v1.0
뭐 이런 식으로 하면 해당 커밋 이후의 변경 내용은 다 삭제가 될 것.
2) Soft Reset
--soft 옵션을 사용하면 이전 커밋으로 작업 디렉토리는 유지한 채 스테이징 영역만 초기화한다.
git reset --soft [commit]
3)Mixed Reset(Default)
hard나 soft로 모드 지정 안 하고 그냥 reset하면 default가 'mixed'다.
이 모드에서는 작업 디렉토리의 변경 사항은 유지한 채 스테이징 영역만 초기화된다.
git reset [commit]
총정리
--hard: 작업 디렉토리와 스테이징 영역을 리셋하고, 변경 사항을 모두 삭제합니다.
--soft: 작업 디렉토리는 유지하면서 스테이징 영역을 리셋합니다. 변경 사항은 스테이징되지 않은 상태로 남아 있습니다.
--mixed (기본값): 작업 디렉토리와 스테이징 영역을 리셋하고, 변경 사항을 작업 디렉토리로 이동시킵니다. 변경 사항은 스테이징되지 않은 상태로 남아 있습니다.
git pull은 원격 저장소에서 변경 사항을 가져와서 로컬 브랜치를 업데이트하는 역할을 한다.
그런데 git pull은 종류가 2가지다.
1) 기본 pull(fetch & merge)
git pull은 기본적으로 원격 저장소의 변경 사항을 가져온 후에 git merge를 사용해 로컬 브랜치와 병합한다.
원격 저장소에서 변경 사항을 git fetch 명령으로 가져온 다음, 로컬 브랜치에 git merge를 수행하여 병합하는 것과 같다.
git pull origin master
깃아, 오리진 원격 저장소에서 마스터 브랜치 내용을 pull해 줘.
2) Rebase pull
git pull --rebase origin master
git pull --rebase 옵션을 사용하면 원격 저장소의 변경 사항을 가져오고, 로컬 브랜치의 커밋을 대상 브랜치 위에 리베이스 할 수 있다.
로컬 브랜치의 커밋들을 대상 브랜치의 최신 커밋 위에 순차적으로 재배치하여 선형적인 이력을 유지할 수 있다.
총정리
둘 다 원격 저장소의 변경 사항을 가져와서 로컬 브랜치를 업데이트하는 목적은 동일하다.
그런데 가져온 변경 사항을 로컬 브랜치에 병합하는 방식에 차이가 있다.
일반 pull은 가져온 변경 사항을 현재 로컬 브랜치의 끝에 추가하여 병합한다.
그래서 커밋 이력이 기록 순서대로 보존된다.
rebase pull은 원격 저장소에서 변경 사항을 가져온 후 로컬 브랜치의 커밋을 대상 브랜치 위에 리베이스한다.
그래서 원격 저장소의 브랜치 이력이 재작성된다.