Git scm

git에 대해 설명되있는 문서들은 온라인에 많이들 나와 있지만,

뭔가 초보자들이 그대로 따라하기엔 부족한 면이 있는것 같아,

요즈음 잉여력 폭발인 시기라 ㅋㅋ, 한번 만들어봤습니다.

우선 Git 이 다른 SCM 과 다른 점은 working directory, staging area 그리고 repository가 있다는 점입니다.

working directory 는 git에 등록되지 않은 작업공간, staging area 는 변경이력이 추적되기위해 준비되는 예비공간(응?), repository는 본격적으로 버전관리가 되는 공간입니다.

자, 그냥 한번 속는셈 치고 따라해 보세요. ㅎㅎ

먼저 Local Repository 사용법 부터 시작해봅니다.

 

Playing with Git Local Repository

 

Init

먼저 git을 사용할 디렉토리를 만듭니다.

$mkdir gittest

해당 디렉토리로 이동합니다.

$cd gittest

git을 초기화합니다.

이는 해당 디렉토리내에 .git 이라는 이름의 폴더를 생성하게 되고,

.git 폴더는 이 디렉토리(gittest)를 git version control 시스템에 local repository로 등록시켜주는 역할을 합니다.

$git init

그럼 아래와 같은 메시지가 나오는 것을 볼 수 있습니다.

Initialized empty Git repository in c:/temp/gittest/.git/

제가 생성한 c:/temp/gittest라는 디렉토리 밑에 .git이라는 디렉토리를 만들었고 그 안에 비어있는 Git Repository를 만들었다는 내용입니다.

Add

자 이제, 뭔가 만들어서 등록해보죠.

문자열을 standard output 인 화면에 뿌려주는 커맨드인 echo를 이용해 “hello Git”이라는 문자열을 뿌려주고

동시에 유닉스 파이프 명령어인 > (rediect) 을 사용하여 결과를 곧바로 READ라는 파일로 넘겨줍니다.

$echo "hello Git" > README

git status를 입력하면 현재 staging area에 추가 또는 변경된 파일, 그리고 working directory에만 존재하는 git 에 의해 추적되지 않는 (untracked) 파일 들을 볼 수 있습니다.

$git status

결과는 아래와 같이 나타나게 됩니다.

# On branch master
#
# Initial commit
#
# 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)

위 결과에 대한 의미입니다.

# On branch master // 디폴트로 여러분의 브랜치 이름은 master라는 이름을 갖게 됩니다.
# Untracked files: //Untracked files 밑에 나오는 파일들은 아직 git에 등록되지 않은 파일을 나타냅니다.
# (use "git add <file>..." to include in what will be committed) //친절하게도, git add <file> 을 이용하여 git repository에 추가할 수 있다고 알려줍니다.

git add <파일명> 을 이용하면 파일을 git repository에 등록할 수 있습니다.

다만, 이때 이 파일이 등록되는 위치는 git repository 의 바로 전 단계인 staging area 입니다.

staging area에 있는 파일들은 정식으로 repository에 등록되기 바로 전의 상태입니다.

이런 파일들을 git 에서는 따로 tracked file 이라고 부른다는 것도 알고 계세요.

Git은 commit 하기 전에 반드시 staging area를 거치도록 설계되어있습니다.

이것이 subversion이나 CVS 같은 다른 SCM (source control management system) 과의 차이점입니다.

따라서, 새로 만든 파일은 반드시 git add를 통해 staging area에 등록하고, 그 이후에 commit을 통해 repository에 등록해야 합니다.

$git add README

git의 상태가 어떻게 변했는지 다시 한번 확인해봅니다.

John@JOHN-HPLAPTOP /c/temp/gittest (master)
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed: //메시지가 아까 untracked ... 에서 바뀐것을 알 수 있습니다.
# (use "git rm --cached <file>..." to unstage)
#
# new file: README
#

Changes to be committed: 라인을 보면 방금 전의 untracked … 에서 이것으로 바뀐것을 알 수 있습니다.

Commit

이제 staging area 에 등록된 파일들을 repository에 등록시킵시다.

이 명령을 입력하면 또다른 팝업창이 뜨면서 commit comment를 입력하라고 할겁니다.

