Git
git add

git add 명령어 사용법: 취소, all, 특정 파일 폴더, -u, -i 옵션

git init 명령어에 이어, 이번 포스팅은 git add 명령어의 모든 것입니다. add부터 commit까지 이어지는 git의 동작 원리, 생산성을 높이는 옵션들, staging한 파일과 폴더 취소 방법을 다룹니다. 또한, 더 많이 알고 싶은 분들을 위해 내부 동작 원리를 마지막에 정리합니다.

1. add부터 commit까지 간단한 동작 원리

1.1 git add와 git commit 흐름 이해하기

Git의 동작 원리에 대해 알아보기 전에, 생각해볼 것이 있습니다. 만약, 새로운 문서 하나를 작성하고 저장해야 한다면 우리는 몇 개의 단계를 거칠까요?

바로 내용 작성 -> 내용 저장, 이렇게 1가지 단계만 거치면 문서가 저장됩니다. 이 방법은 간편하지만 문제가 하나 있습니다. 하나의 단계만 거치기 때문에 잘못 저장할 가능성이 큽니다.

git은 한 번 저장한 데이터를 아주 중요하게 생각합니다. 그래서 한 번 저장할 때 잘못 저장할 가능성을 최대한 줄이도록 2개의 단계를 거칩니다. 이 단계는 다음과 같습니다.

어떤 파일에 변경사항이 생기면, 이 변경사항들은 git add 명령어를 통해 staged 상태에 놓입니다. 그 다음 git commit 명령어를 실행하면, 현재 staged 상태에 있는 모든 변경사항을 하나의 커밋으로 히스토리에 등록합니다.

커밋에 등록한 파일에 새로운 변경사항이 생기면, 이 변경사항은 다시 git add 명령어의 대상이 됩니다. 이렇게 git add -> git commit -> 파일 변경 -> git add 순환을 반복하며 버전 관리가 이루어집니다.

예제를 보며 이해해보겠습니다.

1.2 git add와 git commit 직접 해보며 이해하기

먼저 2가지 마크다운 파일이 저장된 디렉토리를 준비하고 새 repo를 생성합니다. git status 명령어로 현재 상태를 살펴보면, 아직 추적하지 않은 파일 2개가 보입니다.

git add 전 untracked 상태

git add 명령어로 1.md 파일 하나를 staged 상태에 두었습니다. 연두색으로 표시된 1.md 파일 트래킹이 시작되었고, 이 파일은 커밋을 기다리고 있습니다.

git add 후 상태

git commit -m "커밋 메시지" 명령어로 커밋을 실행하면 1.md 파일의 변경사항은 새 커밋으로 등록되고 staged 상태에서 사라집니다.

git commit 이후 상태

이 때, 1.md 파일에 새로운 변경사항이 생기면, 이 파일은 다시 staged 상태에 들어옵니다.

변경사항이 있는 파일이 staged 상태에 있음

이렇게 addcommit 명령어가 반복 순환됩니다.

1.3 조금 더 자세히 살펴보기

Git 은 작업 폴더의 모든 파일 혹은 폴더를 크게 다음 2가지 상태로 관리합니다.

  • untracked: git이 파일의 변경사항을 트래킹하지 않고 있는 파일입니다.
  • tracked: git이 파일의 변경사항을 트래킹하고 있는 파일입니다. git init 명령어로 새 repo 를 생성하면 모든 파일이 untracked 상태입니다. git add 명령어는 untracked 상태의 파일을 tracked 상태로 변경하고 변경사항을 계속 지켜봅니다.

git은 tracked 상태의 파일을 다시 3가지 상태로 관리합니다.

  • staged: staged 상태는 commit이 되기 위해 준비하고 있는 상태입니다. untracked 상태의 파일이 처음 tracked 상태로 바뀌면 staged 상태가 됩니다. 또한, modified 상태의 파일도 git add 명령어를 통해 staged 상태에 놓입니다.
  • unmodified: staged 상태의 파일의 변경사항이 git commit 명령어를 통해 커밋에 등록되면 unmodified 상태가 됩니다. 이 상태는 변경사항이 발생하지 않을 때까지 지속됩니다.
  • modified: unmodified 상태의 파일에서 변경사항이 발생하면 modified 상태가 됩니다. 이 상태의 파일은 git add 명령어의 대상이 됩니다.

즉 모든 상태를 정리해서, untracked --(git add)--> tracked/staged --(git commit)--> unmodified --(변경 사항 발생)--> staged 순으로 상태가 변화한다고 이해하면 됩니다.

2. git add -A 혹은 --all 명령어로 전체 파일 및 폴더 추가하기

위 예제에서 보았듯이, 현재 작업 폴더에서 특정한 파일 혹은 폴더를 staged 상태에 놓기 위해서는 다음의 명령어를 사용합니다.

