기타/기타

Git 명령어 정리

lazy man 2023. 5. 9. 00:45

1. 깃(Git)이란

버전 관리 시스템(VCS)의 한 종류로 소스 코드를 효율적으로 관리하기 위한 기술입니다. 파일의 변경 사항을 추적하고 여러 명의 개발자가 작성한 소스코드를 합치고 충돌을 해결하는데 사용됩니다. VCS에는 SVN도 많이 사용하는데 SVN 과의 차이점은 SVN은 중앙 서버에서 소스코드를 관리지만 Git은 분산형 저장소로 중앙 서버의 장애로 인해 소스코드가 사라지더라도 로컬 저장소를 통해 복원이 가능합니다.

 


 

2. 깃의 명령어

깃(Git)에서는 일반적으로 Commit, Push, Pull, Merge 을 주로 사용합니다. 이번 포스팅에서는 명령어 기반으로 깃을 사용하는 것을 포스팅하려고 합니다. 명령어 기반으로 깃을 이해한다면 소스트리 같은 Git GUI를 좀 더 효율적으로 사용할 수 있습니다.

 

2-1. git init

새로운 깃 저장소를 생성하기 위한 명령어입니다. 깃 저장소를 만들 폴더로 이동 후 명령어를 실행하면 깃을 관리하기 위한 .git 폴더가 생성됩니다.

 

2-2. git status, git add, git commit

git status 명령어를 통해 git에 의해 파일이 관리되고 있는 상태를 확인할 수 있습니다. f1.txt를 생성한 후 git status로 상태를 확인해보면 f1.txt란 파일은 아직 git에 의해 관리되는 상태가 아니라는 것을 알 수 있습니다. git에 의해 관리되기 위해선 git add 명렁어를 사용해야 합니다.

 

git add 명령어를 통해 파일을 staging area로 이동시키는 명령어입니다. staging area란 커밋을 대기하고 있는 파일이 위치하는 곳입니다. git add 명령어 이후 상태를 다시 확인해보면 파일의 변화가 git에 의해 관리되고 있는 것을 알 수 있습니다.

 

git commit 명령어는 지금까지 작업한 내용을 하나의 버전으로 만드는 명령어입니다. 하나의 버전이란 의미있는 작업의 단위를 말합니다. 예를 들어 2개의 정수를 받아 덧셈 결과값을 반환하는 메소드 역시 하나의 작업 단위가 될 수 있습니다.

 

만일 staging area에 파일이 없는 상태에서 commit 명령어를 수행하면 어떻게 될까요? 아래와 같이 커밋이 실패하면서 커밋할 것이 없다는 메세지를 확인할 수 있습니다.

 

2-3. git remote

로컬에서 작업한 내용을 commit 명령어를 통해 하나의 버전으로 만들었다면 이 버전을 원격 저장소에 저장시켜 여러 개발자들이 함께 사용할 수 있어야 합니다. 원격 저장소에 저장하기 위해서는 원격 저장소와 로컬 저장소를 연동해야 하고 이 때 remote 명령어를 사용합니다.

 

2-4. git push, git pull, git fetch

원격 저장소를 연결했다면 로컬의 작업했던 commit 내용을 push 명령어를 통해 원격 저장소에 저장할 수 있습니다.

 

commit message를 10으로 하고 push 했을 때의 원격 저장소

 

반대로 다른 개발자가 원격 저장소에 새롭게 저장한 내용을 제가 업데이트 해야할 때는 pull 또는 fetch 명령어를 사용합니다. 두 명령어는 약간의 차이가 있는데 fetch의 경우 원격 저장소에 변경 내용이 있는지 확인만 하고 실제 로컬 코드와 merge하지 않습니다. 반대로 pull 명령어는 원격 저장소에 변경 내용이 있다면 로컬 내용과 merge를 시도하게 됩니다.

 

2-5. git branch, git checkout, git merge

마스터란 하나의 브랜치로 많은 구성원들이 작업을 공유하는 것은 어려운 일입니다. 때문에 기업에서는 각각 독립적인 저장소(브랜치)를 분리하여 운영합니다. 운영중인 서비스의 저장소인 운영 브랜치, 개발 서버의 브랜치인 개발 브랜치, 신규 기능 A를 위한 위한 브랜치 등 저장소를 분리하여 작업한 후 merge 작업을 통해 코드를 합치는 작업을 하게됩니다.

 

브랜치 간에 이동하는 명령어를 check out, 브랜치 간 소스코드를 합치는 명령어를 merge라고 하며 이러한 개념으로 보았을 때  마스터 역시 하나의 branch로 볼 수 있습니다. 

 

아래의 예시는 master 브랜치에서 develp 브랜치를 생성한 후 checkout 하는 예시입니다. 우측의 브랜치의 이름이 변경되는 것을 확인할 수 있습니다.

 

만약 브랜치 간의 코드를 합치고 싶다면 merge 명령어를 사용해야 합니다. 아래의 예시는 develop 브랜치에서 작업한 내용을 master 브랜치로 합치는 작업입니다. 우선 master로 checkout 한 이후 merge를 실행해야 합니다.

 

