본문 바로가기

프로그래밍/기타

[Git] Git의 기초 1 - Pro git book, 2nd Edition 정리

반응형

2.1. Git 저장소 만들기

Git을 사용하는 방법을 알고 싶은데 한 챕터밖에 읽을 시간이 없다면 이번 챕터를 읽어야 한다. Git에서 자주 사용하는 명령어는 모두 2장에 등장한다.

Git 저장소 만들기

  1. 아직 버전관리를 하지 않은 로컬 디렉토리 하나를 선택해서 Git 저장소를 적용하는 방법
  2. 다른 어딘가에서 Git 저장소를 Clone 하는 방법

기존 디렉토리를 Git으로 만들기

해당 디렉토리로 가서 명령어를 입력한다. 시스템마다 디렉토리 이동 명령어가 조금 다른 점을 주의하자.

$ git init

이 명령은 .git 이라는 하위 디렉토리를 만든다. .git 디렉토리에는 저장소에 필요한 뼈대 파일이 들어 있다. 이 명령만으로는 아직 프로젝트의 어떤 파일도 관리하지 않는다.

Git이 파일을 관리하게 하려면 저장소에 파일을 추가하고 커밋해야 한다.git add 명령으로 파일을 추가하고 git commit 명령으로 커밋한다

$ git add *.c
$ git add LICENSE
$ git commit -m 'initial project version'

기존저장소를 Clone하기

다른 프로젝트에 참여하거나(Contribute) Git 저장소를 복사하고 싶을 때 git clone

명령을 사용한다.

$ git clone <https://github.com/libgit2/libgit2>

아래과 같은 명령을 사용하여 저장소를 Clone 하면 libgit2이 아니라 다른 디렉토리 이름으로 Clone 할 수 있다.

$ git clone <https://github.com/libgit2/libgit2> mylibgit

Git은 다양한 프로토콜을 지원한다. 이제까지는 https:// 프로토콜을 사용했지만 git://를 사용할 수도 있고 user@server:path/to/repo.git 처럼 SSH 프로토콜을 사용할 수도 있다.

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

워킹 디렉토리의 모든 파일은 크게 Tracked(관리대상)와 Untracked(관리대상이 아님)로 나눈다. Tracked 파일은 이미 스냅샷에 포함돼 있던 파일이다. Tracked 파일은 또 Unmodified(수정하지 않음)와 Modified(수정함) 그리고 Staged(커밋으로 저장소에 기록할) 상태 중 하나이다. 간단히 말하자면 Git이 알고 있는 파일이라는 것이다.

  • Tracked
  • Unmodified
  • Modified
  • Staged
  • Untracked

파일의 상태 확인하기

파일의 상태를 확인하려면 보통 git status 명령을 사용한다. Clone 한 후에 바로 이 명령을 실행하면 아래과 같은 메시지를 볼 수 있다.

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

위의 내용은 파일을 하나도 수정하지 않았다는 것을 말해준다.

리고 현재 작업 중인 브랜치를 알려주며 서버의 같은 브랜치로부터 진행된 작업이 없는 것을 나타낸다.

파일을 새로 추적하기

git add 명령으로 파일을 새로 추적할 수 있다. 아래 명령을 실행하면 Git은 README 파일을 추적한다.

$ git add README

git add명령은 파일을 새로 추적할 때도 사용하고 수정한 파일을 Staged 상태로 만들 때도 사용한다. Merge 할 때 충돌난 상태의 파일을 Resolve 상태로 만들때도 사용한다. add의 의미는 프로젝트에 파일을 추가한다기 보다는 다음 커밋에 추가한다고 받아들이는게 좋다.

git add 명령을 실행하면 Git은 파일을 바로 Staged 상태로 만든다. 지금 이 시점에서 커밋을 하면 git commit 명령을 실행하는 시점의 버전이 커밋되는 것이 아니라 마지막으로 git add 명령을 실행했을 때의 버전이 커밋된다.

파일 상태를 짤막하게 확인하기

git status 명령으로 확인할 수 있는 내용이 좀 많아 보일 수 있다. 좀 더 간단하게 변경 내용을 보여주는 옵션이 있다.

git status -s 또는 git status --short

$ git status -s
 M README
MM Rakefile
A  lib/git.rb
M  lib/simplegit.rb
?? LICENSE.txt

??: 아직 추적하지 않는 새 파일

A: Staged 상태로 추가한 파일 중 새로 생성한 파일

M: 수정한 파일

왼쪽에는 Staging Area에서의 상태를, 오른쪽에는 Working Tree에서의 상태를 표시한다.

README 파일 같은 경우 내용을 변경했지만 아직 Staged 상태로 추가하지는 않았다.

lib/simplegit.rb 파일은 내용을 변경하고 Staged 상태로 추가까지 한 상태이다.

Rakefile 은 변경하고 Staged 상태로 추가한 후 또 내용을 변경해서 Staged 이면서 Unstaged 상태인 파일이다.

파일 무시하기

.gitignore 파일을 만들고 그 안에 무시할 파일 패턴을 적는다. 아래는 .gitignore 파일의 예이다.

$ cat .gitignore
*.[oa]
*~

첫번째 라인은 확장자가 “.o” 나 “.a” 인 파일을 Git이 무시하라는 것이고 둘째 라인은 ~ 로 끝나는 모든 파일을 무시하라는 것이다.

.gitignore 파일에 입력하는 패턴은 아래 규칙을 따른다.

  • 아무것도 없는 라인이나, #로 시작하는 라인은 무시한다.
  • 표준 Glob 패턴을 사용한다. 이는 프로젝트 전체에 적용된다.
  • 슬래시(/)로 시작하면 하위 디렉토리에 적용되지(Recursivity) 않는다.
  • 디렉토리는 슬래시(/)를 끝에 사용하는 것으로 표현한다.
  • 느낌표(!)로 시작하는 패턴의 파일은 무시하지 않는다.

