[Git] Git 기초 , 기본 사용법 (1) - 파일의상태, 삭제, 변경, 커밋 히스토리 조회

권준혁·2020년 11월 1일
4

Git

목록 보기
2/8
post-thumbnail

안녕하세요!
Git 기초, 기본 사용법에 대한 포스팅입니다.

git add .
git commit -m "update ........."
git push origin master

익숙한 메세지입니다.
저 처럼 github를 혼자서만 사용했다면 더 익숙하게 느껴질 거라 생각합니다.

개발자가 되려면 github를 해야된다는 말을 듣고 기계처럼 사용하던 명령어들인데, 더 이상 잘 모르고 사용하지 않도록 기초부터 닦아야겠다는 생각이 들기도 했고,
입사를 하게되면 가장 걱정되는 협업..
사실 깃허브로 협업을 시작하면 실수로 폐를 끼치지 않을까? 하는 노파심이 가장 컸습니다.
이 번 기회에 제대로 알고 써야겠습니다 !


1. Git 저장소 만들기

Git 저장소를 만드는 방법은 두 가지 입니다.

  • 기존 프로젝트나 디렉터리를 Git저장소로 만드는 방법
  • 다른 서버에 있는 저장소를 Clone하는 방법

1-1. 기존 디렉터리 Git저장소로 만들기

해당 디렉터리로 이동해 git init 명령을 실행합니다.

git init

이 명령을 실행하면 .git이라는 하위 디렉터리가 생성됩니다.

1-2. 기존 저장소를 clone하기

다른 프로젝트에 참여하거나 Git저장소를 복사하고 싶을 때 사용합니다.

git clone <url>

git clone 명령을 실행하면 서버에 있는 거의 모든 데이터 (서버에만 적용한 설정 제외) 를 복사합니다.
프로젝트 히스토리를 모두 받아오므로 실제로 서버의 디스크가 망가져도 클라이언트 저장소 중에서 아무거나 하나 가져다가 복구하면 됩니다.

git clone 명령을 실행하면 저장소의 데이터를 모두 가져온 뒤, 자동으로 가장 최신 버전을 Checkout해 놓습니다.
다시말해 프로젝트 히스토리를 실제로 복사해오지만 최신 버전을 자동으로 Checkout해주기 때문에 DVCS가 아닌 다른 VCS처럼 최신 코드를 바로 사용하는 장점도 가집니다.

실습을 위해 저장소를 가져와보겠습니다.

git clone https://github.com/libgit2/libgit2

2. 수정과 저장

워킹 디렉터리의 모든 파일은 크게 Tracked(관리대상임)Untracked(관리대상이 아님)으로 나뉩니다.
그리고 Tracked 파일은 Unmodified, Modified, Staged 상태 중 하나입니다.

git clone으로 스냅샷을 가져왔을 때, 모든파일은 Tracked 면서 Unmodified입니다. 파일을 수정하면 Modified상태가 되고 git add 명령으로 Staged상태로 만들 수 있습니다.
git commit을 하고나면 다시 Unmodified상태가 됩니다.

이 상태들을 확인인하려면 git status 명령을 사용합니다.

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

현재 branch는 기본 branch인 master이고, Unmodified상태기 때문에 commit할 파일이 없습니다.
git clone를 이용해 워킹디렉토리로 데이터를 불러왔지만, 아무 것도 수정하지 않았기 때문에 당연히 up-to-date 입니다.

2-1. Untracked 상태의 파일 Tracked 상태로 만들기

텍스트파일을 하나 생성해보겠습니다. 그럼 이 파일은 Untracked가 됩니다.

$ git status
On branch master
Your branch is up-to-date with 'origin/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)

메세지에서 가장 윗 세줄은 아까와 동일하지만, Untracked files 목록을 함께 보여줍니다. git add 명령어로 commit 할 목록에 추가하라는 메세지가 나옵니다.
git add README 명령을 실행하면 Tracked상태가 될 겁니다.
기존에 git add . 로 항상 모든 파일을 Tracked로 바꿨던게 생각나네요

정상적으로 git add README가 성공했다면 아래의 메세지가 확인됩니다.

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
new file: README

README파일은 이제 staged 상태입니다.
디렉토리를 git add로 추가했다면 하위의 모든 파일들을 재귀적으로 추가하게 됩니다.

2-2. Modified 상태의 파일을 Stage하기

먼저 Modified상태의 파일을 만들기 위해 임의의 파일 하나를 수정해보겠습니다.
README.md 파일을 열어서 아무 문자나 넣어서 수정해봤습니다.

git status 명령어를 실행해보면 아래와 같은 메세지가 확인됩니다.

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
new file: README
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: README.md

Changes not staged for commit 이라는 메세지와 함께 변경된 파일이름이 출력됩니다.
이 번에도 역시 git add README.md 를 실행해 staged 상태로 만들어야 합니다.
git add 명령어는

~프로젝트에 파일을 추가한다는 의미~

보다 다음 커밋에 추가한다는 의미로 이해하는게 맞습니다.

$ git add README.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
new file: README
modified: README.md

