처음 Git을 쓸 때 헷갈렸던 부분

2025년 10월 19일

제가 처음에 Github을 쓸때는, Git은 뭐고 Github는 뭐야? 그냥 남들이 많이 쓰니깐 써야지 라는 초보자 적인 마인드를 가지고 시작했었던 거 같습니다. 실제 제 경험을 바탕으로 체계적으로 정리해보겠습니다.

Git/GitHub의 근본적인 이해

왜 Git을 사용할까?

Git은 분산 버전 관리 시스템입니다. 코드의 변경 이력을 추적하고, 관리하는 로컬환경 기반 프로그램이죠. 인터넷 없이도 사용가능합니다. Git이 없었다면 개발자들은 파일을 final.zip, final_final.zip, real_final.zip 이렇게 관리하였을 텐데, Git은 이 모든 걸 체계적으로 관리해줍니다.

Git의 3가지 영역

Working Directory (작업 디렉토리)

↓ git add

Staging Area (준비 영역)

↓ git commit

Local Repository (로컬 저장소)

↓ git push

Remote Repository (원격 저장소 - GitHub)

이 구조를 이해하면 Git 명령어들이 훨씬 쉽게 이해됩니다.

그렇다면 Github이란?

Github이란 Git을 기반으로 한 클라우드 서비스입니다. Git으로 관리하는 프로젝트를 온라인에서 공유하고, 여러 개발자들이 협업할 수 있게 도와줍니다. 쉽게 말하면, Git으로 만든 프로젝트를 업로드하고, 다른 사람과 함께 작업할 수 있게 해주는 공간이라고 생각하시면 됩니다.

1. 기본 명령어

git add

역할: 작업 디렉토리의 변경사항을 Staging Area로 올립니다.

git add .                    // 모든 변경사항 추가
git add filename.txt         // 특정 파일만 추가
git add *.js                 // 특정 확장자만 추가
git add -p                   // 변경사항을 일부만 선택해서 추가 (대화형)

실무 팁: git add -p는 한 파일에 여러 기능을 수정했을 때, 논리적으로 커밋을 나누고 싶을 때 유용합니다.

git commit

역할: Staging Area의 변경사항을 로컬 저장소에 기록합니다.

git commit -m "메시지"              // 기본 커밋
git commit -am "메시지"             // add + commit 동시에 (추적 중인 파일만)
git commit --amend                  // 직전 커밋 수정 (메시지나 파일 추가)
git commit --amend --no-edit        // 메시지 유지하고 파일만 추가

그리고 현업에서 팀원들과 협업을 할때는 통일된 커밋메세지 규칙이 있습니다. 이걸, 컨벤션(Commit Convention)이라고 부릅니다. 일반적으로, 현업에서 사용하는 규칙에 대해서 알려드리겠습니다.

feat: 로그인 기능 추가                             // feat: 새로운 기능
fix: 회원가입 시 이메일 검증 버그 수정              // fix: 버그 수정
docs: README에 설치 방법 추가                      // docs: 문서 수정
style: 코드 포맷팅 적용                            // style: 코드 포맷팅 (동작 변경 없음)
refactor: 결제 모듈 구조 개선                      // refactor: 코드 리팩토링
test: 유저 서비스 테스트 코드 추가                  // test: 테스트 코드
chore: 패키지 업데이트                             // chore: 빌드, 설정 파일 수정

그 외 Type:

  • perf: 성능 개선

  • ci: CI/CD 관련

git commit
역할: 로컬 저장소의 커밋을 원격 저장소(GitHub 등)로 업로드합니다.

git push origin main                    // 기본 푸시
git push -u origin feature-branch       // 새 브랜치 첫 푸시 (-u로 upstream 설정)
git push --force                        // 강제 푸시 (위험! 협업 시 조심)
git push --force-with-lease             // 더 안전한 강제 푸시
git push origin --delete branch-name    // 원격 브랜치 삭제

2. 중급 명령어

git stash 💼

