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 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 prune
및 git 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/origin
및 remote/origin
ref 컬렉션이 있습니다. git remote prune origin
은 remote/origin
에 있는 ref만 정리합니다. 그러면 로컬 작업은 local/origin
에 안전하게 유지됩니다.
Git Prune 요약
git prune
명령은 git gc
의 하위 명령으로 호출하기 위한 것입니다. 일상적인 소프트웨어 엔지니어링 작업에서 git prune
을 호출해야 할 가능성은 매우 낮습니다. git prune
의 영향을 이해하려면 다른 명령이 필요합니다. 이 글에서는 git log
, git reflog
및 git checkout
과 같은 명령을 사용했습니다.
이 문서 공유
다음 토픽
여러분께 도움을 드릴 자료를 추천합니다.
이러한 리소스에 책갈피를 지정하여 DevOps 팀의 유형에 대해 알아보거나 Atlassian에서 DevOps에 대한 지속적인 업데이트를 확인하세요.