Git이란 무엇인가?
Source: Dev.to
Git이 필요한 이유
많은 개발자에게, 펜드라이브는 오래된 프로젝트나 파일을 저장하고 꺼내는 장소에 불과합니다.
하지만 too many folders, redundant files, 그리고 nearly‑full pendrive가 생기면 가장 오래된 폴더를 삭제하고 프로젝트의 마지막 1‑2 버전만 남기게 됩니다.
그 후, 새로운 기능을 추가하고 오래된 기능을 제거한 뒤에, 필요한 기본 기능 중 하나가 누락되었으며 이전 버전에 대한 기록이 없다는 것을 깨달을 수 있습니다.
바로 그때 Git이 구세주처럼 등장합니다.
Git이 제공하는 것
- 테스트된 변경을 stage하거나 나중에 push할 때마다 Git은 숨겨진
.git디렉터리 안에 스냅샷을 저장합니다. - 실수를 하면 이전 버전으로 backtrack하여 앱을 계속 실행할 수 있습니다.
- Git은 매번 전체 코드를 저장하는 대신 변경 사항(델타)만 compress하므로, 전체 폴더를 USB에 복사하는 것에 비해 저장소가 작게 유지됩니다.
- 스냅샷은 compressed format으로 저장되며 프로젝트 파일 구조의 전체 히스토리를 포함합니다.
Git 커밋 내부
커밋을 할 때 Git은 .git/objects/ 안에 객체들을 생성합니다:
| 폴더 | 내용 |
|---|---|
blob | 실제 파일 내용(변경 사항) |
tree | 해당 커밋의 디렉터리 구조 |
commit | 메타데이터(작성자, 날짜, 메시지)와 커밋을 식별하는 SHA‑1 해시 |
각 커밋은 고유한 SHA‑1 해시를 가집니다.
이전 버전을 요청하면 Git은 다음과 같이 동작합니다:
- 커밋 객체(메타데이터)를 찾아봅니다.
- 연결된 트리를 읽어 디렉터리 레이아웃을 재구성합니다.
- 필요한 블롭(파일 내용)을 가져옵니다.
- 재구성된 파일들을 작업 디렉터리에 씁니다.
Simple Developer Workflow
1. Initialise a Repository
git init
.git 폴더를 생성하고 Git에게 프로젝트 추적을 시작하도록 알립니다.
2. Stage Files
git add # add specific files
# or
git add .
파일들을 커밋 준비가 된 상태로 표시합니다.
3. Commit
git commit -m "Your commit message here"
고유 해시와 함께 스냅샷을 생성합니다. 이는 나중에 특정 기능이나 버그 수정을 찾아내는 데 필수적입니다.
4. Push (optional)
git push origin <branch-name>
커밋을 원격 저장소(예: GitHub, GitLab)에 업로드하여 프로젝트가 외부에서 추적되도록 합니다.
브랜치 – 여러 개발 라인에서 작업하기
branch는 단순히 커밋을 가리키는 포인터입니다.
Git은 기본 master(또는 main) 브랜치를 생성하지만, 다음과 같은 경우에 추가 브랜치를 만들어야 합니다:
- 기능 개발 – 안정된 코드를 방해하지 않고 새로운 기능을 작업합니다.
- 테스트 – 변경 사항을 메인 라인에 병합하기 전에 검증합니다.
- 협업 – 각 개발자가 자신의 브랜치를 가짐으로써 충돌 가능성을 줄입니다.
예시:
당신과 친구가 Todo 앱을 만든다면, 세 개의 브랜치를 가질 수 있습니다:
dev‑alice– 당신의 작업dev‑bob– 친구의 작업test–main에 병합하기 전 통합 테스트
자세한 내용은 공식 문서를 참고하세요.
보기 기록
-
전체 로그 – 모든 메타데이터와 해시를 표시합니다
git log -
한 줄 요약 – 짧은 해시와 커밋 메시지만 표시합니다
git log --oneline
재방문하려는 커밋의 해시를 복사하세요 (예: 01xyz2).
오래된 버전 체크아웃
Detached HEAD (임시 보기)
git checkout 01xyz2
해당 커밋 시점의 프로젝트 상태를 보여주지만, detached HEAD 상태(어떤 브랜치에도 있지 않음)입니다.
해당 커밋으로부터 새 브랜치 만들기
git checkout -b 01xyz2
- 오래된 버전을 체크아웃하고 그에 새 브랜치를 생성하여, detached HEAD 대신 정상적인 브랜치에 머물게 합니다.
영구적으로 되돌리기
오래된 코드를 검토한 결과 두 가지 옵션이 있습니다:
-
레포지토리를 그대로 두기 – 오래된 코드를 참고용으로만 사용합니다.
-
현재 브랜치를 해당 커밋으로 리셋하기 (위험함 – 히스토리를 재작성합니다).
# Move the current branch pointer to the old commit git reset --hard 01xyz2--hard옵션은 최신 커밋을 모두 버려도 괜찮다고 확신할 때만 사용하세요.
TL;DR
- Git은 오직 변경 사항만 압축된 형식으로 저장하여 히스토리를 가볍게 유지합니다.
- 모든 커밋은 SHA‑1 해시로 식별되는 스냅샷입니다.
- 추적을 시작하려면
git init,git add,git commit,git push를 사용하세요. - 브랜치는 여러 개발자가 서로 충돌하지 않게 병렬로 작업할 수 있게 해줍니다.
git log와git checkout을 사용하면 이전 버전을 탐색하고 되돌릴 수 있습니다.
즐거운 코딩 되세요! 🚀
Git reset 옵션 – 간단 개요
| Command | What it does | Effect on your work‑tree & index |
|---|---|---|
git reset --soft <commit> | 지정한 커밋으로 HEAD를 이동하지만, 해당 커밋 이후에 만든 모든 변경 사항을 스테이징된 상태(인덱스에) 그대로 둡니다. | 지금 커밋하면, 새로운 커밋은 최신 커밋에 있던 모든 변경 사항과 스테이징한 변경 사항을 모두 포함합니다. |
git reset --mixed <commit> (or simply git reset <commit>) | 지정한 커밋으로 HEAD를 이동하고, 그 시점 이후에 스테이징된 모든 변경 사항을 스테이징 해제합니다. | 작업 디렉터리는 그대로 유지되지만, 변경 사항은 더 이상 스테이징되지 않습니다. 원하는 대로 수정하고, 다시 스테이징하고, 커밋할 수 있습니다. |
git reset --hard <commit> | 지정한 커밋으로 HEAD를 이동하고 그 이후의 모든 변경 사항(스테이징된 것과 스테이징되지 않은 것 모두)을 버립니다. | 커밋에 포함되지 않은 모든 수정 사항이 작업 트리에서 영구적으로 삭제됩니다. 주의해서 사용하세요! |
안전하게 되돌리는 방법
- 돌아가고 싶은 커밋을 식별합니다 (예:
git log또는 시각 도구 사용). - 적절한 reset 모드를 선택합니다:
- 새 커밋을 위해 모든 것을 스테이징된 상태로 유지하고 싶다면
--soft를 사용합니다. - 변경 사항은 유지하되 인덱스를 깨끗하게 시작하고 싶다면
--mixed를 사용합니다. - 나중 작업을 버려도 된다고 확신할 때만
--hard를 사용합니다.
- 새 커밋을 위해 모든 것을 스테이징된 상태로 유지하고 싶다면
- 선택한 명령을 실행합니다.
협업 팁
다른 사람과 작업할 때(예: 공유 “Todo” 저장소) 공개 히스토리를 재작성하지 않도록 합니다:
- 이미 공유 브랜치에 푸시된 커밋에 대해
git reset --hard를 절대 사용하지 마세요. - 공개 커밋을 되돌려야 할 경우, 대신
git revert사용을 고려하세요; 이는 히스토리를 재작성하지 않고 변경 사항을 되돌리는 새로운 커밋을 생성합니다.
이 세 가지 reset 모드를 이해하면, 코드 버전 사이를 자신 있게 이동하면서 실수로 인한 데이터 손실이나 병합 충돌 위험을 최소화할 수 있습니다.