Git 개념 정리 (1) - Git vs SVN , Git file status

Git 이란?

형상관리(버전관리)를 하기 위한 tool로써 소스코드를 효과적으로 관리하기 위해 개발된 분산형 버전 관리 시스템이다.
형상관리를 하기 위한 또다른 대표적인 tool로 SVN (subversion)이 존재한다. SVN은 Git은 분산형 버전 관리 시스템임에 비해 중앙집중관리식이다. 즉 local PC에서 commit을 하면 바로 중앙저장소에 반영되는 반면에 Git은 각 개발자마다 로컬저장소가 있어, push 전에는 중앙저장소에 반영되지 않는다.

  • Git Repository : Git repository는 변경 이력별로 구분되어 소스코드가 저장되는데, 원격 저장소, 로컬 저장소로 나뉜다.

    • Remote Repository (원격 저장소) : 파일이 원격 저장소 서버에 저장되며 , 협업하는 개발자들과 공유 가능
    • Local Repository (로컬 저장소) : 말 그대로 로컬 PC에 파일이 저장되며 개인 저장소이다.

Git은 로컬저장소가 있음으로 성능상에 SVN에 비해 얻을 수 있는 장점도 있다.
프로젝트의 history를 조회하거나 어떤 파일의 현재 버전과 한달전 버전을 비교하고자 할떄 네트워크 요청없이 수행될 수도 있다.

Git 파일 상태

  • Git은 파일을 Committed , Modified , Staged 이렇게 3가지 상태로 관리한다.
  1. Committed : data 가 local repository에 안전하게 저장되었음 (git commit 이후 상태 )
  2. Modified : data 가 수정되었으나 local repository 에 저장되지 않았음
  3. Staged : 현재 수정한 file을 곧 commit 할것이라고 표시한 상태 (git add 이후 상태)

Commit

  • 파일(소스코드)의 변경사항이 있을떄 저장소에 반영하고자 하면 Git commit 명령어를 통해 수행될 수 있다.

각 commit 은 40자리의 id값을 부여받는데 , SHA-1 해시를 사용해서 checksum을 만든다. 저장소에는 이 id값을 보고 commit을 구분한다.

Git 사용자 정보 등록

Git 설치 이후 최초에는 사용자 정보 등록을 해야한다. 프로젝트마다 다르게 설정하고 싶으면 –global option을 주지 않는다.

1
2
$ git config --global user.name "devcs96"
$ git config --global user.email katd6@naver.com

Git 저장소 생성

  • Git 저장소는 2가지 방법 중 하나로 쓰기 시작할 수 있다.
  1. 아직 버전 관리하지 않은 로컬 directory에서 git init

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    cs@gimchansuui-iMac hello-git % git init .
    hint: Using 'master' as the name for the initial branch. This default branch name
    hint: is subject to change. To configure the initial branch name to use in all
    hint: of your new repositories, which will suppress this warning, call:
    hint:
    hint: git config --global init.defaultBranch <name>
    hint:
    hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
    hint: 'development'. The just-created branch can be renamed via this command:
    hint:
    hint: git branch -m <name>
    Initialized empty Git repository in /Users/cs/Desktop/hello-git/.git/

    git init 명령어로 로컬 저장소를 만들면 .git directory가 생성되고 현재 directory가 working directory가 된다.

    1
    drwxr-xr-x   9 cs  staff  288  1 14 14:34 .git
  2. 원격의 Git 저장소에서 git clone

주로 github에서 저장소를 생성하고 생성된 원격 저장소를 clone해서 생성할수도 있다. git clone 명령어를 수행하면 원격 서버에 있는 프로젝트 데이터를 모두 받아오고, .git directory를 만들며, 해당 directory가 working directory가 된다.

1
git clone https://github.com/devcs96/git.git 

working directory 내 파일 상태

git init . 또는 git clone <url> 이후에 해당 working directory에는 .git sub directory가 생긴다. working directory내 파일 상태는 크게 2가지로 나뉜다.

  • untracked : git 에 의해 관리되고 있지 않음
  • tracked : git 에 의해 관리되고 있음
1
2
3
4
5
6
7
8
9
cs@gimchansuui-iMac hello-git % touch hello.txt
cs@gimchansuui-iMac hello-git % git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt

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

working directory에 파일을 위와 같이 생성하면 untracked file status를 볼 수 있다. git log를 보면 track 상태로 바꾸려면 즉 git이 관리하게 만드려면 git add 명령어를 치라고 로그가 찍혀있다.

tracked 상태는 처음 “Git 파일 상태” 단락에 추가한 내용과 동일하다

git add 이후에는 staged 상태가 된다 (commit 이전 상태)

1
2
3
4
5
6
7
cs@gimchansuui-iMac hello-git % git status 
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: hello.txt

cs@gimchansuui-iMac hello-git %

git commit 명령어를 실행하게 되면 git add 를 실행한 시점(staged 상태)의 파일이 commit되어 저장소 history에 남게된다.

이 상태로 file을 수정하면 modified 상태로 변경된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
cs@gimchansuui-iMac hello-git % vim hello.txt // 파일 내용 수정 
cs@gimchansuui-iMac hello-git % git status .
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: hello.txt

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: hello.txt

cs@gimchansuui-iMac hello-git %

다시 변경 내역을 staged상태로 변경하려면 git add 명령어를 통해 staged상태로 변경할 수 있다.

.gitignore

working directory내에서 git이 관리할 필요가 없는 파일을 개발자가 직접명시해줄수 있다. 대표적으로 build , node_modules 등과 같은 바이트 코드와 library 코드들은 .gitignore를 통해 원격저장소에 올리지 않을 수 있다.

