반응형

1. Git Workflow

  • working directory : 현재 작업중인 파일이 존재하는 공간
  • staging area : 어느정도 작업하다가 버전 히스토리에 저장 할 준비가 되어있는 파일들을 옮겨 놓는 공간
  • git directory : 버전의 히스토리를 가지고 있는 git repository

Git workflow

working directory에 작업 중이던 파일 a.py, b.py 의 수정이 완료되면 add 명령어를 통해 staging area로 보내게 되고 commit 명령어를 통해 git 버전 히스토리에 저장하게 됩니다. 이렇게 git directory에 저장된 버전은 local에만 보관되기때문에 저장 공간에 문제가 생기면 모든 히스토리를 잃어버리게 됩니다. 그래서 github 와 같은 서버에 push 명령어를 수행하여 내 git directory를 서버에 업로드 해둘 수 있습니다. 이후 서버에서 pull 명령어를 수행하여 local git directory로 다운로드 받을 수 있습니다. checkout 명령어를 통해 git directory에 저장 된 버전 중 원하는 버전으로 돌아갈 수 있습니다. 

commit된 버전에는 고유한 hash 코드 ID와 버전 message, author, date/time 등의 Snapshot된 정보를 가지고 있습니다. 

working directory는 두가지로 나눌 수 있습니다.

  • untracked : 아직 트레킹 하지 않은 파일 (새로 만들어진 파일이거나 기존에 존재하던 프로젝트를 초기화 했을 때)
  • tracked : Git이 이미 트레킹 하고 있는 파일 (Git이 이미 알고 있는 파일)

이렇게 트레킹 하고 있는 파일들을 이전 버전과 비교하여 unmodified와 modified로 나뉠 수 있는데 이 중에서 modified만 staging area로 옮길 수 있습니다.

## 3개의 파일을 생성
C:\git (master) > echo hello world > a.py
C:\git (master) > echo hello world > b.py
C:\git (master) > echo hello world > c.py

## 상태 확인
C:\git (master) > git status
On branch master

No commits yet

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

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

working directory에 변경사항이 발생하여 master branch 가 노란색으로 표기 된 것을 확인 할 수 있습니다. 또한 변경사항이 아직 commit 되지 않았다는 뜻이기도 합니다. 

untracked 된 파일 3개는 하단에도 설명이 나와있지만 git add 명령어를 통해 tracking 할 수 있습니다.

## 1개의 파일만 add 명령어로 추가하고 상태를 확인
C:\git (master) > git add a.py
C:\git (master) > git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.py

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

a.py 파일은 staging area 에 존재하고 b.py, c.py는 아직 working directory에 존재한다는 뜻입니다.

## 리스트로 나열하여 추가
C:\git (master) > git add b.py c.py

## 확장자로 모두 추가
C:\git (master) > git add *.py
C:\git (master) > git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.py
        new file:   b.py
        new file:   c.py

이후 다시 a.py 파일을 수정하게 되면 modified 상태로 변경이 됩니다.

C:\git (master) > echo yunwoong >> a.py
C:\git (master) > git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.py
        new file:   b.py
        new file:   c.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   a.py

더보기

sourcetree 를 이용하면 좀 더 시각적으로 각 파일의 상태를 확인 할 수 있습니다.

다시 add 명령어를 이용하여 a.py 파일을 추가합니다. rm --cached 명령어를 이용하면 staging area에서 working directory로 다시 이동하게 됩니다.

C:\git (master) > git add a.py
C:\git (master) > git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.py
        new file:   b.py
        new file:   c.py

## rm --cached 명령어를 이용하여 staging area에서 working directory로 이동
C:\git (master) > git rm --cached *.*
rm 'a.py'
rm 'b.py'
rm 'c.py'
C:\git (master) > git status
On branch master

No commits yet

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

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

2. gitignore