git add README.md를 실행하고 난 뒤, 이대로 커밋하지않고 파일을 더 수정해야 한다고 가정해보겠습니다.
README.md를 다시 수정한 뒤 git status를 실행한 결과입니다.

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
new file: README
modified: README.md
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: README.md

Chages to be committed 커밋할 준비가 된 상태의 README.md가 있고
Changes not staged for commit에 not staged 상태의 README.md가 있습니다.
그러니까 마지막으로 git add 를 했을 시점의 버전이 커밋되는 것입니다.
수정을 했고 커밋을 해야한다면 반드시 git add 명령어로 staged상태로 만들어줘야 합니다.

git add 명령어로 다시 새롭게 추가해주세요

$ git add README.md
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
    (use "git reset HEAD <file>..." to unstage)
new file: README
modified: README.md

3. 간단한 상태확인

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

README파일은 내용을 변경했지만 아직 staged 상태로 추가하지 않은 상태
lib/simplegit.rb는 내용을 변경하고 staged 상태로 추가까지 한 상태
lib/git.rb는 새로 생성된 파일
Rakefile은 바로 위에서 README와 마찬가지로 staged면서 unstaged인 상태
LICENSE.txt는 untracked 상태입니다.

4. 파일 무시하기

git으로 관리하고싶지 않은 파일은 .gitignore에 작성하면 자동으로 무시됩니다.
.gitignore 파일에 입력하는 패턴은 아래 규칙을 따릅니다.

  • 아무것도 없는 라인이나 , #로 시작하는 라인은 무시한다.
  • 표준 Glob 패턴을 사용한다.
  • 슬래시로 시작하면 하위 디렉터리에 적용되지 않는다.
  • 디렉터리는 슬래시를 끝에 사용하는 것으로 표현한다.
  • 느낌표로 시작하는 패턴의 파일은 무시하지 않는다.

4-1. .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

더 많은 사용 예 보기 : A collection of .gitignore templates

5. 상태의 변경 내용 보기

지금까지 git status 명령어로 상태를 확인했습니다. 하지만, 변경된 내용까지 보고싶다면 git diff 명령어로 볼 수 있습니다.

  • git diff 명령은 수정했지만 아직 staged 상태가 아닌 파일을 비교해 볼 수 있습니다. modified 상태
    워킹 디렉터리와 Staging Area를 비교한다
  • git diff --staged *_처럼 옵션을 넣어주면 *_staged 상태의 파일을 비교합니다. --staged옵션 대신에 --cached 옵션을 사용해도 됩니다.
    저장소에 커밋한 것과 Staging Area를 비교한다

내가 git add를 하기전이라면 git diff로 비교를 하고, git add를 실행한 뒤 저장소와 비교하려면 git diff --staged로 비교하면 되겠습니다.
따라서, 만약 git add . 로 모든 파일들을 staged상태로 만들었다면, git diff는 아무 것도 출력하지 않게됩니다.

6. 변경사항 커밋하기

$ git commit -m "first commit"
[master 3edbf5e81]  first commit
 3 files changed, 3 insertions(+), 3 deletions(-)
 create mode 100644 README

commit을 실행해보면 3edbf5e81 체크섬(자료의 무결성을 위해 사용되는 문자, 커밋마다 항상 다르다.)과 함께 결과 메세지가 로깅됩니다.
이 때 스냅샷을 커밋하게됩니다. 따라서 나중에 스냅샷끼리 비교하거나 예전 스냅샷으로 돌릴 수 있는 것입니다.

7. Staging Area 생략하기

Staging Area는 커밋할 파일을 대기시킨다는 점에서 유용하지만, 필요하지 않은 경우도 있습니다. Staging Area를 생략하는 수도 있습니다.

$ git commit -a -m "second commit"

-a 옵션을 사용하면 자동으로 tracked 상태의 파일을 자동으로 Staging Area에 넣어줍니다.
주의할 점은 새로 생성된 파일은 tracked가 아니라는 점입니다.

8. 파일 삭제하기

가장 중요한 삭제입니다.

Git에서 파일을 삭제하려면 git rm 명령으로 Tracked상태의 파일을 삭제한 후, 커밋해야 합니다. (정확히는 Staging Area에서 삭제하는 것이지만 워킹 디렉토리에서도 삭제됩니다.)

  • 명령어를 사용하지 않고 워킹디렉토리에서 직접 삭제하는 경우
    Staging Area에서는 삭제되지 않습니다.
    따라서, git status명령으로 상태를 확인하면 "Changes not staged for commit" 이라는 메세지를 만나게 됩니다.
    조금 헷갈릴 수도 있는데, 삭제한 파일이 statged 상태, deleted 상태로 commit이 이루어져야 저장소의 파일이 삭제되는 것입니다.
    커밋을 받는 저장소에서도 명시적으로 어떤 파일이 삭제됐는지 알아야 하기 때문입니다.

한 번 실습해보겠습니다.

$ git rm grit.gemspec
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working
directory)
  deleted: grit.gemspec
no changes added to commit (use "git add" and/or "git commit -a")