적당한 커맨트를 입력해줍니다. (저는 my README added for testing 라고 입력했습니다.)

<pre>$ git commit
[master (root-commit) d93f882] my README added for testing
1 file changed, 1 insertion(+)
create mode 100644 README

파일 하나가 변경되었고, 추가된 파일은 하나가 있다는 의미입니다.

git log는 여태까지 git repository에 발생된 로그 목록을 보여줍니다.

$ git log
commit fbad8bbbd504948fbbdbe00cb39f780b295d666f
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 21:47:19 2012 +1000

my README added for testing

README 파일을 vi 로 열어서 내용을 약간 고쳐봅시다.

$vi README

저는 “git is awesome and cool version control system” 라고 입력하겠습니다.

변경내용을 저장하고 vi를 빠져나옵시다.

다시 한번 git의 상태를 확인해봅니다.

$ git status
# On branch master
# 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
#
no changes added to commit (use "git add" and/or "git commit -a")

README 라는 파일이 수정되었는데 (“modified: README”), 이 변화는 아직 커밋하기 전 단계인 staging area에 반영되지 않았다 (“Changes not staged for commit:”)는 내용의 메시지 입니다.

잠깐만요. 아까 분명히 git add를 통해 이미 staging area에 등록했는데 왜 또 git add를 하라고 할까요.

이것도 역시 git의 특성입니다. 새로 만든 파일도 commit을 위해서는 git add를 통해 staging area에 등록(traced)해야하지만,

이미 tracked 된 파일이라 할지라도 그 이후 파일내용에 어떤 변화가 발생되었다면, git add를 통해 해당 수정내용을 staging area에 업데이트 해줘야 합니다.

git add에 u (update) 옵션을 이용하면, 변화(추가 또는 변경)가 생긴 모든 파일을 staging area에 등록할 수 있습니다.

$git add -u

다시한번 상태를 확인해봅시다.

$ git status
warning: LF will be replaced by CRLF in README.
The file will have its original line endings in your working directory.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: README
#

이제 파일의 변화가 staging area에 들어와있으므로, 메시지가 바뀌었습니다. commit의 대상이 될 수 있는, 변화된 파일이 README 라는 의미입니다.
staging area 에서 unstaging area 즉, working copy로 되돌리려면 git reset HEAD <파일명> 을 이용하라는 친절한 메시지도 함께 보여줍니다.
그런데, 위 메시지를 보면 “warning: LF will be replaced by CRLF in README.” 라는 부분이 눈에 거슬리네요. 이 메시지는 유닉스나 리눅스에서는 생기지 않지만, 윈도우에서만 나타나는 경고 메시지입니다.

유닉스나 리눅스는 개행문자에 LF (Line Feed) 만 사용하는 반면, 윈도우는 CRLF(Carriage Return Line Feed)를 사용합니다.

제가 아까 README 파일을 수정할때 사용한 vi 는 리눅스 기반 유틸을 윈도우로 포팅한 것이라, 어떤 내용을 입력하고 엔터를 치면 새로운 라인으로 이동하기 위해 CRLF 가 아닌 LF를 입력하게 됩니다.

윈도우용 Git 의 설정옵션 중에는 LF를 자동으로 CRLF 로 변경해주도록 되어있습니다.

이 설정 때문에 위와 같은 메시지가 나타난 것입니다.

이 셋팅을 바꾸면 이와 같은 자동변환도 방지하고, 눈에 거슬리는 경고메시지도 나타나지 않게 할 수 있습니다.

아래 커맨드를 입력하면 됩니다.

$ git config core.autocrlf false

git commit 시에 -m 옵션을 주면, 다른 팝업을 띄우지 않고도, 편리하게 바로 커밋 명령어와 함께 커밋 메시지지를 입력할 수도 있습니다.

$git commit -m "README updated"

git의 상태를 확인해봅니다.

$ git status
# On branch master
nothing to commit (working directory clean)

커밋할 것이 없는, working directory가 깨끗한 상태인 것을 확인할 수 있습니다.

이번에는 git의 로그를 확인해봅니다.

$ git log
commit c7e70572be3b206b28571d393c667ecbddf20331
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:03:18 2012 +1000

