push 하기 전 원격저장소와 연결되어 있는지 확인
$ git remote -v
$ git add . // Staging Area 추가
$ git commit -m "#{코멘트}" // 커밋(코멘트 작성 포함)
$ $ git push #{원격저장소} #{branch이름}
Git은 파일을 Committed, Modified, Staged 이렇게 세 가지 상태로 관리한다.
이 세 가지 상태는 Git 프로젝트의 세 가지 단계 와 연결되어 있다.
<Git 디렉토리>
Git이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말하며, Git의 핵심이다.
다른 컴퓨터에 있는 저장소를 Clone 할 때 Git 디렉토리가 만들어진다.
<워킹 트리>
프로젝트의 특정 버전을 Checkout 한 것이다.
Git 디렉토리는 지금 작업하는 디스크에 있고 그 디렉토리 안에 압축된 데이터베이스에서 파일을 가져와서 워킹 트리를 만든다.
< Staging Area>
Git 디렉토리에 있다.
단순한 파일이고 곧 커밋할 파일에 대한 정보를 저장한다.(임시 저장소)
Git에서는 기술용어로는 “Index” 라고 한다.
- 작업하는 프로젝트를 수정한다 => Modified 상태, 워킹 트리 단계
- 커밋할 파일들을 Staging Area에 추가한다 => Staged 상태, Staging Area 단계
- 커밋한다 => Committed 상태, Git 디렉토리 단계
로컬 branch 정보를 확인했을 때, 현재 설정된 branch(*)가 HEAD로터 분리되어 있는 경우가 있다.
$ git branch
git은 HEAD라는 포인터를 하나 가지는데 이 포인터는 지금 작업하는 로컬 branch를 가르킨다.
즉, HEAD는 현재 작업하는 branch의 마지막 커밋이다.
HEAD -> branch -> 커밋 순서로 가르키는 것이고 HEAD는 커밋을 간접적으로 가르킨다.
Detached HEAD
branch를 통해서가 아니라 직접 다이렉트로 커밋을 참조하고 있는 상태를 뜻한다.
처음 프로젝트를 clone할 때 서브모듈이 포함된 프로젝트를 clone했다.
그 과정에서 $ git submodule update 명령어를 실행했는데, 이 때 HEAD가 커밋을 바로 가르키게 되면서 detached HEAD가 된 것이다.
강제로 push를 실행해보니 위와 같은 힌트를 알려줬다.
$ git push origin HEAD:main
이 명령어를 실행하니 push를 성공했다.
detached HEAD 상태에서 커밋은 성공했고, push는 실패했다.
그 말은 detached HEAD에서 커밋이 가능하며 branch없는 커밋이 만들어질 가능성이 있다는 것이다.
따라서 내가 실행한 커밋은 branch가 없어 push가 되지 않았던 것이다❗️(버전관리 불가)
코드를 작성하기 전에 내가 어느 branch에서 작업하는지 확인하는 것이 필요하고,
만약 detached HEAD이면 branch를 가르키도록 설정한 뒤 작업하는 것이 중요함
$ git submodule update --remote --merge
$ git checkout -b #{임시브랜치} // (새로운)임시 브랜치 만들어 체크아웃
$ git checkout #{정착할 브랜치} // 정착할 브랜치(보통 master)로 이동
$ git merge #{임시브랜치} // 정착할 브랜치에 임시브랜치 머지
$ git branch -d #{임시브랜치} // 필요없다면 임시브랜치 삭제
$ git reflog // branch가 없는 커밋의 id를 확인
$ git checkout #[기존브랜치} // 기존 브랜치로 이동
$ git cherry-pick #{커밋id} // branch없는 커밋 기존브랜치에 붙이기
[참고]
1.https://git-scm.com/book/ko/v2/%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-Git-%EA%B8%B0%EC%B4%88
2.https://www.devhak.com/blog/git-detached-head