공사중

쉽게 정리한 Git 사용법 : status, commit 이해하기(+diff, vim, .gitignore, 삭제, 이름변경) 본문

개발 | Git

쉽게 정리한 Git 사용법 : status, commit 이해하기(+diff, vim, .gitignore, 삭제, 이름변경)

행운개발자 LuckyDeveloper 2019. 2. 19. 20:09

워킹 디렉토리의 모든 파일은 크게 Tracked 와 Untracked로 나뉩니다.  Tracked파일은 이미 스냅샷에 포함되어있는 파일입니다.  Tracked는 다시 Unmodified, Modified, Staged상태들로 나뉩니다.  


위 사진에서 화살표가 있는 부분만 한 번 보고 끄덕끄덕 하시면 됩니다. 특히 Staged에서 Commit을 하면 Unmidified가 되는 것이 포인트입니다.

현재 디렉토리에 있는 파일들이 위 그림의 네 가지 상태 중 어떤 상태인지를 확인하기 위해서는 아래의 명령어를 사용합니다. 


git status 

위의 내용은 tracked 파일을 하나도 수정하지 않았다는 것을 말해줍니다.  Untracked는 말 그대로 Untracked이니 git이 파일의 변화를 알아채지 못합니다. origin/master라고 나온 것은 나중에 브랜치branch를 공부할 때 다시 설명합니다.


maker@DESKTOP-GL6512D MINGW64 /d/GitTest/stb (master)
$ cd ..

maker@DESKTOP-GL6512D MINGW64 /d/GitTest (master)
$ ls
main.cpp  myFolderName/  README.txt  stb/

maker@DESKTOP-GL6512D MINGW64 /d/GitTest (master)
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        README.txt
        myFolderName/
        stb/

nothing added to commit but untracked files present (use "git add" to track)

maker@DESKTOP-GL6512D MINGW64 /d/GitTest (master)
$ git add README.txt

