Close

Git prune

git prune 명령은 연결할 수 없거나 "고립된" Git 개체를 정리하는 내부용 유틸리티입니다. 연결할 수 없는 개체란 어떤 ref도 액세스할 수 없는 개체입니다. 브랜치나 태그를 통해 액세스할 수 없는 커밋은 연결할 수 없는 것으로 간주됩니다. git prune은 일반적으로 직접 실행되지 않습니다. Prune은 가비지 컬렉션 명령으로 간주되며 git gc 명령의 하위 명령입니다.


Git Prune 개요


git prune의 영향을 이해하려면 커밋에 연결할 수 없게 되는 시나리오를 시뮬레이션해야 합니다. 이러한 경험을 시뮬레이션하는 명령줄 실행 시퀀스는 다음과 같습니다.

~ $ cd git-prune-demo/
~/git-prune-demo $ git init .
Initialized empty Git repository in /Users/kev/Dropbox/git-prune-demo/.git/
~/git-prune-demo $ echo "hello git prune" > hello.txt
~/git-prune-demo $ git add hello.txt
~/git-prune-demo $ git commit -am "added hello.txt"

앞의 명령 시퀀스는 git-prune-demo라는 디렉터리에 새 리포지토리를 만듭니다. 새 파일 hello.text로 구성된 하나의 커밋이 "hello git prune"의 기본 콘텐츠와 함께 리포지토리에 추가됩니다. 다음으로 hello.txt를 만들고 수정한 다음 해당 수정에서 새 커밋을 만들 것입니다.

~/git-prune-demo $ echo "this is second line txt" >> hello.txt
~/git-prune-demo $ cat hello.txt
hello git prune
this is second line txt
~/git-prune-demo $ git commit -am "added another line to hello.txt"
[main 5178bec] added another line to hello.txt
1 file changed, 1 insertion(+)
데이터베이스
관련 자료

전체 Git 리포지토리를 이동하는 방법

Bitbucket 로고
솔루션 보기

Bitbucket Cloud에서 Git에 대해 알아보기

이제 데모 리포지토리에 2개의 커밋 기록이 생겼습니다. git log로 확인할 수 있습니다.

~/git-prune-demo $ git log
commit 5178becc2ca965e1728554ce1cb8de2f2c2370b1
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 14:49:59 2018 -0700

        added another line to hello.txt

commit 994b122045cf4bf0b97139231b4dd52ea2643c7e
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 09:43:41 2018 -0700

        added hello.txt

git log 출력에는 hello.txt의 편집에 대한 커밋 2개와 해당 커밋 메시지가 표시됩니다. 다음 단계는 커밋 중 하나를 연결할 수 없도록 만드는 것입니다. git reset 명령을 활용하여 이 작업을 수행합니다. 리포지토리 상태를 첫 번째 커밋인 "added hello.txt" 커밋으로 재설정합니다.

~/git-prune-demo $ git reset --hard 994b122045cf4bf0b97139231b4dd52ea2643c7e
HEAD is now at 994b122 added hello.txt

이제 git log를 사용하여 리포지토리 상태를 살펴보면 커밋이 하나만 있음을 알 수 있습니다

~/git-prune-demo $ git log
commit 994b122045cf4bf0b97139231b4dd52ea2643c7e
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 09:43:41 2018 -0700

        added hello.txt

데모 리포지토리는 이제 분리된 커밋을 포함하는 상태에 있습니다. "added another line to hello.txt" 메시지로 만든 두 번째 커밋은 더 이상 git log 출력에 표시되지 않으며 이제 분리되었습니다. 커밋이 손실되었거나 삭제된 것처럼 보일 수 있지만 Git은 기록을 삭제하지 않는 것에 대해 매우 엄격합니다. git checkout을 사용하여 직접 살펴보면 해당 커밋이 아직 사용할 수 있지만 분리되어 있다는 것을 확인할 수 있습니다.

~/git-prune-demo $ git checkout 5178becc2ca965e1728554ce1cb8de2f2c2370b1
Note: checking out '5178becc2ca965e1728554ce1cb8de2f2c2370b1'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

      git checkout -b <new-branch-name>

HEAD is now at 5178bec... added another line to hello.txt
~/git-prune-demo $ git log
commit 5178becc2ca965e1728554ce1cb8de2f2c2370b1
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 14:49:59 2018 -0700

      added another line to hello.txt

commit 994b122045cf4bf0b97139231b4dd52ea2643c7e
Author: kevzettler <kevzettler@gmail.com>
Date:   Sun Sep 30 09:43:41 2018 -0700

      added hello.txt

분리된 커밋을 체크아웃하면 Git은 세심하게 우리가 분리된 상태에 있음을 설명하는 자세한 메시지를 보내줍니다. 여기의 로그를 보면 "added another line to hello.txt" 커밋이 이제 로그 출력으로 돌아온 것을 볼 수 있습니다! 이제 리포지토리가 분리된 커밋이 있는 양호한 시뮬레이션 상태라는 것을 알게 되었으므로 git prune을 사용하여 연습할 수 있습니다. 하지만 먼저 git checkout을 사용하여 main 브랜치로 돌아가 보겠습니다.

~/git-prune-demo $ git checkout main
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

      5178bec added another line to hello.txt

If you want to keep it by creating a new branch, this may be a good time
to do so with:

     git branch <new-branch-name> 5178bec

Switched to branch 'main'

git checkout을 통해 main으로 돌아가면 Git은 다시 한 번 세심하게 우리가 분리된 커밋을 놔두고 간다는 사실을 알려줍니다. 이제 분리된 커밋을 정리할 시간입니다! 다음으로 git prune을 실행할 것이지만 몇 가지 옵션을 전달해야 합니다. --dry-run--verbose는 정리하도록 설정된 항목을 나타내는 출력을 표시하지만 실제로 정리하지는 않습니다.

