HyunJun 기술 블로그

Git Workflow 본문

Git

Git Workflow

공부 좋아 2023. 8. 16. 08:29
728x90

Git Workflow

이 글에서는 일단 Git의 간단한 원리를 이론을 통해 배우고, Git이 돌아가는 과정과, 왜 Git을 배우고 사용해야 하는지에 대해서 간단한 실습을 통해 알아보려고 한다.

 

이론

Git의 논리적인 3가지 영역

Git의 저장 공간은 논리적으로 3단계로 나누어져 있다.

  • Working Directory: 작업 중인 디렉터리.
  • Staging area: commit을 하기 전, commit을 할 파일들을 모아놓는 장소
  • Repository: commit 기록들이 모여있는 장소.

 

File Status LifeCycle

  1. Untracked: Working Directory에 있는 파일이지만, Git에 의해 추적되고 있지 않은 상태 즉, 아직 Git으로 버전 관리를 하지 않는 상태를 의미한다.
  2. Tracked: Git이 해당 파일의 변경사항을 추적하고 있는 상태를 의미한다.
    1. Staged: 파일이 변경되었고, 변경 사항이 Staging Area에 추가(반영) 된 상태이다. 다음 Commit에 포함될 준비가 된 상태이다.
    2. Unmodified: 파일이 마지막으로 Commit된 이후로 변경되지 않은 상태이다. 즉, 작업 디렉터리의 해당 파일은 최근 Commit된 버전과 동일하다.
    3. Modified: 파일이 마지막으로 Commit된 이후로 변경된 상태이다. 하지만 아직 Staging Area에 추가되지는 않았다. 파일이 추가된 이후 해당 파일이 수정되었을 때의 상태이다.
    4. Deleted: 파일이 작업 디렉터리에서 삭제되었으나 아직 Staging Area에는 삭제 사항이 추가되지 않은 상태이다.

 

즉, Git은 아래와 같은 형태의 프로세스로 동작한다.

flowchart LR
        subgraph WorkingDirectory
        direction LR
            UntrackedFile --> add
        end
        add --> TrackedFile
    subgraph StagingArea
        direction LR
        TrackedFile --> commit
    end
        commit --> commited
    subgraph LocalRepo
        direction LR
        commited --> push
                pull
                fetch
    end
        push

subgraph RemoteRepository
direction LR
    OriginFile
end

push --> OriginFile
OriginFile --> |pull| WorkingDirectory
RemoteRepository --> fetch

 

실습

실습 환경은 EC2에 설치된 Ubuntu Linux에서 진행된다. 기본적인 git init 방법은 이전 글을 참고하자.

 

기본적인 실습은 이전 글에서 생성했던 /home/ubuntu/myProject 디렉터리에서 진행한다. Git의 구조만 알아보기 위해 파일의 제목이나 내용은 최대한 간단하게 작성했다.

 

a라는 파일을 만들고, a라는 텍스트를 저장했다.

vi a

## vi
a
##

 

저장하는 순간, main 브랜치의 색상이 초록색에서 노란색으로 변경되었다. 초록색은 현재 체크아웃된 브랜치에 변경 사항이 없고, 작업 디렉터리가 깨끗한 상태를 나타낸다. 노란색은 작업 디렉터리에 변경 사항이 있음을 나타낸다. 예를 들어, 새로운 파일이 추가되거나 기존 파일이 수정되었을 때 이런 색상으로 변경될 수 있다. 다만 이는 셸 환경이나, 터미널 설정에 따라 다를 수 있다.

 

git status

$ git status

 

git status를 사용하면 아래와 같이 a 파일이 Untracked File이라고 나온다. 우린 이미 서론의 이론에서 Untracked File은 Git에 의해 추적되지 않는 파일이라고 배웠다.

 

 

파일 a를 만들었던 것과 같이 같은 방식으로 b, c를 만들어보자.

$ git status

 

 

서론에 언급했던 것처럼, Git에 의해 관리되는 디렉터리는 아래와 같은 논리적인 구조 및 과정을 거친다.

  1. working directory
  2. staging area
  3. repository

 

 

git add

현재의 a, b, c 파일은 Untracked 상태이고, Working Directory에 있는 파일이지만, 아직 Git으로 버전 관리를 하지 않는 상태를 의미한다. 이때 git add를 사용해서 Tracked 상태로 변경하면서 staging area로 이동할 수 있다.

git add b
git status

 

 

 

 

git rm

또한 친절하게 git에서 알려주는 것처럼, git rm --cached [파일명]을 사용해 해당 내용을 지워 다시 Untracked 상태로 만들고 working direcotry로 보낼 수 있다.

