git / GitHub의 기록에서 폴더와 그 내용을 제거하십시오
내 GitHub 계정의 리포지토리에서 작업하고 있는데 이것이 우연히 발견 된 문제입니다.
- 몇 개의 npm 패키지가 설치된 폴더가있는 Node.js 프로젝트
- 패키지는
node_modules
폴더에 있었다 - 해당 폴더를 git 저장소에 추가하고 코드를 github로 푸시했습니다 (당시 npm 부분에 대해서는 생각하지 않았습니다)
- 해당 폴더가 코드의 일부가 될 필요는 없다는 것을 깨달았습니다.
- 해당 폴더를 삭제하고 푸시
이 경우 총 git repo의 크기는 약 6MB 였고 실제 코드 (해당 폴더 제외)는 약 300KB 였습니다 .
이제 마지막으로 찾고있는 것은 git의 기록에서 해당 패키지 폴더의 세부 정보를 제거하는 방법이므로 누군가 복제 한 경우 6mb 가치의 기록을 다운로드 할 필요가 없습니다. 마지막 커밋은 300KB입니다.
가능한 해결책을 찾고이 두 가지 방법을 시도했습니다.
- 자식 저장소에서 파일을 제거하십시오 (이력)
- http://help.github.com/remove-sensitive-data/
- https://gist.github.com/1588371
Gist는 스크립트를 실행 한 후 해당 폴더를 제거했음을 보여준 후 50 개의 다른 커밋이 수정 된 것으로 나타났습니다. 그러나 그것은 그 코드를 밀어 넣지 못했습니다. 내가 그것을 밀어 넣으려고했을 때, 그것은 Branch up to date
50 커밋이에 수정되었음을 보여주었습니다 git status
. 다른 두 가지 방법도 도움이되지 않았습니다.
이제 폴더의 기록을 제거했음을 보여 주었지만 로컬 호스트에서 해당 리포지토리의 크기를 확인할 때 여전히 약 6MB였습니다. (또한 refs/original
폴더를 삭제 했지만 저장소 크기의 변화를 보지 못했습니다).
내가 분명히하고 싶은 것은 커밋 히스토리 (내가 생각한 유일한 것임)뿐만 아니라 git가 롤백하고 싶다고 가정하는 파일을 제거하는 방법이 있는지 확인하는 것입니다.
해결책이 제시되어 내 로컬 호스트에 적용되었지만 해당 GitHub 저장소로 재현 할 수 없다고 가정 해보십시오. 해당 저장소를 복제하고 첫 번째 커밋으로 롤백하여 트릭을 수행하고 푸시 할 수 있습니까 (또는 git이 여전히 모든 커밋의 역사가 있습니까?-일명 6MB).
내 최종 목표는 기본적으로 git에서 폴더 내용을 제거하는 가장 좋은 방법을 찾는 것입니다. 따라서 사용자는 6MB 상당의 자료를 다운로드 할 필요가 없으며 여전히 모듈 폴더를 건드리지 않은 다른 커밋을 가질 수 있습니다 (예 : git의 역사에서).
어떻게해야합니까?
코드를 복사하여 붙여 넣기하려면 :
이것은 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
자식이 실제로하는 일 :
첫 번째 줄은 'rm -rf node_modules'명령을 실행하여 HEAD (현재 분기)와 동일한 트리 (--tree-filter)의 모든 참조를 반복합니다. 이 명령은 사용자에게 프롬프트를 표시하지 않고 node_modules 폴더를 삭제합니다 (-r없이 -r, rm은 폴더를 삭제하지 않음). 추가 된 --prune-empty는 쓸모없는 (아무것도 변경하지 않은) 커밋을 재귀 적으로 삭제합니다.
두 번째 줄은 이전 분기에 대한 참조를 삭제합니다.
나머지 명령은 비교적 간단합니다.
나는 것을 발견 --tree-filter
다른 답변에서 사용되는 옵션은 특히 커밋의 많은 큰 저장소에 매우 느릴 수 있습니다.
다음은 --index-filter
옵션을 사용하여 git history에서 디렉토리를 완전히 제거하는 데 사용되는 방법입니다 .
# 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
with 전후에 리포지토리의 크기를 확인할 수 있습니다 .
git count-objects -vH
위 의 인기있는 답변 외에도 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 # i.e. 'node_modules' in other examples
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push --mirror https://project/new-repository
파일을 삭제하려면 대신 delete-files 옵션을 사용하십시오.
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
Windows의 git을 사용하여 오래된 C # 프로젝트에서 bin 및 obj 폴더를 제거했습니다. 조심해
git filter-branch --tree-filter "rm -rf bin" --prune-empty HEAD
git install 폴더에서 usr / bin 폴더를 삭제하여 git 설치의 무결성을 파괴합니다.
참고 URL : https://stackoverflow.com/questions/10067848/remove-folder-and-its-contents-from-git-githubs-history
'Programing' 카테고리의 다른 글
Java 메소드를 선언하거나 더 이상 사용되지 않는 것으로 표시하는 방법은 무엇입니까? (0) | 2020.03.25 |
---|---|
Thread에서 ThreadStart 메소드에 매개 변수를 전달하는 방법은 무엇입니까? (0) | 2020.03.25 |
EC2 인스턴스에는 퍼블릭 DNS가 없습니다 (0) | 2020.03.25 |
JavaScript로 이미지의 실제 너비와 높이를 얻으시겠습니까? (0) | 2020.03.25 |
JSP 또는 JSTL 내에있는 경우 (0) | 2020.03.25 |