README updated

commit fbad8bbbd504948fbbdbe00cb39f780b295d666f
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 21:47:19 2012 +1000

my README added for testing

git 에는 HEAD 라는 개념이 있는데, 이는 마지막으로 커밋한 내용을 가르키는 것입니다.

HEAD~1 이라고 하면 마지막 커밋보다 하나 이전에 커밋한 내용. HEAD~2는 마지막 커밋보다 이전, 이전에 커밋한 내용입니다.

방금 커밋한 내용과 그 바로 전에 커밋한 내용의 차이를 보기 위해서는 git diff 커맨드 뒤에 비교하고자 하는 대상을 .. 으로 구분해서 써주면 됩니다.

이때, 주의할 것은 HEAD~1이 앞에 나오고 HEAD가 뒤에 나와야 합니다.

오래된 버전에서 (From) 최신 버전의 순서대로(To) 써준다고 생각하면 이해하기 쉽습니다.

“HEAD~1 에서(..) HEAD 까지” 이렇게 생각하면 쉽죠?

이 순서를 바꾸면 결과도 달라집니다.

$ git diff HEAD~1..HEAD
diff --git a/README b/README
index 8d0e412..39162d9 100644
--- a/README
+++ b/README
@@ -1 +1,4 @@
hello git
+
+git is awesome and cool version control system
+

참고로 git diff HEAD 라고 입력하면 현재 working directory 또는 staging area에 있는 버전과 repository에 있는 버전 간의 차이점을 보여줍니다.

즉, 마지막으로 커밋된 버전과 내가 로컬에서 변경하고 있거나 (working directory) 또는 변경을 끝내고 커밋하기 직전(staging area)에 있는 버전간의 차이점을 보여주는 커맨드입니다.

+ 표시 뒤에 나오는 부분은 기존 파일에 추가된 내용을 의미하고, – 표시는 삭제된 내용을 표시할때 사용됩니다.

이번에는 vi를 이용해 다음과 같이 파일 2개를 만들어 봅시다.

$vi a.txt
$vi b.txt

git의 상태를 확인해 봅니다.

$ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a.txt
# b.txt
nothing added to commit but untracked files present (use "git add" to track)

 

$git add -A

git add에 -A 옵션을 주면 변경된 모든 (ALL) 파일을 staging area 로 올리라는 의미입니다. -A와 –all 의 별명(alias)이고, 또한 -A는 “git add .” 커맨드와 “git add -u” 커맨드를 연달아 입력한 것과 동일한 효과를 냅니다.

“git add .” 는 현재 directory (.) 와 그 서브 디렉토리를 대상으로 새롭게 추가되었거나 변화된 파일들을 모두 staging area에 등록하라는 의미입니다. 여기서 새롭게 추가된 파일이란 아직 staging area에 등록되지 않은채 working directory에만 존재하는 파일들을 의미합니다. 그리고 변화된 파일이란, staging area에 등록된 파일중에 업데이트된 파일 또는 working directory 에 있던 파일 가운데 업데이트된 파일을 의미합니다.

이 커맨드는 현재 디렉토리와 그 아래 서브 디렉토리까지 순차적으로 검색하며 staging area로 등록하기 때문에, 대상 파일들이 많은 경우에 유용합니다.

한편 “git add -u”는 현재 staging area에 등록된 파일들에 한해서, 변화가 있는 경우, 그 변화를 staging area에 등록하라는 의미입니다. git add . 와 다른점은 working directory에 있는 파일들은 다루지 않는 다는 것입니다.

잠깐 옆길로 새서, 위에 git add -A 와 git add –all이 동일한 거라고 설명했는데, 어떨때 대쉬(-) 가 하나 오고, 어떨때 두개 (–)가 오는지 처음하는 분은 헷갈릴 수 있습니다.

보통 git 의 옵션은 더블 대쉬(–)를 사용하는 것이 맞습니다. 싱글 대쉬(-) 가 오는 경우는 줄여서 사용할때 쓴다고 이해하면 쉽습니다. git add -u 도 사실 git add –update 와 같은 의미입니다.
이제 다시 git의 상태를 확인해 봅시다.

