LainyZine: 프로그래머 가이드 🐣

git clean 사용법: Git 저장소에 포함되지 않은 파일 삭제

Git을 사용해 소스코드를 관리하다 보면 변경 사항과 관련된 여러가지 작업을 해야하는 상황이 생깁니다. Git에서는 파일들을 크게 저장소에 포함된 커밋된 파일들과, 저장소에 포함될 예정인 스테이징 상태의 파일, 그리고 저장소에 포함되지 않은 파일들로 나눌 수 있습니다. 저장소에 포함되지 않은 파일들은 추적되지 않는(Untracked) 상태의 파일이라고 하며, 아직 저장소에서 관리하는 대상이 아닙니다. git status 명령어를 사용하면 추적되지 않는 파일들도 함께 알려줍니다. 나중에 커밋하거나 수정하기 위한 용도로 남겨둘 수도 있지만, 필요없는 파일들이 저장소 디렉터리에 포함된 경우 git clean 명령어로 한꺼번에 삭제해버릴 수도 있습니다. 이 글에서는 git clean 명령어를 소개합니다.

git clean 테스트할 예제 Git 저장소 만들기

git clean 명령어를 테스트하기 위한 간단한 예제 환경을 만들어보겠습니다. git-clean 디렉터리를 하나 만들고 Git 저장소를 초기화해줍니다.

$ mkdir git-clean
$ cd git-clean
$ git init
Initialized empty Git repository in /Users/lainyzine/tmp/git-clean/.git/

$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)

빈 상태의 Git 저장소가 만들어졌습니다. 이번에는 a, b, c, d, e 다섯 개의 파일을 만들고 a, b, c 파일만 커밋해보겠습니다.

$ touch a b c d e
$ git add a b c
$ git commit -m'Initialize repository'
[master (root-commit) 491cb5f] Initialize repository
 3 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a
 create mode 100644 b
 create mode 100644 c

그럼 a, b, c는 저장소에 포함된(커밋된) 상태가 됩니다. 그리고 이번에는 d 파일을 git add로 스테이지 상태로 변경한 다음 git status로 저장소의 상태를 확인해봅니다.

$ git add d
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   d

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

이제 d 파일은 스테이지 상태(Changs to be committed)가 되었고, e 파일은 추적되지 않는(Untracked files) 상태로 남아있습니다.

git clean으로 저장소에서 추적되지 않는 파일 삭제하기

git clean 명령어는 앞에서 이야기한대로 Git 저장소에서 추적하지 않는 파일들(Untracked files)을 삭제해주는 명령어입니다. 논리적으로 생각해보면 현재 저장소에서 git clean을 실행하면, e 파일을 삭제해야합니다. 실제로 이렇게 동작할까요? 한 번 실행해보겠습니다.

$ git clean
fatal: clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean

fatal 에러가 나면서 삭제가 되지 않습니다. 여전히 파일은 그대로 남아있습니다.

☠️ 주의사항: git clean 명령어가 실패하는 데서도 유추할 수 있습니다만, 이 명령어는 기본적으로 매우 위험한 명령어입니다. Git으로 추적되지 않는 파일을 삭제해버리면 되돌릴 수 있는 방법이 없습니다. 따라서 이 명령어를 사용하기 전에는 정말로 필요 없는 파일인지 한 번 더 확인하는 것을 추천합니다. ☠️

주의사항을 확인하셨다면 강제 삭제 옵션을 -f 사용해 다시 한 번 실행해보겠습니다.

$ git clean -f
Removing e

$ gs
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   d

$ ls
a b c d

정말로 e 파일이 삭제되었습니다. a, b, c 파일은 커밋된 파일이라 영향을 받지 않았고, d 파일은 스테이지에 남아있습니다.

git clean 명령어는 기본적으로 디렉터리는 삭제하지 않습니다. 간단한 예제로 확인해보겠습니다.

$ mkdir somedir
$ git clean -f
<아무 내용 없음>
$ ls
a b c d somedir

디렉터리는 그대로 남아있는 것을 알 수 있습니다. 디렉터리까지 삭제하려면 d 옵션을 사용하면 됩니다.

$ git clean -d -f
Removing somedir/

$ ls
a b c d

somedir도 같이 삭제되었습니다.

git clean으로 삭제 될 파일 미리 확인하기

git clean으로 삭제될 파일들은 git status 명령어로 확인해볼 수 있습니다만, git clean 명령어의 옵션에 따라서 삭제 대상이 달라지기 때문에 정확한 것은 아닙니다. 이럴 때는 -n(--dry-run) 옵션을 사용해서 삭제 대상을 먼저 확인해볼 수 있습니다.

몇 개의 파일을 만들고, 드라이 런을 해보겠습니다.

$ touch e 1 2 3 4 5
$ mkdir somedir
$ git clean -n
Would remove 1
Would remove 2
Would remove 3
Would remove 4
Would remove 5
Would remove e

새로 만들 파일들은 모두 Git 저장소에서 추적되지 않는 상태이므로 삭제할 예정이라고 출력됩니다. 단, somedir은 삭제 대상에 포함되지 않습니다.

이번에는 앞에서 다룬 디렉터리도 함께 삭제하는 d 옵션을 붙여보겠습니다.