~/git-prune-demo $ git prune --dry-run --verbose

이 명령은 빈 출력을 반환할 가능성이 높습니다. 빈 출력은 prune이 실제로 아무 것도 삭제하지 않음을 의미합니다. 왜 이런 일이 일어날까요? 커밋은 완전히 분리되지 않았을 가능성이 높기 때문입니다. Git은 아직 커밋에 대한 참조를 어딘가에 유지하고 있습니다. 이는 git gc 외부에서 git prune을 독립 실행형으로 사용하면 안 되는 이유를 보여주는 좋은 예시입니다. 또한 Git으로 데이터를 완전히 손실하기 얼마나 어려운지를 보여주는 좋은 예시이기도 합니다.

Git은 분리된 커밋에 대한 참조를 reflog에 저장하고 있을 가능성이 높습니다. git reflog를 실행하여 확인할 수 있습니다. 이 단계까지 오기 위해 수행한 일련의 작업을 설명하는 출력이 표시됩니다. git reflog에 대한 자세한 내용은 git reflog 페이지를 참조하세요. reflog에서 기록을 보존하는 것 외에도 Git에는 분리된 커밋을 정리할 시기에 대한 내부 만료 날짜가 있습니다. 다시 강조하자면 이 모든 것은 git gc가 처리하는 구현 세부 사항이며 git prune은 독립 실행형으로 사용해서는 안 됩니다.

git prune 시뮬레이션 데모를 마무리하기 위해 reflog를 지워야 합니다

~/git-prune-demo $ git reflog expire --expire=now --expire-unreachable=now --all

위의 명령은 지금보다 오래된 reflog 항목을 모두 강제로 만료시킵니다. 일반 Git 사용자로서는 절대 사용할 일이 없을 위험한 명령입니다. 여기서는 git prune에 성공한 것을 보여주기 위해 이 명령을 실행하는 것입니다. reflog가 완전히 지워지면 이제 git prune을 실행할 수 있습니다.

~/git-prune-demo $ git prune --dry-run --verbose --expire=now
1782293bdfac16b5408420c5cb0c9a22ddbdd985 blob
5178becc2ca965e1728554ce1cb8de2f2c2370b1 commit
a1b3b83440d2aa956ad6482535cbd121510a3280 commit
f91c3433eae245767b9cd5bdb46cd127ed38df26 tree

이 명령은 위와 비슷한 Git SHA 개체 참조 목록을 출력합니다.

사용


git prune에는 개요 섹션에서 다룬 몇 가지 옵션이 있습니다.

-n --dry-run

prune을 실행하지 않고 prune이 어떤 일을 할지에 대한 출력만 표시합니다

-v --verbose

prune에서 수행한 모든 개체 및 작업의 출력을 표시합니다

--progress

prune의 진행률을 나타내는 출력을 표시합니다

--expire <time>

시간이 지난 개체를 강제로 만료합니다

<head>…

<head>를 지정하면 해당 head ref의 모든 옵션이 보존됩니다

토론


Git Prune, Git Fetch --prune 및 Git Remote Prune의 차이점은 무엇입니까?

git remote prunegit fetch --prune은 동일한 작업을 수행하며 원격에 없는 브랜치의 ref를 삭제합니다. 이는 main에 병합한 후 원격 브랜치가 삭제되는 팀 워크플로에서 작업할 때 매우 유용합니다. 두 번째 명령인 git fetch --prune은 정리하기 전에 원격에 연결하여 최근 원격 상태를 가져옵니다. 기본적으로 명령의 조합에 해당합니다.

git fetch --all && git remote prune

일반적인 git prune 명령은 완전히 다릅니다. 개요 섹션에서 설명한 것처럼 git prune은 로컬에서 분리된 커밋을 삭제합니다.

오래된 브랜치는 어떻게 정리합니까?

git fetch --prune은 오래된 브랜치를 정리하는 데 가장 적합한 유틸리티입니다. 원격 공유 리포지토리에 원격으로 연결하여 모든 원격 브랜치 ref를 가져옵니다. 그런 다음 원격 리포지토리에서 더 이상 사용하지 않는 원격 ref를 삭제합니다.

Git Remote Prune Origin은 로컬 브랜치를 삭제합니까?

아니요, git remote prune origin은 더 이상 존재하지 않는 원격 브랜치의 ref만 삭제합니다. Git은 로컬 ref와 원격 ref 모두 저장합니다. 리포지토리에는 local/originremote/origin ref 컬렉션이 있습니다. git remote prune originremote/origin에 있는 ref만 정리합니다. 그러면 로컬 작업은 local/origin에 안전하게 유지됩니다.

Git Prune 요약


git prune 명령은 git gc의 하위 명령으로 호출하기 위한 것입니다. 일상적인 소프트웨어 엔지니어링 작업에서 git prune을 호출해야 할 가능성은 매우 낮습니다. git prune의 영향을 이해하려면 다른 명령이 필요합니다. 이 글에서는 git log, git refloggit checkout과 같은 명령을 사용했습니다.


이 문서 공유
다음 토픽

여러분께 도움을 드릴 자료를 추천합니다.

이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.

도구로 가득한 벽을 사용하여 협업하는 사람들

Bitbucket 블로그

DevOps 일러스트레이션

DevOps 학습 경로

Atlassian 전문가와 함께 하는 Demo Den 기능 데모

Bitbucket Cloud가 Atlassian Open DevOps와 작동하는 방법

DevOps 뉴스레터 신청

Thank you for signing up