$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: a.txt
# new file: b.txt
#

두 개의 파일이 커밋을 기다리고 있다고 말하고 있습니다. 커밋을 해봅시다.

$ git commit -m "added new cool features"
[master f95ccac] added new cool features
2 files changed, 3 insertions(+)
create mode 100644 a.txt
create mode 100644 b.txt

그리고 확인합니다.

$ git status
# On branch master
nothing to commit (working directory clean)

로그를 확인해봅니다.

$ git log
commit f95ccacb187384d9626671fdd2e02b64b1f7e8fd
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:23:47 2012 +1000

added new cool features

commit c7e70572be3b206b28571d393c667ecbddf20331
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:03:18 2012 +1000

README updated

commit fbad8bbbd504948fbbdbe00cb39f780b295d666f
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 21:47:19 2012 +1000

my README added for testing

Diff

이번엔 diff 에 대해 알아보겠습니다.

인자없이 git diff라고 입력하면 현재 working directory 에서 발생한 변화와 repository에 마지막으로 커밋된 내용간의 차이를 보여줍니다.

만약 뭔가 인자를 준다면 그 인자 값과 마지막으로 커밋된 내용간의 차이점을 보여주는 것이고요.

$git diff HEAD~1

이 커맨드는 HEAD~1, 즉 마지막으로 커밋된 버전과 바로 그 직전에 커밋된 버전간의 차이점을 보여줍니다. 눈치채셨듯이 비교대상이 되는 마지막 커밋된 내용, 즉 HEAD는 묵시적으로 생략되어 있습니다.

 $ git diff HEAD~1
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..b5eca57
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+a.txt^M
diff --git a/b.txt b/b.txt
new file mode 100644
index 0000000..f4c2c85
--- /dev/null
+++ b/b.txt
@@ -0,0 +1,2 @@
+b.txt^M
+^M

만약 마지막 커밋보다 두번 앞에 커밋된 내용과 차이를 확인하고 싶은 경우엔 HEAD~2를 대신 입력하면 됩니다.

 $ git diff HEAD~2
diff --git a/README b/README
index 8d0e412..39162d9 100644
--- a/README
+++ b/README
@@ -1 +1,4 @@
hello git
+
+git is awesome and cool version control system
+
diff --git a/a.txt b/a.txt
new file mode 100644
index 0000000..b5eca57
--- /dev/null
+++ b/a.txt
@@ -0,0 +1 @@
+a.txt^M
diff --git a/b.txt b/b.txt
new file mode 100644
index 0000000..f4c2c85
--- /dev/null
+++ b/b.txt
@@ -0,0 +1,2 @@
+b.txt^M
+^M

a.txt 파일을 vi로 열어서 뭔가 내용을 추가해봅시다.

 $vi a.txt

README 파일도 뭔가 내용을 추가해봅시다.

 $vi README

a.txt만 staging area에 추가해봅시다.

$git add a.txt

git의 상태를 확인해보면, 앞에서 변경한 두 개의 파일이 커밋대상이라고 알려줍니다.

 $ git status
# On branch master
# 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
# modified: a.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

git의 상태를 보면 a.txt만 staging area에 올라가 있고, README는 여전히 staging 되지 않은채 working directory에 존재한다고 알려줍니다.

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: a.txt
#
# 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
#

커밋을 해봅시다.

 $ git commit -m "a.txt has been updated"
[master a04e811] a.txt has been updated
1 file changed, 2 insertions(+)

이때 a.txt 에 대해서만 앞에서 add 를 했기 때문에, a.txt 만 commit 이 되고, README 는 add를 해주지 않았기 때문에 commit이 먹지 않습니다.
1 file changed, 2 insertions(+) 라는 메시지는 repository에는 1개의 파일만 반영(커밋)이 되었고, 이 커밋에는 2 라인의 변경(+ 이므로 추가, -의 경우엔 삭제)이 발생했다는 의미입니다.
README 파일도 commit을 위해 변경내역을 staging area에 올립시다.

 $git add README

커밋을 해줍니다.

 $ git commit -m "more README comment added"
[master 9844fe4] more README comment added
1 file changed, 3 insertions(+)

이제 확인해보면 working directory가 깨끗해졌습니다.

 $ git status