.gitignore에 입력할 패턴은 다음과 같은 규칙을 따르는데 reference에서 그대로 가져왔다

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

  1. 아무것도 없는 라인이나, #로 시작하는 라인은 무시한다.
  2. 표준 Glob 패턴을 사용한다. 이는 프로젝트 전체에 적용된다.
  3. 슬래시(/)로 시작하면 하위 디렉토리에 적용되지(Recursivity) 않는다.
  4. 디렉토리는 슬래시(/)를 끝에 사용하는 것으로 표현한다.
  5. 느낌표(!)로 시작하는 패턴의 파일은 무시하지 않는다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 확장자가 .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 diff

추가로 modified된 file 이 어떤 내용이 staged 상태와 다른지 확인하려면 git diff 명령어로 확인할 수 있다

1
2
3
4
5
6
7
8
9
cs@gimchansuui-iMac hello-git % git diff
diff --git a/hello.txt b/hello.txt
index d1c6469..7e7bc4b 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1 @@
-hello git!
+hello git!!!
cs@gimchansuui-iMac hello-git %

git commit

git commit 명령어로 git add 명령어를 통해 staged 상태로 만든 file들을 local 저장소에 저장할 수 있다.

git commit을 치면 commit message를 통해 어떤 변경사항이 생겼는지 기록을 남기는데 , 회사마다 convention이 있겠지만 대표적으로 AngularJS Git Commit Message Conventions 이 있다.
(Ref - https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit#heading=h.uyo6cb12dt6w)

commit 내역은 git log 명령어를 통해 확인할 수 있다.

참고로 commit 26735a693a2305950d2e2bdf722bbd70f854e4fd 이 부분은 git에서 각 commit을 구분하기 위한 checksum이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
cs@gimchansuui-iMac hello-git % git log
commit 26735a693a2305950d2e2bdf722bbd70f854e4fd (HEAD -> master)
Author: devcs96 <katd6@naver.com>
Date: Fri Jan 14 15:15:16 2022 +0900

initial commit

commit b4c460c8ffa32fab0bbcad9e056c6cc39fecc95c
Author: devcs96 <katd6@naver.com>
Date: Fri Jan 14 14:37:41 2022 +0900

initial version control
cs@gimchansuui-iMac hello-git %

git commit 되돌리기

완료한 commit을 수정해야할떄 , 파일을 수정하고나서 git add 명령어로 staging 상태로 만든 다음에 git commit –amend 옵션을 주어 commit을 재작성할 수 있다.

git commit –amend 명령어를 쳤는데 만약 수정된 내용이 없다면 commit message만 수정된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cs@gimchansuui-iMac hello-git % git commit --amend 
[master b4ed6d1] initial commit 이 내용 넣는 것을 깜빡했네요
Date: Fri Jan 14 15:15:16 2022 +0900
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
cs@gimchansuui-iMac hello-git % git log
commit b4ed6d19078cbbc1cb5b47085b6756c633bf7d10 (HEAD -> master)
Author: devcs96 <katd6@naver.com>
Date: Fri Jan 14 15:15:16 2022 +0900

initial commit
이 내용 넣는 것을 깜빡했네요

commit b4c460c8ffa32fab0bbcad9e056c6cc39fecc95c
Author: devcs96 <katd6@naver.com>
Date: Fri Jan 14 14:37:41 2022 +0900

initial version control

기존 커밋을 덮어씌우는 개념이다.

staged 상태를 unstaging 상태로 변경하기

1
2
3
4
5
6
7
cs@gimchansuui-iMac hello-git % git add *
cs@gimchansuui-iMac hello-git % git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: hello.txt
modified: index.txt

실수로 다음과 같이 git add * 을 호출해 원하지 않는 파일도 staged 상태로 변경하였다. 이를 unstaged 상태로 변경하려면 git reset HEAD <file명> 으로 unstaging상태로 변경할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
cs@gimchansuui-iMac hello-git % git reset HEAD hello.txt
Unstaged changes after reset:
M hello.txt
cs@gimchansuui-iMac hello-git % git status .
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: index.txt

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: hello.txt

modified 상태를 변경전 상태의 파일로 원상복구하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
cs@gimchansuui-iMac hello-git % head index.txt
index.txt
수정
cs@gimchansuui-iMac hello-git % git status .
On branch master
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: index.txt

no changes added to commit (use "git add" and/or "git commit -a")
cs@gimchansuui-iMac hello-git % git checkout -- index.txt
cs@gimchansuui-iMac hello-git % head index.txt
index.txt
cs@gimchansuui-iMac hello-git % git status .
On branch master
nothing to commit, working tree clean

index.txt 파일을 수정하고나서 modified된 상태를 변경 전 내용으로 원상복구하고 싶다면
git checkout – <file명> 을 통해 변경 전 내용으로 원상복구 할 수 있으나, branch 를 사용하는 방법을 권고한다.

Remote Repository 등록

git remote 명령어를 통해 현재 project에 등록된 원격 저장소를 확인할 수 있다. 참고로 git clone을 사용하면 clone한 repository가 자동으로 “origin”이라는 이름의 원격 저장소로 등록된다.

1
2
3
cs@gimchansuui-iMac git % git remote -v
origin https://github.com/devcs96/git.git (fetch)
origin https://github.com/devcs96/git.git (push)

git init을 통해 working directory를 생성하면 등록된 원격저장소가 없는 상태이다. 이때 다음과 같이 원격저장소를 등록해줄 수 있다.

git remote add <원격저장소 단축이름> <원격저장소url>

1
2
3
4
5
cs@gimchansuui-iMac hello-git % git remote -v
cs@gimchansuui-iMac hello-git % git remote add hello https://github.com/devcs96/git.git
cs@gimchansuui-iMac hello-git % git remote -v
hello https://github.com/devcs96/git.git (fetch)
hello https://github.com/devcs96/git.git (push)

Comments