Git/GitHub 기록에서 폴더 및 폴더 내용 제거
저는 GitHub 계정에서 저장소 작업을 하고 있었는데 우연히 발견한 문제입니다.
- 몇 개의 npm 패키지가 설치된 폴더가 있는 Node.js 프로젝트
- 는 소들포은안있다니습었에▁in로 되어 있었습니다.
node_modules
folder - git 저장소에 해당 폴더를 추가하고 코드를 git허브에 푸시했습니다(당시 npm 부분은 생각하지 않았습니다).
- 해당 폴더가 코드의 일부가 될 필요가 없음을 깨달았습니다.
- 해당 폴더를 삭제하고 푸시했습니다.
당시 총 Gitrepo의 크기는 약 6MB였으며 실제 코드(해당 폴더를 제외한 모든 코드)는 약 300KB에 불과했습니다.
마지막으로 제가 찾고 있는 것은 Git의 기록에서 패키지 폴더의 세부 정보를 제거하는 방법입니다. 따라서 누군가가 Git를 복제할 경우 마지막 커밋 기준으로 얻을 수 있는 실제 파일이 300KB인 6MB의 기록을 다운로드할 필요가 없습니다.
저는 이에 대한 가능한 해결책을 찾아 이 두 가지 방법을 시도했습니다.
Gist는 스크립트를 실행한 후 해당 폴더를 제거한 후 50개의 다른 커밋이 수정된 것으로 나타났습니다.하지만 그것은 제가 그 코드를 누르지 못하게 했습니다.내가 그것을 밀려고 했을 때, 그것은 말했습니다.Branch up to date
하지만 50개의 커밋이 수정되었음을 보여줍니다.git status
다른 두 가지 방법도 도움이 되지 않았습니다.
폴더의 ( 해제폴기제나만것지났또타로, 컬스호해때확크리 6MB여는을했인전삭정습니했다제한다니습였도히이당서를트에기포당의더으거의록로된이)▁(▁the▁now또▁deletedmb'i▁also▁(▁6▁still▁when,▁that▁folder))refs/original
폴더를 만들었지만 저장소 크기의 변경 내용을 확인하지 못했습니다.
제가 분명히 하고 싶은 것은 커밋 기록(내가 생각하는 유일한 일)뿐만 아니라 롤백하고 싶다고 가정한 파일들도 제거할 수 있는 방법이 있는지 여부입니다.
여기에 대한 솔루션이 제공되고 로컬 호스트에 적용되지만 해당 GitHub repo에 복제할 수 없다고 가정해 보겠습니다. 해당 repo를 복제하고 첫 번째 커밋으로 롤백하여 트릭을 수행하고 푸시할 수 있습니다(또는 Git에 모든 커밋의 기록이 여전히 남아 있음을 의미합니까? 즉, 6MB).
여기서 저의 최종 목표는 기본적으로 git에서 폴더 내용을 제거하는 최선의 방법을 찾는 것입니다. 따라서 사용자는 6MB 상당의 자료를 다운로드할 필요가 없고 모듈 폴더를 건드리지 않은 다른 커밋(거의 모든 것)을 기록할 수 있습니다.
어떻게 해야 하나요?
경고: 깃 필터 분기는 더 이상 공식적으로 권장되지 않습니다.공식적인 권장 사항은 git-filter-repo를 사용하는 것입니다. 자세한 내용은 André Anjos의 답변을 참조하십시오.
코드를 복사하여 붙여넣으려면 다음을 수행합니다.
은 다은다음제예다니제입는을 제거하는 입니다.node_modules
git filter-branch --tree-filter "rm -rf node_modules" --prune-empty HEAD
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
echo node_modules/ >> .gitignore
git add .gitignore
git commit -m 'Removing node_modules from git history'
git gc
git push origin master --force
git가 실제로 하는 일:
번째 트리에 합니다.--tree-filter
분기로, HEAD(으) , 명령실행rm -rf node_modules
폴더node_modules")를 합니다.-r
를 제외하고, 이없.-r
,rm
않음(더를삭제지않음폴하않표음지사용자시를하롬프트에프게▁won),-f
)가 추가됨--prune-empty
불필요한(아무 것도 변경하지 않음) 커밋을 반복적으로 삭제합니다.
두 번째 줄은 이전 분기에 대한 참조를 삭제합니다.
나머지 명령은 비교적 간단합니다.
나는 그것을 발견합니다.--tree-filter
다른 답변에 사용되는 옵션은 특히 커밋이 많은 대규모 저장소에서 매우 느릴 수 있습니다.
다음은 Git 기록에서 디렉터리를 완전히 제거하기 위해 사용하는 방법입니다.--index-filter
훨씬 더 빨리 실행되는 옵션:
# Make a fresh clone of YOUR_REPO
git clone YOUR_REPO
cd YOUR_REPO
# Create tracking branches of all branches
for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done
# Remove DIRECTORY_NAME from all commits, then remove the refs to the old commits
# (repeat these two commands for as many directories that you want to remove)
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch DIRECTORY_NAME/' --prune-empty --tag-name-filter cat -- --all
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
# Ensure all old refs are fully removed
rm -Rf .git/logs .git/refs/original
# Perform a garbage collection to remove commits with no refs
git gc --prune=all --aggressive
# Force push all branches to overwrite their history
# (use with caution!)
git push origin --all --force
git push origin --tags --force
저장소의 크기를 확인할 수 있습니다.gc
매개 변수:
git count-objects -vH
이에 대한 최신 답변은 다음을 사용하지 않는 것으로 보입니다.filter-branch
직접(최소한 Git 자체는 더 이상 권장하지 않음) 작업을 외부 도구로 연기합니다.특히 git-filter-repo는 현재 권장됩니다.해당 도구의 작성자는 사용하는 이유에 대한 주장을 제공합니다.filter-branch
직접적으로 문제로 이어질 수 있습니다.
를 제거하기 위한 줄 dir
기록에서 다음과 같이 다시 기록할 수 있습니다.
git-filter-repo --path dir --invert-paths
그 도구는 그것보다 더 강력합니다.작성자, 전자 메일, 참조자 이름 등(여기서는 전체 메뉴 페이지)별로 필터를 적용할 수 있습니다.게다가, 그것은 빠릅니다.설치는 간단합니다. 다양한 형식으로 배포됩니다.
위의 일반적인 답변 외에도 Windows 시스템에 대한 몇 가지 참고 사항을 추가하고 싶습니다.명령어
git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
수정 없이 완벽하게 작동합니다!따라서 다음을 사용해서는 안 됩니다.
Remove-Item
,del
또는 다른 것 대신에.rm -rf
.파일 또는 디렉토리의 경로를 지정해야 하는 경우 다음과 같은 슬래시를 사용합니다.
./path/to/node_modules
내가 찾은 가장 좋고 정확한 방법은 bfg.jar 파일을 다운로드하는 것이었습니다. https://rtyley.github.io/bfg-repo-cleaner/
그런 다음 명령을 실행합니다.
git clone --bare https://project/repository project-repository
cd project-repository
java -jar bfg.jar --delete-folders DIRECTORY_NAME
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push --mirror https://project/new-repository
파일을 삭제하려면 파일 삭제 옵션을 대신 사용합니다.
java -jar bfg.jar --delete-files *.pyc
복사 & 붙여넣기 방법을 테스트한 후 주석에 명령을 추가하기만 하면 됩니다(복사 붙여넣기 솔루션의 경우).
git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
echo node_modules/ >> .gitignore
git add .gitignore
git commit -m 'Removing node_modules from git history'
git gc
git push origin master --force
그런 다음 .gitignore에서 "node_modules/" 행을 제거할 수 있습니다.
Windows 사용자의 경우 다음을 사용하십시오."
대신에'
추가됨-f
다른 백업이 이미 있는 경우 강제로 명령을 실행합니다.
git filter-branch -f --tree-filter "rm -rf FOLDERNAME" --prune-empty HEAD
git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
echo FOLDERNAME/ >> .gitignore
git add .gitignore
git commit -m "Removing FOLDERNAME from git history"
git gc
git push origin master --force
git on window를 사용하여 이전 C# 프로젝트에서 bin과 obj 폴더를 제거했습니다.조심하세요
git filter-branch --tree-filter "rm -rf bin" --prune-empty HEAD
Git 설치 폴더에서 usr/bin 폴더를 삭제하여 Git 설치의 무결성을 파괴합니다.
복사기의 경우(여기서):
git filter-repo --invert-paths --path PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA
echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
git add .gitignore
git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"
git push origin --force --all
언급URL : https://stackoverflow.com/questions/10067848/remove-folder-and-its-contents-from-git-githubs-history
'sourcecode' 카테고리의 다른 글
어레이별 MongoDB 그룹 내부 요소 (0) | 2023.05.03 |
---|---|
데이터를 "라우터 아웃렛" 하위 구성 요소로 전달 (0) | 2023.05.03 |
UI 보기의 왼쪽 상단 및 오른쪽 상단 모서리에만 모서리 반지름을 설정하는 방법은 무엇입니까? (0) | 2023.05.03 |
zip 아카이브에서 파일 하나를 업데이트하는 방법 (0) | 2023.05.03 |
새로운 DI를 사용하여 ILogger를 IWebJobs Startup을 사용하여 Azure 함수에 주입하려면 어떻게 해야 합니까? (0) | 2023.05.03 |