# On branch master
nothing to commit (working directory clean)

Delete

이번엔 삭제에 대해 알아봅시다.

먼저 디렉토리에 어떤 파일이 있나 보죠.

 $ ls
README a.txt b.txt

b.txt를 삭제해봅시다.

 $rm b.txt

삭제가 잘됬나보죠. 잘 되었군요.

 $ ls
README a.txt

이제 git의 상태를 확인해봅시다.

 $ git status
# On branch 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: b.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

b.txt 가 삭제되었지만, 아직 commit되지는 않았다고 알려줍니다.
앞에서 파일을 새로 만들었던 것과 마찬가지로, 삭제할때도 add를 사용해야 삭제 동작이 staging area 에 등록됩니다.

 $git add -u

다시 git을 확인해봅니다.

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
#

이제 커밋을 할 수 있도록, staging area에 등록된 것을 알 수 있습니다.

c.txt 라는 파일을 새로 만들어봅시다.

 $ vi c.txt

스테이징 에어리어에 등록하고요.

 $ git add c.txt

git 상태를 확인.

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
# new file: c.txt
#

이제 a.txt 라는 파일의 이름을 newfile.txt로 변경해 봅시다.

 $mv a.txt newfile.txt

git 상태 확인.

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
# new file: c.txt
#
# 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: a.txt
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# newfile.txt

뭔가 재밌는 일이 벌어졌습니다. 조금 복잡한게 흠이네요. ㅎㅎ

하나하나 보죠.

원래 staging area에 올려둔 내용은 그대로 있고요.

 # Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
# new file: c.txt

a.txt라는 파일은 원래 git repository에 등록되있던 파일인데, 우리가 방금 이름을 newfile.txt로 바꾸었지않습니까? git은 일단 a.txt가 삭제되었다고 생각합니다.

 # 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: a.txt

그리고 newfile.txt 라는 듣보잡 파일이 working directory에 새롭게 생성되었다고 생각합니다.

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

뭔가 복잡해졌습니다. 암튼 해야할 일을 분명하죠. 일단 staging area에 뭐가 됬든간에 다 올려줘야 하지 않겠습니까? 이때 아까 배운 git add -A 옵션을 써먹을 수 있습니다.

 $git add -A

git 상태를 확인해보면

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
# new file: c.txt
# renamed: a.txt -> newfile.txt
#

오옷. 이제 git도 a.txt에서 newfile.txt로 rename 되었다는걸 알아차렸네요.

변경내용을 한꺼번에, 깡그리 커밋해 버립시다.

 $ git commit -m "reorganized"
[master 176ecf9] reorganized
3 files changed, 2 insertions(+), 2 deletions(-)
delete mode 100644 b.txt
create mode 100644 c.txt
rename a.txt => newfile.txt (100%)

Checkout & Reset

이번에 변경내용을 복구하는 방법을 알아봅시다.

우선 화면이 지저분하니, 깔끔하게 만듭시다. 유닉스의 clear 커맨드를 날리면 됩니다.

 $clear

우선 재료를 만들어야 되니, README 파일을 변경합시다.

 $vi README

내용은 아무거나 막 넣습니다.

git을 확인해보고요.

 $ git status
# On branch master
# 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
#
no changes added to commit (use "git add" and/or "git commit -a")

웁쓰. 근데, 해놓고보니 잘못 고친것 같습니다. README 파일을 원래대로 돌려놔야 겠습니다. git에서는 이게 아주 간단합니다. checkout 커맨드를 날려주면 됩니다.

 $git checkout README

git 상태를 확인해보면 다시 원래상태로 돌아온 것을 알 수 있습니다.

 $ git status
# On branch master
nothing to commit (working directory clean)

현재 디렉토리에 있는 파일을 확인해봅니다.

 $ ls
README c.txt newfile.txt

다시 README 파일을 고쳐봅니다.

 $vi README

c.txt 파일도 삭제해봅시다.

 $rm c.txt

newfile.txt 도 삭제해봅시다.

 $rm newfile.txt

git 상태를 확인해봅니다.

 $ git status
# On branch 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)
#
# modified: README
# deleted: c.txt
# deleted: newfile.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