역할: 작업 중인 변경사항을 임시 저장소에 보관합니다. 커밋하지 않고도 작업 내용을 저장할 수 있습니다.

git stash                           // 현재 변경사항 저장
git stash save "작업 설명"           // 설명과 함께 저장
git stash list                      // 저장된 목록 보기
git stash pop                       // 가장 최근 stash 적용 후 삭제
git stash apply stash@{0}           // 특정 stash 적용 (삭제 안함)
git stash drop stash@{0}            // 특정 stash 삭제
git stash clear                     // 모든 stash 삭제

실무 상황: 급하게 다른 브랜치로 전환해야 하는데 현재 작업은 커밋하기 애매할 때

git fetch vs git pull

역할:

git fetch: 원격 저장소의 변경사항을 가져오기만 하고 현재 브랜치에는 합치지 않습니다.

git pull: 원격 저장소의 변경사항을 가져오고 자동으로 현재 브랜치에 병합합니다.

git fetch origin            // 원격 변경사항 가져오기만 (병합 안함)
git pull origin main        // fetch + merge 동시 수행
git pull --rebase           // fetch + rebase 수행 (깔끔한 히스토리)

git diff 🔍

역할: 파일의 변경사항을 비교해서 보여줍니다. 무엇이 바뀌었는지 확인할 수 있습니다.

git diff                       // Working Directory vs Staging Area
git diff --staged              // Staging Area vs 마지막 커밋
git diff HEAD                  // Working Directory vs 마지막 커밋
git diff branch1 branch2       // 브랜치 간 비교
git diff commit1 commit2       // 커밋 간 비교
git diff --name-only           // 파일 이름만 보기

git log
역할: 커밋 히스토리(기록)를 보여줍니다. 누가 언제 무엇을 변경했는지 확인할 수 있습니다.

git log                                    // 기본 로그
git log --oneline                          // 한 줄로 요약
git log --graph --all --decorate           // 그래프로 보기 (예쁨!)
git log --author="이름"                    // 특정 작성자
git log --since="2 weeks ago"              // 기간 검색
git log --grep="버그"                      // 커밋 메시지 검색
git log -p filename                        // 파일의 변경 이력
git log --follow filename                  // 파일 이름 변경도 추적

별칭 만들기:

git config --global alias.lg "log --graph --oneline --all --decorate" # 이제 git lg 로 사용 가능!

git revert

역할: 특정 커밋을 되돌리는 새로운 커밋을 생성합니다. reset과 달리 히스토리를 지우지 않아 안전합니다.

git revert abc123               // 특정 커밋 되돌리기
git revert HEAD                 // 마지막 커밋 되돌리기
git revert --no-commit HEAD~3.. // 여러 커밋 되돌리기 (한번에 커밋)

실무에서: 이미 push한 커밋은 reset보다 revert를 써야 합니다!

git blame

역할: 파일의 각 줄을 누가 언제 마지막으로 수정했는지 보여줍니다. 버그의 원인을 찾거나 담당자를 확인할 때 유용합니다.

git blame filename              // 전체 파일
git blame -L 10,20 filename     // 10~20줄만
git blame -w filename           // 공백 변경 무시

git bisect

역할: 이진 탐색으로 버그가 발생한 커밋을 찾습니다.

git bisect start
git bisect bad                  // 현재가 버그 있음
git bisect good abc123          // 이 커밋은 정상
// Git이 자동으로 중간 커밋으로 이동
// 테스트 후 good 또는 bad 입력 반복
git bisect reset                // 종료

git clean

역할: Git이 추적하지 않는 파일들(untracked files)을 삭제합니다. 작업 디렉토리를 깨끗하게 정리할 때 사용합니다.

git clean -n                    // 삭제될 파일 미리보기
git clean -f                    // 파일 삭제
git clean -fd                   // 파일 + 디렉토리 삭제
git clean -fX                   // .gitignore에 있는 파일만 삭제

3. 고급 명령어

