> ## Documentation Index
> Fetch the complete documentation index at: https://blog.nvim.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Git 설치부터 첫 커밋까지

> index.js와 README.md로 저장소를 만들고, 작성자 설정부터 status·add·commit·log까지 직접 실행하며 첫 로컬 기록을 남겨봐요.

`index.js`에 `console.log("hello");`를 적고 저장했어요. 이 코드를 첫 커밋으로 남기려면 어디부터 시작해야 할까요? GitHub 계정부터 만들어야 할까요? 이름과 이메일을 입력하면 로그인한 걸까요?

[앞 글](https://blog.nvim.me/git/learn/why-git-and-version-control.md)에서는 작업 파일, 인덱스, 커밋을 구분했어요. 이번에는 `index.js`와 `README.md`를 만들고 **내 컴퓨터에 첫 커밋 하나를 남겨볼 거예요.**

코드 실행은 필요하지 않으므로 Node.js나 패키지를 설치하지 않아요. Git 설치가 끝나면 GitHub 계정이나 원격 저장소 없이 진행할 수 있어요. 마지막에 `git log`에서 기록을 찾고, `git status`로 남은 변경이 없는지 확인하면 돼요.

## 시작하기 전에

이 글의 명령은 **Bash** 기준이에요. 운영체제에 맞는 설치 안내를 따라 준비해요.

| 준비할 것 | 이번 실습의 조건 |
| - | - |
| Git | `git init -b main`을 사용할 수 있는 Git 2.28 이상 |
| 터미널 | Bash 셸. Windows에서는 Git Bash를 사용할 수 있어요 |
| 작업 위치 | 기존 프로젝트나 Git 저장소 밖의 폴더 |
| 시작 상태 | 새 `git-practice` 폴더. 기존 파일이나 커밋은 필요 없어요 |
| 종료 상태 | `main` 브랜치에 파일 두 개를 담은 커밋 하나. 원격 저장소는 없어요 |

### Git이 설치되어 있는지 확인해요

터미널에서 실행해보세요.

```bash theme={null}
git --version
```

`git version` 뒤에 버전 번호가 나오면 설치된 Git을 실행할 수 있어요.

명령을 찾을 수 없다면 운영체제에 맞는 공식 안내를 따라 설치한 뒤 터미널을 새로 열어 확인해요.

* **Windows:** [Git 설치 안내](https://git-scm.com/install/windows)를 따라 설치하고 **Git Bash**를 열어요.
* **macOS:** [Git 설치 안내](https://git-scm.com/install/mac)에서 Homebrew나 Xcode Command Line Tools 등 환경에 맞는 방법을 골라요. 실습은 Bash에서 진행해요.
* **Linux:** [Git 설치 안내](https://git-scm.com/install/linux.html)에서 배포판에 맞는 패키지 관리자 명령을 확인해요.

`-b` 옵션은 [Git 2.28의 init 문서](https://git-scm.com/docs/git-init/2.28.0)에 포함되어 있어요. 더 오래된 Git이라면 먼저 업데이트해요.

## 명령을 실행하면 무엇이 바뀔까요?

이번 명령이 파일, 설정, 이력 중 무엇을 바꾸는지 먼저 구분해봐요.

| 명령 | 바뀌는 대상 | 아직 일어나지 않는 일 |
| - | - | - |
| `git init -b main` | 현재 폴더에 Git 저장소를 만들고 첫 브랜치 이름을 정해요 | 파일을 커밋하지는 않아요 |
| `git config --local` | 이 저장소의 설정을 기록해요 | GitHub에 로그인하지는 않아요 |
| `git add` | 지정한 파일의 현재 내용을 다음 커밋에 준비해요 | 새 커밋은 아직 없어요 |
| `git commit` | 준비한 상태를 로컬 이력에 기록해요 | 원격 저장소에 보내지는 않아요 |

일반적인 저장소에서 `git init`은 현재 폴더 안에 숨김 디렉터리 `.git`을 만들어요. Git은 이곳에서 이력과 설정을 관리해요. 직접 편집하는 `index.js`와 `README.md`는 `.git` 밖의 작업 트리에 있어요. [git init 문서](https://git-scm.com/docs/git-init)에서 초기화 동작을 확인할 수 있어요.

## 첫 기록을 남겨봐요

아래 단계는 같은 터미널에서 순서대로 진행해요. 명령이 실패하면 다음 단계로 넘어가기 전에 아래 문제 해결 표에서 원인을 확인해요.

**1. 빈 실습 폴더에 저장소 만들기**

기존 프로젝트 밖의 작업 위치로 이동한 뒤 실행해요. `pwd`는 현재 위치를 보여줘요.

```bash theme={null}
pwd
mkdir git-practice && cd git-practice && git init -b main
```

`mkdir`와 `cd`가 모두 성공했을 때만 저장소를 초기화해요. 이미 같은 이름의 폴더가 있다면 여기서 멈추고 새 실습 폴더 이름을 골라요. 기존 폴더에 이어서 초기화하지 않아요.

이제 첫 브랜치 이름은 `main`으로 정해졌지만, 커밋은 아직 없어요. `.git` 내부 파일은 직접 편집하지 않아요.

**2. 이 저장소에서 사용할 작성자 정하기**

커밋에는 누가 기록했는지도 들어가요. 연습용 이름과 이메일을 이 저장소에만 설정해요.

```bash theme={null}
git config --local user.name "Git Learner"
git config --local user.email "learner@example.com"
git config --local --get user.name
git config --local --get user.email
```

확인 명령 두 개의 출력이에요.

```text theme={null}
Git Learner
learner@example.com
```

`--local`은 현재 저장소의 `.git/config`에 설정해요. 다른 저장소에 적용할 전역 설정을 바꾸지 않아요. 위 값은 연습용이며, 실제 작업에서는 기록에 남길 이름과 이메일을 사용해요.

**이 설정은 로그인이 아니에요.** `user.name`은 GitHub 사용자 이름을 인증하는 항목이 아니고, 이메일에 비밀번호나 토큰을 넣는 것도 아니에요. [git config 문서](https://git-scm.com/docs/git-config)와 [Git FAQ](https://git-scm.com/docs/gitfaq#_configuration)는 작성 정보와 원격 인증을 구분해요.

**3. 파일을 저장하고 현재 상태 보기**

빈 실습 폴더에 코드 한 줄과 프로젝트 설명 파일을 만들어요. 아래 `>`는 같은 이름의 파일이 있으면 내용을 덮어써요. 앞에서 만든 새 `git-practice` 폴더 안에서만 실행해요.

```bash theme={null}
printf 'console.log("hello");\n' > index.js
printf '# Git practice\n' > README.md
git status --short
```

파일 저장 직후에는 이렇게 보여요.

```text theme={null}
?? README.md
?? index.js
```

`??`는 Git이 아직 추적하지 않는 파일이라는 뜻이에요. 파일은 작업 트리에 있지만, 다음 커밋에 넣을 내용으로 고르지는 않았어요.

**4. 이번 기록에 담을 내용을 고르기**

두 파일을 지정해서 스테이징해요. 이 명령은 파일을 다른 폴더로 옮기지 않아요.

```bash theme={null}
git add index.js README.md
git status --short
```

이제 상태가 바뀌어요.

```text theme={null}
A  README.md
A  index.js
```

왼쪽 열의 `A`는 새 파일이 인덱스에 추가됐다는 뜻이에요. 짧은 상태 표시에서는 첫 번째 열이 인덱스, 두 번째 열이 작업 트리의 상태를 나타내요. [git status 문서](https://git-scm.com/docs/git-status#_short_format)에 각 표시가 정리되어 있어요.

커밋하기 전에 준비한 내용도 확인해요.

```bash theme={null}
git diff --cached
```

첫 커밋 전이므로 스테이징한 파일 전체가 추가된 내용으로 나와요. `index.js`에 `+console.log("hello");`, `README.md`에 `+# Git practice`이 있는지 확인해요. 앞의 `+`는 파일에 저장된 문자가 아니라 추가된 줄 표시예요.

출력이 길어 별도 보기 화면이 열렸다면 `q`로 나올 수 있어요.

여기서 파일을 다시 고쳤다면 `git add`도 다시 해야 새 내용이 준비돼요. `add`가 담는 것은 **실행한 시점의 내용**이에요. [git add 문서](https://git-scm.com/docs/git-add)도 이 차이를 설명해요.

**5. 커밋을 만들고 이력 확인하기**

준비한 두 파일을 하나의 기록으로 남겨요.

```bash theme={null}
git commit -m "Add initial script and README"
git log --oneline
```

`-m` 뒤에는 커밋 메시지를 적어요. 이번에는 처음 만든 코드와 README를 기록했다는 뜻이에요. 메시지를 명령에 넣었으므로 메시지 편집기를 따로 열지 않아요.

`git log --oneline`에는 `Add initial script and README`라는 메시지를 가진 기록 한 줄이 나와요. 맨 앞에는 축약된 커밋 ID가 붙어요. 작성 정보와 기록 시점 등에 따라 값이 달라지므로 같은 ID가 나올 필요는 없어요. 길이도 항상 같지는 않아요. **메시지가 있는 기록 한 줄**을 찾으면 돼요.

작성자와 현재 작업 상태도 확인해요.

```bash theme={null}
git log -1 --format='%an <%ae>'
git status
```

검증 환경의 출력이에요.

```text theme={null}
Git Learner <learner@example.com>
On branch main
nothing to commit, working tree clean
```

`git log`는 남긴 이력을 보여주고, `git status`는 지금 남아 있는 변경을 보여줘요. `working tree clean`은 현재 Git이 보고하는 미커밋 변경이 없다는 뜻이에요. 파일이 지워졌거나 원격에 업로드됐다는 뜻은 아니에요.

메시지 옵션은 [git commit 문서](https://git-scm.com/docs/git-commit), 한 줄 출력과 형식 옵션은 [git log 문서](https://git-scm.com/docs/git-log)에서 확인할 수 있어요.

## GitHub에는 왜 아무것도 없을까요?

이번에는 원격 저장소를 연결하지 않았어요. 아래 명령으로 확인할 수 있어요.

```bash theme={null}
git remote -v
```

새 실습 저장소에서는 출력이 없어요. 연결한 원격이 없기 때문이에요. **로컬 커밋이 없는 것과는 달라요.** 앞에서 `git log`로 기록을 확인했죠.

작성자 이름과 이메일을 입력해도 원격이 생기지 않아요. 커밋을 만들어도 자동으로 전송되지 않고요. [Pro Git](https://git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F)에서 설명하듯, 이력 기록과 조회 같은 기본 작업은 로컬에서 할 수 있어요.

## 중간에 막혔다면

아래는 오류 상황별 확인 순서예요. 실제 문구는 Git 버전과 언어 설정에 따라 달라질 수 있어요.

| 상황 | 먼저 확인할 것 | 이어서 할 일 |
| - | - | - |
| `git` 명령을 찾지 못해요 | Git 설치 여부와 터미널 환경 | 공식 설치 안내를 확인하고 새 터미널에서 `git --version`을 실행해요 |
| `init`의 `-b` 옵션을 인식하지 못해요 | `git --version` | Git 2.28 이상으로 업데이트해요 |
| `git-practice` 폴더가 이미 있어요 | 기존 실습이나 다른 작업이 들어 있는지 | 기존 폴더를 덮어쓰지 말고 새 이름의 폴더로 시작해요 |
| Git 저장소가 아니라는 오류가 나요 | `pwd`로 현재 위치 | 초기화한 `git-practice` 폴더로 이동해요. 아무 폴더에서나 `git init`을 반복하지 않아요 |
| `add`할 파일을 찾지 못해요 | 현재 폴더, 파일 이름과 저장 여부 | 두 파일이 실습 폴더에 있는지 확인한 뒤 이름을 맞춰 다시 추가해요 |
| 작성자 정보를 요구해요 | 저장소 안에서 `git config --local --get user.name`과 `user.email` 조회 | 두 값을 설정하고 커밋을 다시 실행해요 |
| 커밋할 변경이 없다고 해요 | `git status`와 `git log --oneline` | `??` 파일이면 먼저 추가해요. 이미 커밋했고 작업 트리도 깨끗하다면 더 만들 필요 없어요 |

> [!NOTE]
>
> 기존 전역 설정에서 커밋 서명을 켰거나 별도 Git hook을 사용한다면 추가 조건 때문에 커밋이 실패할 수 있어요. 이 글의 출력은 그런 추가 설정이 없는 환경을 기준으로 해요. 해당 오류가 나오면 서명 키나 hook의 안내를 확인해요. 다른 프로젝트까지 영향을 주는 전역 설정을 무작정 바꾸지는 않아요.

## 첫 기록을 남겼는지 스스로 확인해봐요

* `git log --oneline`에 첫 커밋이 한 줄 보여요.

* 작성자가 이 저장소에 설정한 이름과 이메일로 나와요.

* `git status`에 현재 브랜치가 `main`이고 작업 트리가 깨끗하다고 나와요.

* `git remote -v`에는 출력이 없어요. 기록은 내 컴퓨터에 있어요.

두 파일은 그대로 두면 돼요. 실습을 마치고 폴더 밖으로 나가려면 `cd ..`를 실행해요. 다시 `git-practice`으로 들어오면 남긴 기록을 읽을 수 있어요.

이제 `console.log("hello git");`로 코드를 바꾼다면 무엇부터 달라질까요? 파일을 저장하는 순간 바뀌는 것은 작업 트리예요. `add`로 고르고 `commit`으로 기록하는 과정은 다시 필요해요. 이번에 직접 본 상태 변화를 떠올리며 구분해보세요.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.