작업을 하다보면 부수적으로 생성되는 파일이 있습니다. (log 등) 그리고 해당 파일이 Git에 포함되기를 원지 않을 수 있는데 이런 경우에는 .gitignore 파일을 이용 할 수 있습니다. .gitignore 파일에 추가해 놓는다면 더이상 해당 파일은 Git에 포함되지 않습니다.

C:\git (master) > echo log >> log.log
C:\git (master) > git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.py
        new file:   b.py
        new file:   c.py

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        log.log
        
## *.log 파일은 더이상 git에 포함되지 않도록 추가
C:\git (master) > echo *.log > .gitignore
C:\git (master) > git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   a.py
        new file:   b.py
        new file:   c.py

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

.gitignore 파일을 editor 열어서 다양한 방식으로 제외하도록 편집 할 수 있습니다.

3. Git Status

C:\git (master) > git status -h
usage: git status [<options>] [--] <pathspec>...

    -v, --verbose         be verbose
    -s, --short           show status concisely
    -b, --branch          show branch information
    --show-stash          show stash information
    --ahead-behind        compute full ahead/behind values
    --porcelain[=<version>]
                          machine-readable output
    --long                show status in long format (default)
    ...
    ...

git status 명령어는 option을 입력하지 않으면 기본적으로  --long option으로 수행됩니다. --short 옵션으로 좀 더 간단히 볼 수 있습니다.

C:\git (master) > git status -s
A  a.py
A  b.py
A  c.py
?? .gitignore

만일 staging area 에 있는 파일이 추가적으로 수정이 발생 했다면 AM 상태를 확인 할 수 있습니다. 간편하고 빠르게 상태를 확인 할 수 있죠.

C:\git (master) > echo modify >> a.py
C:\git (master) > git status -s
AM a.py
A  b.py
A  c.py
?? .gitignore

git status 를 통해 어떤 파일이 수정 되었는지 확인 할 수 있지만 정확히 어떤 내용이 수정이 되었는지는 확인 할 수 없습니다. 정확하게 수정된 내용을 확인하고 싶을 때는 diff 명령어를 사용 할 수 있습니다. diff 뒤에 option이 없는 경우에는 working directory에 있는 내용만 볼 수 있습니다.

C:\git (master) > git diff
diff --git a/a.py b/a.py
index de474ea..7b36095 100644
--- a/a.py
+++ b/a.py
@@ -1,2 +1,3 @@
 hello world
 yunwoong
+modify

staging에 있는 파일을 비교하려면 diff 뒤에 --staged 라는 option을 추가하시면 됩니다. 

C:\git (master) > git diff staged
diff --git a/a.py b/a.py
new file mode 100644
index 0000000..de474ea
--- /dev/null
+++ b/a.py
@@ -0,0 +1,2 @@
+hello world
+yunwoong
diff --git a/b.py b/b.py
new file mode 100644
index 0000000..4a1f475
--- /dev/null
+++ b/b.py
@@ -0,0 +1 @@
+hello world
diff --git a/c.py b/c.py
new file mode 100644
index 0000000..4a1f475
--- /dev/null
+++ b/c.py
@@ -0,0 +1 @@
+hello world

수정된 내용이 많아지게 되면 커맨드라인으로 내용을 확인하기가 어렵습니다. difftool 설정을 하여 좀 더 편리하게 수정된 내용을 확인 할 수 있습니다. 저는 p4merge tool 을 이용했습니다.

C:\git (master) > git config --global diff.tool p4merge
C:\git (master) > git config --global difftool.p4merge.path "C:\Program Files\Perforce\p4merge.exe"
C:\git (master) > git config --global difftool.prompt false
C:\git (master) > git config --global merge.tool p4merge
C:\git (master) > git config --global mergetool.p4merge.path "C:/Program Files/Perforce/p4merge.exe"
C:\git (master) > git config --global mergetool.prompt false
## difftool 수행
C:\git (master) > git difftool
## difftool (staging area) 수행
C:\git (master) > git difftool --staged

3. Git commit