중급 명령어부터는 혼자 개발하시는 분들이 자주 사용하지 않아서, 익숙하지 않은 분들이 계실 겁니다. 저 역시 그랬고, 인턴 근무를 하면서 협업을 하다보니 익혔었던 명령어들을 정리해 보았습니다.

git rebase

역할: 커밋 히스토리를 선형으로 정리합니다. Merge와 달리 깔끔한 히스토리를 만듭니다.

상황: main 브랜치에 새 커밋이 생겼고, 내 feature 브랜치를 최신화하고 싶을 때

// feature 브랜치에서
git rebase main

// 만약 충돌 발생 시
// 1. 충돌 파일 수정
// 2. git add .
// 3. git rebase --continue

// 취소하고 싶다면
git rebase --abort

Interactive Rebase:

git rebase -i HEAD~3    // 최근 3개 커밋 수정

// 나타나는 에디터에서:
// pick -> squash: 커밋 합치기
// pick -> reword: 커밋 메시지 수정
// pick -> edit: 커밋 수정
// pick -> drop: 커밋 삭제

실무 예시:

// 실수로 3개의 작은 커밋을 만들었을 때
git rebase -i HEAD~3
// pick를 squash로 바꿔서 하나로 합치기

git cherry-pick

역할: 다른 브랜치의 특정 커밋만 가져옵니다.

git cherry-pick <commit-hash>        // 특정 커밋 가져오기
git cherry-pick abc123 def456        // 여러 커밋 가져오기
git cherry-pick abc123..def456       // 범위로 가져오기

실무 상황: hotfix가 필요한데 다른 브랜치의 특정 수정사항만 필요할 때 잘못된 브랜치에 커밋했을 때 옮기기

git reset (주의!)

역할: 커밋을 되돌립니다. 3가지 옵션이 있습니다.


git reset --soft HEAD~1     // 커밋만 취소, 변경사항은 Staging Area에 유지
git reset --mixed HEAD~1    // 커밋 취소, 변경사항은 Working Directory에 유지 (기본)
git reset --hard HEAD~1     // 커밋 취소, 모든 변경사항 삭제 (위험!)

# 특정 커밋으로 돌아가기
git reset --hard abc123

실무 팁: --hard는 정말 위험하니 신중하게 써야 됩니다. 대신 git revert를 쓰는 게 안전할 때가 많습니다.

git reflog

역할: Git의 모든 작업 이력을 보여줍니다. reset --hard로 날린 커밋도 복구 가능!

git reflog                  // 모든 HEAD 이동 기록 확인
git reset --hard HEAD@{2}   // 2단계 전으로 복구

4. 브랜치 관리

기본 브랜치 명령어

역할: 브랜치(Branch)는 독립적인 작업 공간입니다. 기능 개발, 버그 수정 등을 분리해서 작업할 수 있게 해줍니다.

git branch                          // 로컬 브랜치 목록
git branch -r                       // 원격 브랜치 목록
git branch -a                       // 모든 브랜치 목록
git branch feature-name             // 새 브랜치 생성
git checkout -b feature-name        // 생성 + 전환
git switch -c feature-name          // 생성 + 전환 (최신 명령어)
git branch -d feature-name          // 브랜치 삭제 (병합 후)
git branch -D feature-name          // 강제 삭제
git branch -m old-name new-name     // 브랜치 이름 변경

원격 브랜치 관리

역할: 원격 저장소(GitHub)의 브랜치를 관리합니다.

git push origin :branch-name        // 원격 브랜치 삭제 (구버전)
git push origin --delete branch     // 원격 브랜치 삭제 (신버전)
git fetch --prune                   // 삭제된 원격 브랜치 정리
git remote prune origin             // 위와 동일

5. 협업 필수 명령

git merge

역할: 두 브랜치를 합칩니다. 다른 브랜치의 작업 내용을 현재 브랜치로 가져와 통합해요.

git merge feature-branch            // 현재 브랜치에 병합
git merge --no-ff feature-branch    // Fast-forward 방지 (머지 커밋 생성)
git merge --squash feature-branch   // 커밋들을 하나로 합쳐서 병합