2-6. git stash

개발자가 한창 작업을 하고 있는데 급하게 오류를 수정해야 하는 경우 어떻게 해야 할까요? 작업이 완료되지 않은 내용을 commit 하고 오류를 수정해야 할까요? 이럴 때 stash 명령어를 사용하면 문제를 해결할 수 있습니다. 

 

아래의 예제는 f1.txt 파일을 수정한 후 add하지 않은 상태입니다.

 

git stash 명령어를 사용한 후 다시 status를 확인해보면 변경된 내용이 사라진 것을 확인할 수 있습니다. 

 

사라진 작업 내용은 git stash list를 통해 확인할 수 있으며, git stash apply를 통해 다시 적용할 수 있습니다. apply 이후 f1.txt 파일은 add되지 않은 상태로 복원된 것을 볼 수 있습니다.

 

2-7. git reset

우선 git의 작업 공간은 Working Directory → Index → Repository 의 구조를 가지며 코드를 변경하는 곳이 Working Directory, git add 이후 저장되는 곳이 Index, git commit 이후 저장되는 곳이 Repository 입니다. git reset은 커밋을 취소하기 위한 명령어로 옵션별로 약간의 차이가 있습니다. 

 

아래와 같이 develop 브랜치에 3개의 커밋을 만든 후 reset 을 옵션별로 실행해보도록 하겠습니다.

 

hard 옵션

hard 옵션은 Working Directory, Index, Repository 모두 삭제하는 옵션입니다. 아래는 3번 커밋을 hard 옵션으로 삭제하는 명령어 입니다. 

$ git reset --hard db01320b45021bf85b93e9cd8ae80cf62d6da71f
HEAD is now at db01320 2

 

깃 로그를 확인해보면 3번 커밋이 사라진 것을 확인할 수 있습니다.

$ git log
commit db01320b45021bf85b93e9cd8ae80cf62d6da71f (HEAD -> develop)
Author: troh <dhxofla91@gmail.com>
Date:   Mon May 8 23:21:14 2023 +0900

    2

commit 1abbde2d1557db2f6cbc167cd76d9ff2cf8c2504
Author: troh <dhxofla91@gmail.com>
Date:   Mon May 8 23:20:59 2023 +0900

    1

 

hard 옵션의 경우 working directory 까지 삭제하기 때문에 변경 내용 자체를 확인할 수 없습니다.

$ git status
On branch develop
Your branch is ahead of 'origin/develop' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

 

mixed 옵션

mixed 옵션은 Index와 Repository는 초기화하고 Working Directory에는 작업 내용이 남아있습니다. 아래는 3번 커밋을 mixed 옵션으로 삭제하는 명령어 입니다.

$ git reset --mixed db01320b45021bf85b93e9cd8ae80cf62d6da71f
Unstaged changes after reset:
M       f1.txt

 

깃 로그를 확인해보면 3번 커밋이 사라진것을 확인할 수 있습니다.

$ git log
commit db01320b45021bf85b93e9cd8ae80cf62d6da71f (HEAD -> develop)
Author: troh <dhxofla91@gmail.com>
Date:   Mon May 8 23:21:14 2023 +0900

    2

commit 1abbde2d1557db2f6cbc167cd76d9ff2cf8c2504
Author: troh <dhxofla91@gmail.com>
Date:   Mon May 8 23:20:59 2023 +0900

    1

 

mixed 옵션의 경우 index도 삭제하기 때문에 working directory의 코드 변경이 아직 index에 적용되지 않은 것을 확인할 수 있습니다.

$ git status
On branch develop
Your branch is ahead of 'origin/develop' by 2 commits.
  (use "git push" to publish your local commits)

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   f1.txt

no changes added to commit (use "git add" and/or "git commit -a")

 

soft 옵션

soft 옵션은 Repository만 초기화하는 옵션입니다. 아래는 3번 커밋을 soft 옵션으로 삭제하는 명령어 입니다.

$ git reset --soft db01320b45021bf85b93e9cd8ae80cf62d6da71f

 

 

 

깃 로그를 확인해보면 3번이 사라진 것을 확인할 수 있습니다.

 

$ git log
commit db01320b45021bf85b93e9cd8ae80cf62d6da71f (HEAD -> develop)
Author: troh <dhxofla91@gmail.com>
Date:   Mon May 8 23:21:14 2023 +0900

    2

commit 1abbde2d1557db2f6cbc167cd76d9ff2cf8c2504
Author: troh <dhxofla91@gmail.com>
Date:   Mon May 8 23:20:59 2023 +0900

    1

 

soft 옵션의 경우 repository만 삭제하기 때문에 변경 내용이 state 상태에 있는 것을 확인할 수 있습니다.

$ git status
On branch develop
Your branch is ahead of 'origin/develop' by 2 commits.
  (use "git push" to publish your local commits)

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   f1.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        "q\357\200\233\357\200\233\357\200\272\357\200\233\357\200\233\357\200\233d"