실습을 위해 git add b를 다시 적용했다.

 

 

git commit

  • staging area 영역에 존재하는 모든 파일들을 repository로 저장한다.
  • 쉽게 말하면 저장소(repository)에 관리하는 파일을 저장(commit)하는 것이다.
  • commit 시, commit할 파일들을 일일이 지정하지 않는다.
  • commit 메시지만 기입해 주면 된다.

 

commit history

repository로 commit을 하게 되면, commit history에는 commit 기록들이 저장되고 아래와 같은 특징을 갖는다.

  • commit을 한 기록들이 시간 순서대로 남게 된다.
  • 각각의 commit은 중복되지 않는 고유한 키값(해시값)을 가진다.
  • 각각의 commit들은 해시값을 기반으로 시간순으로 연결되어 링크드 리스트와 유사한 구조를 가진다. (실제로는 DAG(Directed Acyclic Graph) 구조라고 한다.)

 

git log

commit history는 아래의 명령어로 확인할 수 있다.

$ git log

현재 "b" 파일은 add로 staging area에만 올렸을 뿐 commit을 하지 않아 repository로 저장되지 않았고 commit history(log)에 뜨지 않는다.

 

commit을 하게되면 staging area에 있는 모든 내역들을 repository에 저장하게 된다.

$ git commit -m "feat: add file b"

 

그러면 이제 b 파일은 git status에서 보이지 않는다.

 

 

 

git log를 하면 비로소 commit history를 확인할 수 있다.

$ git log

그러면 파일 a와, c를 각각 add 한후 commit 해보자.

 

HEAD

HEAD는 현재 바라보고 있는 commit을 의미한다. 파일 a와 c를 각각 add 및 commit 했다면 이제 보이는 내용과 repository의 내용(Commit History)이 같게 되었다.

 

 

git checkout

file b의 commit 내역으로 HEAD를 돌려보자 checkout 명령어로 변경할 수 있다.

$ git checkout 4a7c83

 

그러면이제 git log 시 file b의 커밋 내역만 나오며, 실제로 파일도 b만 보이게 된다.

 

원래의 HEAD가 바라보는 곳으로 돌아가려면 main으로 다시 checkout하면 된다.

$ git checkout main

 

또한 아래처럼 사용할 수도 있다.

# 현재 HEAD 위치를 기준으로 바로 전 단계의 commit으로 HEAD를 돌린다.
git checkout HEAD^

# 현재 HEAD 위치를 기준으로 3단계전의 commit으로 HEAD를 돌린다.
git checkout HEAD~3

참고로 HEAD를 변경한다는 것은 바라보는 곳을 변경한다는 것이지 삭제한다거나 하는 개념은아니다.

 

git switch

checkout이 하는 역할이 많아지고 복잡해지면서 switch라는 명령어가 나왔다. 이것 또한 git checkout main과 동일하게 동작한다.

$ git switch main

 

modefied

최신의 커밋으로 다시 HEAD를 돌린 후에, b 파일의 내용을 1234로 수정해보자.

vi b

# vi
1234
#

 

  • git status로 확인해 보면 b 파일은 modified 상태가 되었다. 그렇다면 수정된 b 파일과 Repository에 저장된 b 파일은 어떤 차이가 있을까?
    • Repository에 b의 내용에는 파일 b와 내용 b만 저장되어 있다.
    • Modified 상태인 b 파일에는 b라는 문서의 수정된 내용 1234만 저장되어 있다.

즉 git은 생성 및 수정이 됐다면 해당 파일의 생성, 수정 내역 전부를 저장하며 단순 수정만 됐다면 수정 그 자체만을 저장한다. (수정만 한 경우 생성 내역은 저장하지 않음.)

 

해당 수정 사항을 적용하기 위해서는 똑같이 add, commit를 적용해주면 된다.

 

gitignore

git을 사용하다 보면 git에서 전혀 추적하고 싶지 않게 하고 싶을 때가 있다. 예를 들면 아래와 같은 경우이다.

  • .pem key 등 key file을 포함하고 있는 경우
  • DB 설정 파일(연결 정보, 비밀번호), JWT SECERET Key 등 중요 정보를 포함하고 있는 파일의 경우

이러한 파일들의 경우 .gitignore 파일을 직접 생성해 내용을 추가해 주면 된다.

# 새로운 파일 d 생성
vi d

 

.gitignore 파일을 만들고, 제외하고자 하는 파일 명을 저장하면 된다.

$ vi .gitignore

파일 명을 저장 후 종료.

 

그럼 이제, d 파일은 관리 대상에서 제외되고 Untracked File 조차도 보이지 않는다.

728x90
Comments