$ git clean -n -d
Would remove 1
Would remove 2
Would remove 3
Would remove 4
Would remove 5
Would remove e
Would remove somedir/

새로 추가된 파일들과 디렉터리까지 모두 삭제 대상에 포함됩니다.

git clean으로 특정한 파일들만 삭제하기

예제를 통해서 git clean의 몇 가지 사용법을 알아보았습니다. git clean 명령어의 기본적인 사용법은 다음과 같습니다.

git clean [OPTIONS] [PATH]

지금까지는 PATH 인자를 붙이지 않고 사용했습니다만, PATH를 지정하면 특정한 경로만을 대상으로 git clean을 실행할 수 있습니다. 예를 들어 앞에서 만든 숫자 파일들만 삭제하려면 다음과 같이 실행하면됩니다.

$ git clean -f 1 2 3 4 5
Removing 1
Removing 2
Removing 3
Removing 4
Removing 5

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   d

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

git clean을 실행했지만 모든 파일이 삭제된 것은 아닙니다. 정확히 지정된 PATH의 파일들만을 대상으로 git clean이 동작한 것을 알 수 있습니다.

인터렉티브 모드로 삭제 대상을 검토하는 것도 가능합니다. 이 때는 i 옵션을 사용합니다. 인터렉티브 모드는 여러가지 기능이 있어서 직접 사용하면서 사용법일 익혀보는 것을 추천합니다. 간단한 활용법을 하나 소개해보면, 파일 별로 하나씩 삭제 여부를 결정할 수 있습니다.

$ touch 1 2 3 4 5
$ git clean -d -i
Would remove the following items:
  1         2         3         4         5         e         somedir/
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each
    5: quit                 6: help
What now> 4
Remove 1 [y/N]? y
Remove 2 [y/N]? y
Remove 3 [y/N]? f
Remove 4 [y/N]? y
Remove 5 [y/N]? f
Remove e [y/N]? y
Remove somedir/ [y/N]? y

인터렉티브 모드에서 4번을 선택하면 파일을 하나씩 삭제할지 물어봅니다. 이 상태에서 git status로 확인해보면 3과 5만 남아있는 것을 확인할 수 있습니다.

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   d

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

.gitignore 파일에서 무시하는 파일 삭제하기

하나 더 자주 사용할만한 옵션을 소개한다면 소문자 x와 대문자 X 옵션이 있습니다.

.gitignore 파일은 저장소에서 관리하지 않을 파일들을 나열해두는 특수한 파일입니다.

이번에도 간단한 예제로 확인해보겠습니다. 먼저 ignore1과 ignore2를 .gitignore 파일에 추가하고, 이 내용을 커밋합니다. 그 다음 ignore1과 ignore2 파일을 생성합니다.

$ echo "ignore1\nignore2" > .gitignore
$ cat .gitignore
ignore1
ignore2

$ git add .gitignore
$ git commit -m'Add .gitignore'
[master e09a2db] Add .gitignore
 1 files changed, 2 insertions(+)
 create mode 100644 .gitignore

$ touch ignore1 ignore2

git clean의 삭제 대상을 확인해봅니다.

$ ls
3       5       a       b       c       d       ignore1 ignore2

$ git clean -n
Would remove 3
Would remove 5

ignore1ignore2는 추적되지 않는 파일임에도 불구하고 .gitignore에 나열되어있어서 삭제 대상에 포함되지 않습니다. 이번에는 -x 옵션을 붙여서 실행해보겠습니다.

$ git clean -n -x
Would remove 3
Would remove 5
Would remove ignore1
Would remove ignore2

삭제 대상에 ignore1과 ignore2도 포함되었습니다.

x 옵션과 비슷한 X 옵션은 .gitignore에 포함된 파일만 삭제 대상으로 합니다.

$ git clean -n -X
Would remove ignore1
Would remove ignore2

정확히 .gitignore에 포함된 Git 저장소에서 추적되지 않는 파일만 삭제할 대상으로 보여줍니다.

git clean과 비슷하지만 다른 명령어들: stash, reset, revert 등

git clean이 저장소에서 추적하지 않는 명령어라면, 현재 저장소의 변경사항을 임시 저장할 때는 git stash를 사용합니다. stash 명령어는 Git 저장소에서 추적하는 파일들을 임시 저장할뿐만 아니라 u 옵션을 사용해 추적하지 않는 파일도 함께 임시 저장할 수 있습니다. git stash의 자세한 사용법은 다음 글에서 소개합니다.

git clean과 혼동되는 명령어 중 하나가 git reset입니다. reset은 Git 저장소를 특정 상태로 되돌려줍니다만, 추적되지 않는 파일을 삭제하지는 않습니다. 특정 커밋으로 돌아간 다음, 저장소에서 추적하지 않는 파일을 삭제하려면 git clean 명령어와 함께 사용해야합니다. 그 외에 비슷한 명령어로 git revert 명령어는 특정한 커밋의 내용을 취소하는 커밋을 생성해줍니다. reset과 revert 서브 커맨드에 대해서는 아래 글에서 소개합니다.

LainyZine은 쿠팡 파트너스 활동에 따른 수수료를 제공받습니다.