$ git add <파일 1>, <파일 2>, <폴더 1>

만약 <풀더 1>에 하위 디렉토리가 존재한다면 Git 은 알아서 모든 하위 디렉토리들을 함께 staged 상태에 추가합니다.

만약 특정 파일이나 폴더를 선택할 필요 없이, 현재 작업 폴더의 모든 파일 및 폴더를 staged 상태에 올리기 위해서는 다음의 명령어를 사용합니다. 이 때는 모든 untracked, modified 상태의 파일들을 대상으로 합니다.

$ git add -A

혹은

$ git add .

3. git add -u 명령어로 tracked 파일 및 폴더만 추가하기

현재 작업 폴더에서 Git 이 트래킹하고 있는 모든 modified 파일 및 폴더만 staged 상태에 놓기 위해서는 다음 명령어를 사용합니다. 섹션 2의 명령어와 비교해서, 이 때는 untracked 파일 및 폴더가 제외됩니다.

$ git add -u

4. git add -i 명령어로 간편하게 원하는 파일 및 폴더 추가하기

다음 명령어를 이용해서 대화형 모드를 시작하면 간단한 숫자만으로도 원하는 파일만 staged 상태에 두거나 반대로 뺄 수 있습니다.

$ git add -i

대화형 모드는 아래와 같습니다.

git add -i 결과

대화형 모드는 git status 출력과 함께 커맨드들을 출력합니다. 선택지에 따라, 4는 untracked 파일을 stage 하고, 2는 modified 파일을 stage 할 때 사용합니다. 3은 2와 4에서 staging한 파일들을 되돌릴 때 사용합니다.

5. git add 취소하기

git add 명령어를 통해 staging한 파일과 폴더는, 대화형 모드 이외에도 취소하는 명령어가 존재합니다.

작업 폴더 내의 특정 파일 및 폴더를 되돌릴 때는 다음의 명령어를,

$ git restore --staged <파일 1>, <폴더 1>

모든 파일 및 폴더를 되돌릴 때는 다음의 명령어를 사용합니다.

$ git restore --staged .

6. git add 명령어의 내부 동작

내부적으로 Git은 몇 가지 주요 데이터 구조와 개념을 사용하여 변경 사항을 관리하고 추적합니다. git add 명령어를 실행하면 내부적으로 어떤 작업이 이루어지는지 단계적으로 살펴봅니다.

  1. git add 명령어를 실행하면 Git은 지정된 파일의 콘텐츠 스냅샷을 만들고 Git의 오브젝트 데이터베이스(.git/objects에 위치)에 새 Blob 오브젝트를 만듭니다. 블롭 오브젝트는 파일 자체가 아니라 파일의 콘텐츠를 나타냅니다.
  2. 그 다음 Git은 블롭 오브젝트를 참조하여 파일의 staging 영역(다른 말로 index)에 항목을 추가합니다. 이 항목에는 파일의 경로, 모드(파일 유형 및 권한), 블롭 오브젝트의 SHA-1 해시가 포함됩니다. 여러 파일을 추가하면 Git은 각 파일에 대해 별도의 블롭 오브젝트와 인덱스 항목을 생성합니다.
  3. 이제 단계별 변경 사항을 커밋할 준비가 되었습니다. git commit 명령어를 실행하면 새 커밋의 디렉터리 구조와 파일 콘텐츠를 나타내는 새 Tree 개체가 만들어집니다. 또한 트리 개체를 가리키고, 커밋 메타데이터(예: 작성자, 날짜, 메시지)를 저장하고, 부모 커밋을 참조하는 새 Commit 개체가 만들어집니다.
  4. 마지막으로 Git은 브랜치 참조(예: 마스터 브랜치의 경우 refs/heads/master)가 새 커밋 오브젝트를 가리키도록 업데이트하여 브랜치 히스토리에서 최신 커밋이 되도록 합니다.

요약하자면,git add 명령어를 실행하면 추가된 파일에 대한 Blob 오브젝트를 만들고, 해당 파일에 대한 정보로 Staging Area를 업데이트한 후, 다음 커밋을 위해 준비한다는 점을 알고 있으면 됩니다. 커밋 자체는 git commit을 실행할 때까지 생성되지 않습니다.

7. 마치며

git add 명령어는 git 버전 관리 시스템의 중심이자 동작 원리를 잘 이해할 수 있는 많은 개념을 기반으로 이루어집니다. 이번 포스팅으로 git 버전 관리 시스템의 개념과 staging을 쉽게 완료할 수 있는 여러 옵션들을 알고 많이 활용할 수 있길 바랍니다.

copyright for git add

© 2023 All rights reserved.