반응형

1. Tracked / Untracked

Working Directory에 있는 각각의 파일들은 다음과 같이 두 분류로 구분됩니다.

  1. tracked
  • 마지막 스냅샷에 포함되어 있는 파일로, (unmodified, modified, staged) 중 하나의 상태를 갖습니다.
  • 쉽게 말해, Git이 인지하고 있는 파일입니다.
  1. untracked
  • 위에서 언급한 tracked file에 속하지 않는 모든 파일입니다.
  • 스냅샷에도, staging area에도 포함되지 않은 파일입니다.

 

어떤 저장소를 clone 하여 가져왔을 때, 모든 파일은 tracked 파일이면서 unmodified 상태입니다.

그림 1. The lifecycle of the status of your files.

 

2. Checking the Status of Your Files

파일들의 상태에 대해 확인하는데 사용되는 명령어는 git status 입니다.

만약 어떤 저장소를 clone 한 후에 git status 명령어를 입력하면 아래와 같은 결과를 볼 수 있습니다.

$ git status

On branch master

Your branch is up-to-date with 'origin/master'.

    nothing to commit, working directory clean

위 결과를 살펴보면 git status

  1. 현재 로컬 브랜치가 어느 지점에 있는지 알려주고,
  2. 서버에 있는 원격 저장소와 같은 지점에 있는지도 알려줍니다.
  3. 그리고 작업 디렉토리가 clean 하다는 것은 디렉토리 내에 어떤 tracked 파일도 modified 상태가 아니라는 걸 의미합니다.

이번에는 작업 디렉토리 내에서 간단한 README 를 작성해 보겠습니다.

$ echo 'My Project' > README

$ 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)

새로 만든 README 파일이 untracked 파일인 것을 확인할 수 있습니다. 이처럼 git status 명령어는 tracked 파일 뿐만 아니라, untracked 파일까지도 인지할 수 있습니다.

 

3. Tracking New Files

새로운 파일을 tracking 하기 시작하려면 git add 명령어를 사용해야 합니다.

이는 untracked 파일을 tracked 파일로 바꿔줍니다.

그렇다면 위에서 만들어 두었던 README 파일을 tracking 해보도록 하겠습니다.

$ git add README

그리고서 다시 git status 를 통해 확인해보겠습니다.

$ git status

On branch master

Your branch is up-to-date with 'origin/master'.

Changes to be committed:

    (use "git restore --staged <file>..." to unstage)

        new file: README

결과를 보시면 "Changes to be committed" 라고 있는데, 이 뜻은 파일이 staged 상태가 되었음을 의미합니다.

이 상태에서 commit을 하게 되면 README 파일은 unmodified 상태가 됩니다.(그림 1 참조)

 

4. Git Ignore

작업을 하다보면 untracked 상태로 유지하고 싶은 파일들이 있을 수 있습니다.

(로그 파일, 빌드 시스템에 의해 생성된 파일 등)

 

이를 위해 Git 에서는 사용자가 정의해둔 네임 패턴에 해당하는 파일은 자동으로 tracking 하지 않도록 .gitignore 이라는 것을 제공합니다.

// .gitignore 파일
*.[oa]

*.[oa] 는 파일 이름은 상관 없고, 확장자가 .o 이거나 .a 인 모든 파일을 무시하겠다는 뜻입니다.

 

아마 기본적인 내용은 아실 것이라 생각하여 간단하게 패턴에 대해서만 몇 가지 살펴보도록 하겠습니다.

  • 빈 줄(blank line)과 # 으로 시작하는 라인은 무시됩니다.
  • 표준 glob patterns 으로 작동하며, 이는 전체 working tree에 recursive 하게 적용됩니다. (glob patterns - 정규 표현식과 유사한 패턴으로, 주로 쉘에서 사용)
  • 슬래시(/)로 패턴을 시작하면 recursivity를 회피할 수 있습니다.
  • 슬래시(/)로 패턴을 마무리하면 특정 디렉토리로 한정할 수 있습니다.
  • 느낌표(!)로 패턴을 시작하면 그에 해당하는 파일은 ignore 대상에서 제외 됩니다.

 

다음 예제를 보시면 보다 쉽게 이해할 수 있습니다.

# ignore all .a files

*.a

# but do track lib.a, even though you're ignoring .a files above

!lib.a

# only ignore the TODO file in the current directory, not subdir/TODO

/TODO

# ignore all files in any directory named build

build/

# ignore doc/notes.txt, but not doc/server/arch.txt

doc/*.txt

# ignore all .pdf files in the doc/ directory and any of its subdirectories

doc/**/*.pdf

 

5. Removing Files

Git 으로 부터 파일을 지우려면, staging area 로 부터 tracked file 을 지우고서 commit 해야 합니다.

그리고 git rm 이 이러한 일을 해줍니다. 주의할 점은 git rm 은 staging area 에서만 제외하는 것이 아니라 실제 파일이나 디렉토리를 삭제 하기도 한다는 것입니다.

 

만약 modified 상태의 파일이나 이미 staging area에 추가된 파일을 지우고자 한다면 -f 옵션을 사용하여 강제 제거해야 합니다. (이는 아직 스냅샷에 기록되지 않은 데이터나 Git에서 복구할 수 없는 데이터가 우발적으로 제거되는 것을 방지하기 위한 안전장치가 되어 있기 때문입니다.)

 

git rm 에는 또 하나 유용한 옵션이 있습니다. 그건 바로 --cached 옵션입니다.

이 옵션은 실제 Working tree 에서는 파일을 유지하면서 staging area 에서만 제거하고 싶을 때 사용하면 됩니다. 이는 보통 .gitignore에 미처 등록하지 못하여 올리고 싶지 않은 파일이 staging area 에 올라갔거나, 커밋의 대상으로 적절하지 않은 파일이 올라갔을 때 특정 파일만 unstaged 상태로 만드는 용도로 사용됩니다.

 

6. Moving Files

다른 VCS 와는 다르게, Git은 명시적으로 파일 이동(file movement)을 트래킹하지 않습니다.

만약 git 안에 파일을 rename 한다면, git에는 이 파일이 rename 된 것이라는 어떠한 메타 데이터도 남기지 않습니다.

 

쉘에서와 마찬가지로 git에서도 git mv 라는 명령어를 제공합니다. 그리고 이 명령어가 rename 에도 사용됩니다. git은 그저 mv 된 파일들을 암묵적으로 rename 되었다고 판단합니다.

$ 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 를 수행한 후에 status를 살펴보면 renamed로 인식됩니다.

그러나 이는 사실상 아래와 같은 처리를 수행한 것입니다.

$ mv README.md README

$ git rm README.md

$ git add README

출처 - 저서 ProGit

반응형
반응형