Search

Pro Git 2장 - Git의 기초 (1/2)

Git의 기초: 저장소 생성부터 히스토리 조회까지

이번에 Pro Git 책을 통해 Git에 대해 체계적으로 공부하면서, 2장에서 다루는 Git의 기초적인 내용들을 정리하고자 합니다. 특히 저장소 생성, 변경사항 관리, 그리고 커밋 히스토리 조회와 관련된 내용을 중심으로 살펴보겠습니다.

1. Git 저장소 만들기

Git 저장소를 시작하는 방법은 크게 두 가지입니다.

1.1 기존 디렉토리를 Git 저장소로 만들기

기존 프로젝트 디렉토리를 Git으로 관리하고 싶다면 해당 디렉토리에서 다음 명령어를 실행합니다:
$ git init
Shell
복사
이 명령은 .git이라는 숨김 디렉토리를 생성합니다. 이 디렉토리는 Git 저장소의 핵심이며, 프로젝트의 모든 변경사항과 이력을 저장하는 곳입니다. 하지만 git init 명령만으로는 어떤 파일도 관리되지 않습니다. 파일을 Git의 관리 하에 두려면 다음 명령어로 파일을 추가하고 커밋해야 합니다:
$ git add *.c $ git add LICENSE $ git commit -m '초기 프로젝트 버전'
Shell
복사
.git 디렉토리는 프로젝트의 "심장"과 같습니다. 이 디렉토리를 삭제하면 Git의 모든 이력이 사라지므로 주의해야 합니다. 반면, 다른 작업 디렉토리에 이 .git 디렉토리를 복사하면 이력을 그대로 유지한 채 프로젝트를 복제할 수 있습니다.

1.2 기존 저장소를 Clone 하기

다른 곳에 있는 Git 저장소를 복제하려면 git clone 명령을 사용합니다:
$ git clone https://github.com/libgit2/libgit2
Shell
복사
이 명령은 지정한 URL의 저장소 전체를 로컬에 복제합니다. 디렉토리 이름을 변경하고 싶다면 다음과 같이 추가 인자를 지정할 수 있습니다:
$ git clone https://github.com/libgit2/libgit2 mylibgit
Shell
복사
git clone은 단순히 최신 버전만 가져오는 것이 아니라 저장소의 모든 이력과 브랜치를 가져옵니다. 이는 중앙집중식 버전 관리 시스템(SVN 등)과 Git의 가장 큰 차이점 중 하나입니다. 네트워크 연결이 끊겨도 로컬에서 모든 작업을 계속할 수 있습니다.
Git은 다양한 프로토콜을 지원합니다. https://뿐만 아니라 git://, SSH(user@server:path/to/repo.git) 등을 사용할 수 있습니다. SSH는 인증과 보안이 필요한 경우에 자주 사용됩니다.

2. 수정하고 저장소에 저장하기

저장소를 만든 후에는 파일을 수정하고 변경사항을 저장하는 작업이 Git 워크플로의 핵심입니다. Git에서 파일은 여러 상태를 가질 수 있다는 것을 이해하는 것이 중요합니다.

2.1 파일의 상태 이해하기

Git 저장소 내의 파일은 크게 다음 상태로 나뉩니다:
1.
Tracked (관리대상): Git이 알고 있는 파일
Unmodified: 수정되지 않은 상태
Modified: 수정됐지만 아직 커밋을 위한 스테이징이 되지 않은 상태
Staged: 다음 커밋에 포함될 것이라고 표시된 상태
2.
Untracked (비관리대상): Git이 관리하지 않는 파일
이 라이프사이클은 Git 워크플로의 기본입니다:
Git의 세 가지 주요 영역을 이해하는 것이 중요합니다:
워킹 디렉토리: 실제 파일이 있는 곳
스테이징 영역(인덱스): 다음 커밋에 포함될 변경사항을 준비하는 곳
Git 저장소: 커밋된 내용이 안전하게 저장된 곳
대부분의 Git 작업은 이 세 영역 사이의 데이터 이동으로 볼 수 있습니다.

2.2 파일 상태 확인하기