ls로 확인해봐도 분명 파일이 없어졌네요.

 $ ls
README

하지만, git reset 명령에 –hard 옵션을 주면 다시 되돌릴 수 있습니다.

 $ git reset --hard
HEAD is now at 176ecf9 reorganized

오옷..진짜로 파일이 복원되었습니다.

 $ ls
README c.txt newfile.txt

git 상태를 확인해보면 원래대로 되돌아온것을 알 수 있습니다.

 $ git status
# On branch master
nothing to commit (working directory clean)

심지어 마지막 커밋 두단계 전으로 복원하는 것도 가능합니다.

 $ git reset --soft HEAD~1

git 상태를 확인해봅니다.

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
# new file: c.txt
# renamed: a.txt -> newfile.txt
#

아까 아까 전에 봤던 git 상태로 변경되었습니다.

Log

git log 커맨드로 로그를 확인할 수 있습니다.

$ git log
commit 9844fe48bec34edaf8fb1796590f0766b30a4df7
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:11:06 2012 +1000

more README comment added

commit a04e811a638594a23e2fccdef8d8a01822621be3
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:09:47 2012 +1000

a.txt has been updated

commit f95ccacb187384d9626671fdd2e02b64b1f7e8fd
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:23:47 2012 +1000

added new cool features

commit c7e70572be3b206b28571d393c667ecbddf20331
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:03:18 2012 +1000

README updated

commit fbad8bbbd504948fbbdbe00cb39f780b295d666f
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 21:47:19 2012 +1000

my README added for testing

다시한번 git의 상태를 확인해보고요.

 $ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# deleted: b.txt
# new file: c.txt
# renamed: a.txt -> newfile.txt
#

이제 모든 변화를 커밋합니다.

 $ git commit -m "reorganizing"
[master 67a03f5] reorganizing
3 files changed, 2 insertions(+), 2 deletions(-)
delete mode 100644 b.txt
create mode 100644 c.txt
rename a.txt => newfile.txt (100%)

워킹 디렉토리가 깨끗한지 확인해봅니다.

 $ git status
# On branch master
nothing to commit (working directory clean)

git log 커맨드로 커밋이 잘되었는지 확인해봅니다.

$ git log
commit 67a03f5b1cebecc75e96843648b7cc63462d19fe
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:31:19 2012 +1000

reorganizing

commit 9844fe48bec34edaf8fb1796590f0766b30a4df7
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:11:06 2012 +1000

more README comment added

commit a04e811a638594a23e2fccdef8d8a01822621be3
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:09:47 2012 +1000

a.txt has been updated

commit f95ccacb187384d9626671fdd2e02b64b1f7e8fd
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:23:47 2012 +1000

added new cool features

commit c7e70572be3b206b28571d393c667ecbddf20331
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:03:18 2012 +1000

README updated

commit fbad8bbbd504948fbbdbe00cb39f780b295d666f
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 21:47:19 2012 +1000

my README added for testing

파일도 잘있는지 다시 한번 확인해봅니다.

 $ ls
README c.txt newfile.txt

파일을 삭제하기 이전 단계로 되돌려봅니다. 이번엔 reset 시 hard 옵션을 줍니다.

 $ git reset --hard HEAD~1
HEAD is now at 9844fe4 more README comment added

파일을 확인해보면 이전으로 되돌아간 것을 알 수 있습니다.

 $ ls
README a.txt b.txt

git status를 해보면 working directory가 깨끗한 것을 알 수 있습니다. 이것이 바로 soft reset 과 hard reset 의 차이점입니다.
soft reset 은 staging area 에 기록이 남지만, hard reset 은 staging area에 기록을 남기지 않습니다.

 $ git status
# On branch master
nothing to commit (working directory clean)

Clean

이번에는 git 에 등록되지 않은, 워킹 디렉토리안에서만 작업했던 파일 (untracked file)을 staging area에 올리지 않고, 그냥 삭제하는 방법을 알아봅니다.
테스트를 위해 1.txt 와 2.txt 라는 내용없는 빈 파일을 만듭니다.

 $touch 1.txt 2.txt

확인해보니 잘 만들어져 있군요.

 $ ls