그리고 git rm 명령을 실행하면 삭제된 파일은 Staged상태가 됩니다.

$ git rm grit.gemspec
rm 'grit.gemspec'
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
  deleted: grit.gemspec

이 상태에서 커밋하게 되면 저장소의 grit.gemspec은 삭제되고 더 이상 트래킹하지 않습니다.
만약 이미 파일을 수정했거나 Staging Area에 추가했다면 git rm -f 로 옵션을 주어야 합니다.
커밋하지 않고 수정한 데이터는 Git으로 복구할 수 없기 때문에 옵션을 넣는 안전장치 가 필요한 것입니다.

  • Staging Area에서만 삭제하는 경우
    다시 말해서 하드디스크에 있는 파일은 그대로 두고 Git만 추적하지 않게 하는 것
 $ git rm --cached README

--cached 옵션을 넣어 Staging Area에서만 삭제되게 할 수 있습니다.
실수로 Staging Area에 넣은 경우 사용하게 됩니다.

여러 개의 파일을 삭제하고 싶은 경우에는 file-glob패턴 을 사용하게 됩니다.

  • 예를 들어 log/ 디렉터리에 있는 .log파일들을 모두 삭제하고 싶을 경우

    $ git rm log/\*.log
  • ~로 끝나는 파일을 모두 삭제하고 싶은 경우

    $ git rm \*~

9. 파일 이름 변경하기

mv 명령어를 사용해 이름을 바꿔보겠습니다.

$ git mv README.md README
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
  renamed: README.md -> README

Git은 이름이 바뀐 것을 인지하고 있습니다.
mv명령어는 아래 단축 명령어입니다. 아래의 명령어 3줄을 실행한 것과 같습니다.

$ mv README.md README
$ git rm README.md
$ git add README

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

git log 명령어를 이용해 히스토리를 조회해보겠습니다.

먼저 예제에서 사용할 리포지토리를 가져옵니다.

$ git clone https://github.com/schacon/simplegit-progit

git log 명령어로 히스토리를 출력해보겠습니다.

$ git log
commit ca82a6dff817ec66f44342007202690a93763949 (HEAD -> master, origin/master, origin/HEAD)
Author: Scott Chacon <schacon@gmail.com>
Date:   Mon Mar 17 21:52:11 2008 -0700

    changed the verison number

commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 16:40:33 2008 -0700

    removed unnecessary test code

commit a11bef06a3f659402fe7563abf99ad00de2209e6
Author: Scott Chacon <schacon@gmail.com>
Date:   Sat Mar 15 10:31:28 2008 -0700

    first commit

특별한 옵션없이 git log 명령을 실행하면 저장소의 커밋 히스토리를 시간순으로 보여줍니다.
커밋의 SHA-1 체크섬,저자 이름, 이메일, 날짜, 메세지를 나타냅니다.

자주 쓰이는 유용한 옵션들을 정리해보겠습니다.

  • -p -(number)
    이 옵션은 각 커밋의 diff 결과를 보여줍니다. 여기에 -2 옵션을 사용하면 최근 두개의 결과만 보여주는 옵션이됩니다. 동료가 뭘 했는지 알아볼 때 유용합니다.
    $ git log -p -2
  • --stat
    이 옵션은 각 커밋의 통계 정보를 조회할 수 있습니다. 이 결과에서 얼마나 많은 파일이 변경됐는지, 얼마나 많은 라인이 추가됐는지, 삭제됐는지 보여주게 됩니다. 마지막에는 요약정보를 보여줍니다.
    $ git log --stat
  • --pretty
    이 옵션을 통해 히스토리 내용을 보여줄 때 기본형식 이외에 여러가지 중 하나를 선택할 수 있습니다. 로그를 보고 싶은 형태로 보여줍니다.
    • --pretty=online
    • --pretty=short
    • --pretty=full
    • --pretty=fuller
    • --pretty=format: "..."
      이 옵션은 나만의 포멧으로 결과를 출력할 수 있습니다. 특히, 다른 프로그램으로 결과를 파싱하고자 할 때 유용합니다.
$ git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Scott Chacon, 12 years ago : changed the verison number
085bb3b - Scott Chacon, 12 years ago : removed unnecessary test code
a11bef0 - Scott Chacon, 12 years ago : first commit

--pretty=format: "..." 옵션은 --graph 옵션과 함께 사용할 때 빛납니다.
이 명령은 브랜치와 머지 히스토리를 보여주는 아스키 그래프를 출력합니다.

조회 제한조건

-2 옵션으로 최근 2개의 커밋만을 조회했던 것 처럼, 조회 제한 조건들이 더 있습니다.

  • 이 옵션들 중 시간을 기준으로 조회하는 옵션과 텍스트를 검색할 수 있는 -S 옵션이 유용합니다.
  • 만약 저자를 검색하는 --author--grep 을 함께 사용한다면 --all-match 옵션도 넣어줘야 합니다.

여기까지 Git 기초 첫 번째 포스팅을 마치겠습니다.
읽어주셔서 감사합니다.

profile
웹 프론트엔드, RN앱 개발자입니다.

0개의 댓글