현재 파일들의 상태를 확인하려면 git status 명령을 사용합니다:
$ git status On branch master Your branch is up-to-date with 'origin/master'. nothing to commit, working directory clean
Shell
복사
위 메시지는 모든 파일이 Tracked이면서 Unmodified 상태임을 나타냅니다. 만약 새 파일을 추가하면:
$ echo 'My Project' > README $ git status On branch master Untracked files: (use "git add <file>..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)
Shell
복사
상태 출력이 너무 길다면 간략한 상태를 보는 옵션을 사용할 수 있습니다:
$ git status -s M README MM Rakefile A lib/git.rb ?? LICENSE.txt
Shell
복사
각 파일 앞의 코드는 상태를 나타냅니다:
?? - Untracked
A - Staged (Added)
M - Modified 왼쪽 컬럼은 스테이징 영역의 상태, 오른쪽은 워킹 트리의 상태입니다.

2.3 파일 추적하기

새 파일을 Git이 추적하도록 하려면 git add 명령을 사용합니다:
$ git add README
Shell
복사
git add는 단순히 파일을 추적하는 것뿐만 아니라, 수정된 파일을 스테이징 영역에 추가하는 역할도 합니다. 이는 Git에서 가장 중요한 명령어 중 하나입니다.
git add 명령은 일반적으로 "파일 추가"로 생각하기 쉽지만, 정확히는 "다음 커밋에 이 내용을 포함시키겠다"는 의미입니다. 이 개념을 이해하면 Git의 스테이징 메커니즘을 더 효과적으로 활용할 수 있습니다.

2.4 변경 사항 스테이징하기

이미 추적 중인 파일을 수정하면 "Changes not staged for commit" 섹션에 표시됩니다:
$ git status Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: CONTRIBUTING.md
Shell
복사
이 파일을 스테이징하려면 다시 git add 명령을 사용합니다:
$ git add CONTRIBUTING.md
Shell
복사
파일을 스테이징한 후에 다시 수정하면, 해당 파일은 Staged 상태이면서 동시에 Modified 상태가 됩니다. 이 경우 마지막으로 git add를 실행한 버전만 커밋됩니다. 가장 최신 변경사항을 커밋하려면 다시 git add를 실행해야 합니다.

2.5 파일 무시하기

Git에서 추적하지 않을 파일 패턴을 지정하려면 .gitignore 파일을 사용합니다:
$ cat .gitignore *.[oa] *~
Shell
복사
.gitignore 파일 패턴 규칙:
빈 줄이나 #로 시작하는 줄은 무시됩니다.
표준 Glob 패턴을 사용합니다.
/로 시작하면 하위 디렉토리에는 적용되지 않습니다.
디렉토리는 끝에 /를 붙여 표시합니다.
!로 시작하는 패턴은 무시하지 않습니다.
프로젝트를 시작할 때 .gitignore 파일을 먼저 설정하는 것이 좋습니다. GitHub에서는 다양한 프로젝트 유형에 대한 표준 .gitignore 템플릿을 제공합니다.

2.6 변경 내용 확인하기

파일이 어떻게 변경되었는지 정확히 보려면 git diff 명령을 사용합니다:
$ git diff
Shell
복사
이 명령은 워킹 디렉토리와 스테이징 영역 사이의 차이(staged 되지 않은 변경사항)를 보여줍니다. 스테이징된 변경사항을 보려면:
$ git diff --staged
Shell
복사
git diff는 단순히 변경사항을 보는 것뿐만 아니라, 커밋하기 전에 변경 내용을 검토하는 마지막 기회입니다. 이 명령어를 습관적으로 사용하면 의도하지 않은 변경사항이 커밋되는 것을 방지할 수 있습니다.

2.7 변경사항 커밋하기

스테이징 영역에 있는 내용을 커밋하려면 git commit 명령을 사용합니다:
$ git commit
Shell
복사
이 명령을 실행하면 설정된 에디터가 열리고 커밋 메시지를 입력할 수 있습니다. 또는 인라인으로 메시지를 지정할 수 있습니다:
$ git commit -m "Story 182: Fix benchmarks for speed"
Shell
복사
좋은 커밋 메시지는 프로젝트의 이력을 이해하는 데 매우 중요합니다. "무엇을 변경했는지"보다 "왜 변경했는지"에 초점을 맞추는 것이 좋습니다. 일반적으로 첫 줄은 50자 이내의 요약, 그 다음 빈 줄, 그리고 자세한 설명을 포함하는 형식을 권장합니다.

2.8 Staging Area 생략하기

매번 git add를 실행하는 것이 번거롭다면, git commit -a 옵션을 사용하여 추적 중인 모든 파일을 자동으로 스테이징하고 커밋할 수 있습니다:
$ git commit -a -m 'added new benchmarks'
Shell
복사
주의: 이 옵션은 편리하지만, 어떤 변경사항이 커밋되는지 정확히 알지 못할 수 있으므로 주의해서 사용해야 합니다. 특히 여러 개의 독립적인 변경사항을 작업 중일 때는 개별적으로 스테이징하고 커밋하는 것이 더 좋습니다.

2.9 파일 삭제하기

Git에서 파일을 삭제하려면 git rm 명령을 사용합니다:
$ git rm PROJECTS.md
Shell
복사
이 명령은 워킹 디렉토리에서 파일을 삭제하고, 그 변경사항을 스테이징 영역에 추가합니다.
파일을 이미 수정했거나 스테이징했다면, -f 옵션을 사용하여 강제로 삭제해야 합니다:
$ git rm -f file.txt
Shell
복사
스테이징 영역에서만 제거하고 워킹 디렉토리에는 파일을 유지하려면:
$ git rm --cached README
Shell
복사
git rm은 여러 파일에 glob 패턴을 사용할 수 있습니다:
$ git rm log/\*.log
Shell
복사
백슬래시(\)는 쉘이 아닌 Git이 파일명 확장을 처리하도록 합니다.

2.10 파일 이름 변경하기

Git은 파일 이름 변경을 명시적으로 추적하지 않지만, git mv 명령을 제공합니다:
$ git mv file_from file_to
Shell
복사
이 명령은 사실 다음 세 명령을 순차적으로 실행한 것과 동일합니다:
$ mv file_from file_to $ git rm file_from $ git add file_to
Shell
복사
Git이 파일 이름 변경을 직접 추적하지 않는다는 사실은 처음에는 이상해 보일 수 있습니다. 그러나 Git은 파일의 내용을 기반으로 변경사항을 추적하므로, 이름이 변경된 파일도 내용이 유사하면 자동으로 감지할 수 있습니다. 이는 Git의 내용 중심 설계 철학을 보여줍니다.

3. 커밋 히스토리 조회하기

Git 저장소의 변경 이력을 확인하는 것은 매우 중요합니다. git log 명령은 다양한 옵션으로 히스토리를 조회할 수 있게 해줍니다.

3.1 기본 로그 보기

가장 기본적인 형태는 다음과 같습니다:
$ git log commit ca82a6dff817ec66f44342007202690a93763949 Author: Scott Chacon <schacon@gee-mail.com> Date: Mon Mar 17 21:52:11 2008 -0700 changed the version number commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 Author: Scott Chacon <schacon@gee-mail.com> Date: Sat Mar 15 16:40:33 2008 -0700 removed unnecessary test
Shell
복사
결과는 시간 역순으로 표시되며, 각 커밋의 SHA-1 체크섬, 저자 정보, 날짜, 커밋 메시지를 보여줍니다.
로그 출력은 기본적으로 pager(예: less)를 통해 표시되므로, 스페이스바로 페이지를 넘기고 q로 종료할 수 있습니다.

3.2 다양한 로그 포맷

각 커밋의 변경 내용을 함께 보려면 -p 또는 --patch 옵션을 사용합니다:
$ git log -p
Shell
복사
출력 개수를 제한하려면:
$ git log -p -2 # 최근 2개의 커밋만 표시
Shell
복사
통계 정보를 보려면 --stat 옵션을 사용합니다:
$ git log --stat
Shell
복사
다양한 출력 형식을 위해 --pretty 옵션을 사용할 수 있습니다:
$ git log --pretty=oneline ca82a6d changed the version number 085bb3b removed unnecessary test
Shell
복사
format 옵션으로 출력 형식을 직접 지정할 수도 있습니다:
$ git log --pretty=format:"%h - %an, %ar : %s" ca82a6d - Scott Chacon, 11 years ago : changed the version number 085bb3b - Scott Chacon, 11 years ago : removed unnecessary test
Shell
복사
자주 사용하는 로그 형식은 별칭(alias)으로 설정해두면 편리합니다:
$ git config --global alias.lg "log --pretty=format:'%h - %an, %ar : %s'"
Shell
복사
이후 git lg만으로 해당 형식의 로그를 볼 수 있습니다.

3.3 로그 조회 제한하기

Git은 다양한 방법으로 로그 출력을 제한할 수 있습니다.
시간을 기준으로 조회:
$ git log --since=2.weeks # 최근 2주 동안의 커밋
Shell
복사
저자를 기준으로 조회:
$ git log --author="John Doe"
Shell
복사
커밋 메시지 내용으로 검색:
$ git log --grep="bug fix"
Shell
복사
코드 변경 내용으로 검색:
$ git log -S"function_name" # 특정 함수가 추가되거나 제거된 커밋
Shell
복사
특정 파일이나 디렉토리의 변경 이력만 조회:
$ git log -- path/to/file
Shell
복사
여러 조건을 조합할 수 있습니다. 예를 들어, 특정 파일에서 특정 함수가 변경된 커밋을 찾으려면:
$ git log -S"function_name" -- path/to/file
Shell
복사
이러한 기능을 활용하면 대규모 프로젝트에서도 원하는 변경사항을 빠르게 찾을 수 있습니다.

결론

Git의 기초 명령어들은 겉보기에는 간단하지만, 먼저 고유의 개념들을 이해해야 합니다. 특히 Git의 세 가지 영역(워킹 디렉토리, 스테이징 영역, 저장소)과 파일의 상태(Untracked, Modified, Staged, Committed)를 이해하는 것은 Git을 효과적으로 사용하는 데 핵심입니다.
단순히 명령어를 암기하는 것보다 Git의 작동 원리를 이해하면, 복잡한 상황에서도 문제를 해결할 수 있는 능력이 생깁니다. 또한 Git의 다양한 옵션과 기능을 활용하면, 개발 워크플로를 더욱 효율적으로 만들 수 있습니다.