1.txt 2.txt README a.txt b.txt

working directory의 상태를 확인해봅니다.

 $ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# 1.txt
# 2.txt
nothing added to commit but untracked files present (use "git add" to track)

먼저 지울 수 있는 파일이 어떤게 있나 확인을 위해 git clean 에 -n 옵션 (–dry-run)을 줍니다.

 $ git clean -n
Would remove 1.txt
Would remove 2.txt

강제로 untracked file들을 지우려면 -f 옵션 (–force) 을 주면 됩니다.

 $ git clean -f
Removing 1.txt
Removing 2.txt

확인해보면 지워져 있습니다.

 $ ls
README a.txt b.txt

워킹 디렉토리도 깨끗합니다.

 $ git status
# On branch master
nothing to commit (working directory clean)

.gitignore

마지막으로, 특정 파일들에 대해 git에 등록하지 않는 법에 대해 알아봅니다.

대표적으로 코딩시 에디터들이 자동으로 만들어내는 log 파일들은 git repository에 등록할 필요가 없을 겁니다.

먼저 logs 라는 디렉토리리를 만들고

 $ mkdir logs

만든 디렉토리 안에 log1.txt 라는 빈 파일을 하나 만듭니다.

 $ touch logs/log1.txt

working directory를 살펴보면, logs 폴더 안에 log1.txt 라는 파일이 추가되었기 때문에 logs 디렉토리가 untracked 되었다고 나옵니다.

만약 log1.txt를 추가하지 않았다면 아무 변화가 없다고 나오게 됩니다.

 $ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# logs/
nothing added to commit but untracked files present (use "git add" to track)

로그파일은 버전관리를 할 필요가 없습니다. 이를 위해 이런 정보를 .gitignore 라고 하는 특수한 파일에 알려줘야 합니다.

vi를 통해 .gitignore 파일을 편집합시다.

 $ vi .gitignore

아래와 같은 내용을 넣어줍니다.

 /logs/*.txt
/logs/*.log
/logs

각 라인의 의미는 아래와 같습니다.

/logs/*.txt ==> logs 디렉토리 밑에 있는 모든 txt 확장자 파일은 무시한다.

/logs/*.log ==> logs 디렉토리 밑에 있는 모든 log 확장자 파일은 무시한다.

/logs ==> logs 디렉토리 밑에 있는 모든 파일은 무시한다.

이제 git status를 해보면, 앞에서 작업했던 내용들이 이미 반영되어 add 할 수 있는 파일은 달랑 .gitignore 파일만을 보여줍니다.

 $ git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# .gitignore
nothing added to commit but untracked files present (use "git add" to track)

.gitignore 파일을 staging area 로 올립니다.

 $ git add .gitignore

파일명을 타이핑하는게 귀찮다면 앞에서 배운 현재 디렉토리 내의 모든 변화를 add 하는 커맨드를 써먹어도 됩니다.

아래처럼요.

 $ git add .

커밋을 합니다.

$ git commit -m "Added .gitignore"
[master 5f1b59f] Added .gitignore
1 file changed, 4 insertions(+)
create mode 100644 .gitignore

로그를 확인해봅니다.

$ git log
commit 5f1b59f6407a913756872fc69a7e3ccfe6ac82a8
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:43:10 2012 +1000

Added .gitignore

commit 9844fe48bec34edaf8fb1796590f0766b30a4df7
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:11:06 2012 +1000

more README comment added

commit a04e811a638594a23e2fccdef8d8a01822621be3
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 23:09:47 2012 +1000

a.txt has been updated

commit f95ccacb187384d9626671fdd2e02b64b1f7e8fd
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:23:47 2012 +1000

added new cool features

commit c7e70572be3b206b28571d393c667ecbddf20331
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 22:03:18 2012 +1000

README updated

commit fbad8bbbd504948fbbdbe00cb39f780b295d666f
Author: to.johnny.lee <to.johnny.lee@gmail.com>
Date: Sun Jun 24 21:47:19 2012 +1000

my README added for testing

이상 local git repository 커맨드 사용법을 간단하게 정리해봤습니다.

즐깃하세요!!

 

Playing with Remote Local Repository

 

to be continued ……

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s