Glob 패턴은 정규표현식을 단순하게 만든 것으로 생각하면 되고 보통 쉘에서 많이 사용한다.

아래는 .gitignore 파일의 예이다.

# 확장자가 .a인 파일 무시
*.a

# 윗 라인에서 확장자가 .a인 파일은 무시하게 했지만 lib.a는 무시하지 않음
!lib.a

# 현재 디렉토리에 있는 TODO파일은 무시하고 subdir/TODO처럼 하위디렉토리에 있는 파일은 무시하지 않음
/TODO

# build/ 디렉토리에 있는 모든 파일은 무시
build/

# doc/notes.txt 파일은 무시하고 doc/server/arch.txt 파일은 무시하지 않음
doc/*.txt

# doc 디렉토리 아래의 모든 .pdf 파일을 무시
doc/**/*.pdf

<aside> 💡 GitHub은 다양한 프로젝트에서 자주 사용하는 .gitignore 예제를 관리하고 있다. 어떤 내용을 넣을지 막막하다면 https://github.com/github/gitignore 사이트에서 적당한 예제를 찾을 수 있다.

</aside>

<aside> 💡 .gitignore를 사용하는 간단한 방식은 하나의.gitignore 파일을 최상위 디렉토리에 하나 두고 모든 하위 디렉토리에까지 적용시키는 방식이다. 물론 .gitignore 파일을 하나만 두는 것이 아니라 하위 디렉토리에도 추가로 둘 수도 있다. .gitignore 정책은 현재 .gitignore 파일이 위치한 디렉토리와 그 하위 디렉토리에 적용된다. (리눅스 커널 소스 저장소에는 .gitignore 파일이 206개나 있음) 다수의 .gitignore 파일을 두고 정책을 적용하는 부분은 이 책에서 다루는 범위를 벗어난다. 자세한 내용은 man gitignore에서 확인할 수 있다.

</aside>

Staged와 Unstaged 상태의 변경 내용을 보기

단순히 파일이 변경됐다는 사실이 아니라 어떤 내용이 변경됐는지 살펴보려면 git diff 명령을 사용해야 한다. git diff 명령을 실행하면 수정했지만 아직 staged 상태가 아닌 파일을 비교해 볼 수 있다.

이 명령은 워킹 디렉토리에 있는 것과 Staging Area에 있는 것을 비교한다. 그래서 수정하고 아직 Stage 하지 않은 것을 보여준다. 만약 커밋하려고 Staging Area에 넣은 파일의 변경 부분을 보고 싶으면 git diff --staged 옵션을 사용한다. 이 명령은 저장소에 커밋한 것과 Staging Area에 있는 것을 비교한다.  --staged 와 --cached 는 같은 옵션이다.

꼭 잊지 말아야 할 것이 있는데 git diff 명령은 마지막으로 커밋한 후에 수정한 것들 전부를 보여주지 않는다. git diff 는 Unstaged 상태인 것들만 보여준다. 수정한 파일을 모두 Staging Area에 넣었다면 git diff 명령은 아무것도 출력하지 않는다.

→ 소스트리 stage칸에서는 자동으로 git diff —staged를 보여주고, 아래칸에서는 git diff를 보여주는군

변경사항 커밋하기

git commit을 실행하여 커밋한다.

자동으로 생성되는 커밋 메시지의 첫 라인은 비어 있고 둘째 라인부터 git status 명령의 결과가 채워진다. 커밋한 내용을 쉽게 기억할 수 있도록 이 메시지를 포함할 수도 있고 메시지를 전부 지우고 새로 작성할 수 있다

메시지를 인라인으로 첨부할 수도 있다. commit 명령을 실행할 때 아래와 같이 -m 옵션을 사용한다.

$ git commit -m "Story 182: Fix benchmarks for speed"
[master 463dc4f] Story 182: Fix benchmarks for speed
 2 files changed, 2 insertions(+)
 create mode 100644 README

Git은 Staging Area에 속한 스냅샷을 커밋한다는 것을 기억해야 한다. 수정은 했지만, 아직 Staging Area에 넣지 않은 것은 다음에 커밋할 수 있다. 커밋할 때마다 프로젝트의 스냅샷을 기록하기 때문에 나중에 스냅샷끼리 비교하거나 예전 스냅샷으로 되돌릴 수 있다.

Staging Area 생략하기

Staging Area는 커밋할 파일을 정리한다는 점에서 매우 유용하지만 복잡하기만 하고 필요하지 않은 때도 있다. 아주 쉽게 Staging Area를 생략할 수 있다. git commit 명령을 실행할 때 -a 옵션을 추가하면 Git은 Tracked 상태의 파일을 자동으로 Staging Area에 넣는다. 그래서 git add 명령을 실행하는 수고를 덜 수 있다.

파일 삭제하기

Git에서 파일을 제거하려면 git rm 명령으로 Tracked 상태의 파일을 삭제한 후에(정확하게는 Staging Area에서 삭제하는 것) 커밋해야 한다. 이 명령은 워킹 디렉토리에 있는 파일도 삭제하기 때문에 실제로 파일도 지워진다.

파일 이름 변경하기

Git은 다른 VCS 시스템과는 달리 파일 이름의 변경이나 파일의 이동을 명시적으로 관리하지 않는다. 다시 말해서 파일 이름이 변경됐다는 별도의 정보를 저장하지 않는다. Git은 똑똑해서 굳이 파일 이름이 변경되었다는 것을 추적하지 않아도 아는 방법이 있다.

반응형