maker@DESKTOP-GL6512D MINGW64 /d/GitTest (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   README.txt

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        myFolderName/
        stb/


maker@DESKTOP-GL6512D MINGW64 /d/GitTest (master)
$ git status -s
A  README.txt
?? myFolderName/
?? stb/

maker@DESKTOP-GL6512D MINGW64 /d/GitTest (master)
$

1번째 줄 : 상위 디렉토리로 이동

5번째 줄 : 현재 디렉토리의 파일들을 보여줌

9번째 줄 : git status

10~18번째 줄 : 현재 Tracked 된 파일은 없고 모두 Untracked 상태

20번째 줄 : README.txt파일을 staged 상태(Tracked상태)로 추가함

21번째 줄 : git add는 파일 또는 디렉토리를 argument로 받는다. arg가 디렉토리이면 하위 디렉토리까지 staged 상태로 재귀적으로 만든다.

26~29번째 줄 : staged된 파일이 commit되어야한다는 것을 알려주면서 staged된 파일들의 목록을 보여줌.(여기서는 README.txt뿐) 만약 commit이 된다면 staged 된 순간의 데이터를 기준으로 commit이 된다. 예를 들어 git add를 해서 staged 상태로 만들고 파일을 일부 수정한 다음에 다시 git add하지 않고 바로 commit을 하면, git add 이후에 수정한 내용은 commit되지 않는다. 이 때는 "“Changes not staged for commit”라는 문구가 나온다.

31~35번째 줄 : 동시에 Untracked된 파일들도 같이 보여줌. 

39번째 줄 : git status의 정보를 짧게(-short)보여주는 커맨드

40번째 줄 : tracked된 파일은 Staging Area에 Added되었다는 의미에서 A라고 적혀있음

41번째 줄 : Untracked된 파일은 ??가 붙어있음


이 상태에서 README.txt파일을 다시 한 번 수정하고 git status를 쳐보면 아래와 같은 결과가 나옵니다. 

이전에 git add를 했을 때 시점의 데이터는 staged되어서 commit을 기다리는 "Chaged to be comitted"상태이고,

동시에 git add이후에 수정을 하고 다시 git add하지 않는 내용은 "Changes not staged for commit"상태입니다. 

이를 해결하기 위해서는 다시 git add README.txt 해주면 됩니다. 


git status -s

이 명령어는 이러한 상태를 간결하게 표현해줍니다. 왼쪽에는 Staging Area의 상태를, 오른쪽에는 Working Directory의 상태를 보여줍니다.


즉, AM REAMME.txt라고 되어있는 것은

git add를 했을 때의 시점의 데이터는 Staging Area에 Added 되었지만, 

Working direcktory에서는 수정해서 Modified라고 표시된 것입니다. 보통은 -s를 붙혀서 간결한 내용으로 보실 것이라고 생각합니다. 


추가적으로 git add를 할 때 아래와 같이 커맨드를 입력하면 모든 파일을 다 staged 상태로 만들 수 있습니다. 


git add .

그런데 이렇게 모든 파일을 추가하면 편하긴 하지만 임시로 생성되는 ~로 시작하는 파일이나 binary파일까지 Tracked 상태로 바뀌어서 지저분해집니다. 따라서 전체를 한 번에 추가하되 일부 형식의 파일을 제한하는 방법이 있습니다. .gitignore이라는 파일을 만들고 그 안에 어떤 형식의 파일을 추가하지 않을지 적어놓으면 됩니다.


.gitignore를 만들 때는 vim이라는 에디터를 사용하도록 하겠습니다. 여기에서 기본 편집기를 변경하는 방법을 정리했지만..

그래도 vim 에디터도 꼭 사용할 줄 알아야 편하기 때문에 이참에 vim을 사용하도록 하겠습니다. 


다음의 커맨드를 입력합니다.

vim .gitignore

이 명령어를 입력하면 vim에디터로 이동하게 됩니다. 사용 방법을 간단히 정리해보겠습니다.

저장하지 않고 vim 종료 : q! -> [ENTER]
입력모드 나가기 : [ESC]
내용 입력 후 저장 : [내용입력] -> [ESC] -> :wq -> [ENTER]

그리고 아래는 .gitignore을 작성할 때 참고하는 문법입니다.

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

아래는 제가 작성한 .gitignore의 내용입니다. 아래의 내용을 치고 [ESC] -> :wq -> [ENTER]를 눌러서 저장했습니다.

#확장자가 “.o” 나 “.a” 인 파일을 Git이 무시
#“.o” 와 “.a” 는 각각 빌드 시스템이 만들어내는 오브젝트와 아카이브 파일
*.[oa]
#~ 로 끝나는 파일은 텍스트 편집기가 임시로 만들어내는 파일이라서 무시
*~
# 확장자가 .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

이제 git add에 대해서는 충분히 알아봤습니다. 그리고 git status에 대해서도 이해할 수 있게 되었습니다.

그런데 우리는 git status로 Staging Area와 Working Directory에 파일들이 어떤 상태로 있는지 볼 수 있지만, 구체적을 어떤 내용이 변경되었는지는 알 수 없습니다.

그래서 아래와 같은 커맨드를 입력합니다.

git diff

이 명령어는 Staging Area와 Working Directory의 파일이 어떻게 다른지 line by line으로 보여줍니다. 그래서 아직 수정하지 않고 staged 상태로 만들지 않을 것들을 보여줍니다. 즉 Unstaged 상태인 것만 보여주기 때문에 모든 수정 내용을 add하여 staged로 만들면 git diff는 아무것도 출력하지 않습니다.

만약 Local Git Repository(committed상태의 파일)과 Staging Area의 차이를 보고 싶으면 아래와 같이 입력합니다.

git diff --staged
또는(같은 명령어)
git diff --cached

commit을 하면 아래와 같은 결과를 볼 수 있습니다.

master라는 브랜치에 commit을 했고, 체크썸은 3bb3a1d라고 알려줍니다. 그리고 수정된 파일이 몇 개이고 추가되거나 삭제된 라인의 수를 알려줍니다. 


commit을 하기 전에 꼭 git add를 해야하는 수고로움이 있습니다. 어떤 파일을 commit할 것인지 선별할 수 있는 장점이 있지만 좀 불편합니다. 아래와 같이 -a옵션을 추가하면 모든 파일이 자동으로 staged 상태로 추가된 뒤에 commit됩니다. 편리하지만 조심스럽게 사용해야합니다.

git commit -a -m "message"


Git이 더이상 파일을 추적하지 않도록 삭제하는 방법도 있습니다.

기본 명령어 rm을 사용해서 삭제할 때 : Working tree에서만 삭제됨. Unstaged 상태로 변함.

rm README.txt

git 명령어 rm을 사용해서 삭제할 때 : Stagind Area와 Working tree 모두에서 삭제됨. 여전히 staged 상태에 있는 스냅샷에는 해당 파일이 살아있음.

git rm README.txt

--cache를 사용할 때 : Stagind Area에서만 삭제됨. Working tree와 Stagin Area에는 살아있음.

git rm --cache README.txt


git이 추적하는 파일 이름을 변경할 수도 있습니다. 

git mv file_from file_to

위와 같이 파일 이름을 변경합니다. 사실 git mv명령어는 아래의 세 개의 명령어를 단축해놓은 것입니다.

mv README.md README
git rm README.md
git add READM