staging area 있는 변경 사항을 git repository에 옮기기 위해 commit 이라는 명령어를 사용합니다.

C:\git (master) > git commit

단순히 option 없이 commit을 수행하면 text edit 창이 활성화되고 Template을 보여줍니다. 

타이틀과 상세내용을 작성하고 저장 후 text editor를 닫으면 commit 이 진행되고 간단히 타이틀과 3개의 파일이 생성되었다는 내용을 확인 할 수 있습니다.

히스토리를 확인하기 위해서 git log 명령어를 수행하시면 commit 당시 작성했던 내용과 어느 시점에 누가 작성했는지 확인 할 수 있습니다.

C:\git (master) > git log
commit a9cd7b702ed847d26f48df166b5422bbb414f26c (HEAD -> master)
Author: Yunwoong <이메일@gmail.com>
Date:   Thu Jun 17 18:40:54 2021 +0900

    Title

    Description....
    상세설명내용을 이곳에 작성합니다..

message option 을 사용하여 간단히 commit 할 수 있습니다.

## 파일을 수정
C:\git (master) > echo more >> a.py
C:\git (master) > git status -s
M a.py
?? .gitignore

## staging area
C:\git (master) > git add .
C:\git (master) > git status -s
A  .gitignore
M  a.py

## message를 포함하여 commit
C:\git (master) > git commit -m "second commit"
[master cec27fb] second commit
 2 files changed, 3 insertions(+)
 create mode 100644 .gitignore

staging area를 거치지 않고 working directory에 있는 내용을 바로 commit 할 수 있습니다.

## 파일을 수정
C:\git (master) > echo moremore >> a.py

## staging을 거치지 않고 message를 포함하여 commit
C:\git (master) > git commit -a -m "third commit"
[master fe1c9b1] third commit
 1 file changed, 1 insertion(+)
 
## staging을 거치지 않고 message를 포함하여 commit (option을 모아서 사용가능)
C:\git (master) > git commit -am "third commit"
[master fe1c9b1] third commit
 1 file changed, 1 insertion(+)

git directory에는 어떠한 규모로 commit 을 해야 적당할까요? commit 은 히스토리의 창고입니다. 그렇기 때문에 전체적인 프로그램을 하나의 commit으로 저장하게 되면 히스토리의 의미가 없습니다. 히스토리의 의미가 있게 commit을 하려면 기능별 작은 단위로 나누어 저장하는 것이 좋습니다. 그리고 commit 시 의미 없는 이름으로 commit1, commit2...등으로 저장하기보다는 의미 있는 메시지로 저장하는 것이 좋습니다. (ex) init -> add main page -> add sub page) 의미있는 이름이어야 해당 버전으로 돌리거나 취소하기가 편합니다. 그리고 만약 commit 시 작성한 내용에 해당하는 파일만 고쳐야지 하는 김에 버그를 고쳐서 같이 commit 하거나 새로운 기능을 넣어 commit 한다면 코드 리뷰 시에도 혼동이 오고 히스토리를 바라 볼 때도 혼동이 오게 됩니다. 그렇기 때문에 commit 메시지에 맞게 해당하는 프로그램만 포함하여 commit 하는 것이 중요합니다.  commit은 너무 큰 단위로 해도 문제가 되지만 너무 작은 단위로 하게 되어도 문제가 됩니다. 의미 있는 단위로 나누는 연습은 지속적으로 개발과 git을 활용하면서 감을 쌓아가야 합니다. 

더보기

souretree를 이용하면 간단히 클릭만으로 staging에 올릴 수 있고 특정 줄만 staging area 올린다거나 수정 내용을 버릴 수도 있습니다. 물론 Terminal에서도 가능하지만 직관적이지 않기때문에 GUI 프로그램을 이용한다면 좀 더 세분화하여 작업을 진행 할 수 있습니다.

또한 간단히 히스토리도 확인 할 수 있습니다.

 

반응형