사실 rebase를 굳이 왜 하지? 그냥 merge하면 되는 거 아닌가?라고 혼자 배우면서도 생각하였는데, 실제 협업 프로젝트를 하면 커밋의 갯수가 매우 많아지고, 그러다 보니 히스토리에 merge커밋이 많이 생기다 보면, 불필요한 커밋메시지들이 쌓여 가독성에 좋지 않아 보입니다.

Merge vs Rebase:

Merge: 히스토리 보존, 병합 커밋 생성

Rebase: 선형 히스토리, 깔끔하지만 히스토리 재작성

git remote

역할: 원격 저장소(GitHub 등)의 연결을 관리합니다. 어떤 원격 저장소와 연결되어 있는지 확인하고 설정할 수 있어요.

git remote -v                       // 원격 저장소 확인
git remote add origin <url>         // 원격 저장소 추가
git remote remove origin            // 원격 저장소 제거
git remote rename old new           // 이름 변경
git remote set-url origin <new-url> // URL 변경

git tag

역할: 특정 커밋에 버전 번호나 이름표를 붙입니다. 주로 릴리즈 버전(v1.0, v2.0 등)을 표시할 때 사용해요.

git tag v1.0.0                      // 태그 생성
git tag -a v1.0.0 -m "버전 1.0"     // 주석 달린 태그
git push origin v1.0.0              // 태그 푸시
git push origin --tags              // 모든 태그 푸시
git tag -d v1.0.0                   // 로컬 태그 삭제
git push origin :refs/tags/v1.0.0   // 원격 태그 삭제

6. 설정 및 최적화

Git 설정

역할: Git의 기본 동작 방식이나 사용자 정보를 설정합니다. 최초 1회 설정하면 계속 유지돼요.


git config --global user.name "이름"
git config --global user.email "email@example.com"
git config --global core.editor "code --wait"  // VSCode를 기본 에디터로
git config --global init.defaultBranch main    // 기본 브랜치명 main으로
git config --list                              // 모든 설정 보기

유용한 별칭 (Alias)

역할: 자주 쓰는 긴 명령어를 짧은 단축키로 만듭니다. 예를 들어 git checkout을 git co로 줄일 수 있어요.


git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.lg 'log --graph --oneline --all --decorate'

.gitignore

역할: Git이 추적하지 않을 파일이나 폴더를 지정합니다. 비밀번호, 로그 파일, 빌드 결과물 등을 Git에서 제외할 때 사용해요.

// 예시
node_modules/
.env
*.log
.DS_Store
dist/
build/

전역 gitignore: git config --global core.excludesfile ~/.gitignore_global

8. 고급 기능

Submodule

역할: 다른 Git 저장소를 현재 프로젝트 안에 포함시킵니다. 외부 라이브러리나 공통 모듈을 관리할 때 유용해요.

git submodule add <repo-url> path/to/submodule
git submodule update --init --recursive

Worktree

역할: 하나의 저장소에서 여러 브랜치를 동시에 작업할 수 있게 해줍니다. 브랜치마다 별도의 작업 폴더를 만들어줘요.

git worktree add ../project-feature2 feature2

git worktree list

git worktree remove ../project-feature2

Hooks

역할: Git 명령어 실행 시 자동으로 특정 스크립트를 실행합니다. 커밋 전 자동 테스트나 코드 검사 등을 수행할 수 있습니다.

.git/hooks/ 디렉토리에서 스크립트 실행:

pre-commit: 커밋 전 실행 (린트, 테스트)
pre-push: 푸시 전 실행
commit-msg: 커밋 메시지 검증

회고

이 정도 내용을 알게 된다면, 현업이나, 지금 git을 사용해 작업을 하는데 아무런 지장이 없다라고 생각합니다. 하지만, 단순히 글로만 보게 되면, 헷갈릴 수 있으니, 꼭 로컬에서 작업을 해보면서 테스트를 해보면 좋은 연습이 될 것입니다.