민감한 파일과 GIT 기록에서 커밋을 제거하십시오
-
22-08-2019 - |
문제
GitHub에 GIT 프로젝트를 배치하고 싶지만 민감한 데이터 (Capistrano의 경우 /config/deploy.rb와 같은 사용자 이름 및 암호)가 포함 된 특정 파일이 포함되어 있습니다.
이 파일 이름을 추가 할 수 있다는 것을 알고 있습니다 .gitignore, 그러나 이것은 git 내에서 그들의 역사를 제거하지 않을 것입니다.
또한 /.git 디렉토리를 삭제하여 다시 시작하고 싶지 않습니다.
제거하는 방법이 있습니까? 모두 GIT 기록에서 특정 파일의 흔적?
해결책
모든 실용적인 목적을 위해 첫 번째 당신이 걱정해야 할 것은입니다 비밀번호 변경! GIT 저장소가 완전히 로컬인지 또는 아직 다른 곳에 원격 저장소가 있는지 여부는 확실하지 않습니다. 그것이 원격이고 다른 사람들로부터 보호되지 않으면 문제가 있습니다. 이 문제를 해결하기 전에 그 저장소를 복제 한 사람이라면, 그들은 로컬 컴퓨터에 비밀번호 사본을 갖게되며, 이력에서 나온 "고정 된"버전으로 업데이트 할 수있는 방법은 없습니다. 당신이 할 수있는 유일한 안전한 일은 비밀번호를 사용한 모든 곳으로 비밀번호를 변경하는 것입니다.
그 길을 벗어난 방법으로 여기에 고치는 방법이 있습니다. Github은 그 질문에 FAQ로 정확히 대답했습니다:
Windows 사용자의 참고 사항:이 명령에서 싱글 대신 이중 인용문 ( ")을 사용하십시오.
git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
이 코드를 Github와 같은 원격 저장소로 푸시하고 다른 사람들이 원격 저장소를 복제 한 후에는 이제 이력을 재 작성하는 상황에 처해 있습니다. 다른 사람들 이이 후 최신 변경 사항을 철회하려고하면 변경 사항이 빠르게 진행되지 않기 때문에 변경할 수 없다는 메시지가 표시됩니다.
이 문제를 해결하려면 기존 저장소를 삭제하고 다시 클론하거나 "업스트림 리베이스로부터 회수"의 지침을 따라야합니다. Git-Rebase Manpage.
앞으로 민감한 정보로 실수로 약간의 변경 사항을 제시하지만 ~ 전에 원격 저장소로 밀면 몇 가지 쉬운 수정 사항이 있습니다. 마지막으로 커밋 된 경우 민감한 정보를 추가하기위한 사람이라면 민감한 정보를 간단히 제거한 다음 실행할 수 있습니다.
git commit -a --amend
이는 이전의 새로운 변경 사항으로 이전 커밋을 수정하여 전체 파일 제거를 포함하여 git rm
. 변경 사항이 역사상 더욱 다시 돌아 왔지만 원격 저장소로 밀리지 않으면 대화식 리바이스를 수행 할 수 있습니다.
git rebase -i origin/master
그것은 원격 저장소를 사용한 마지막 공통 조상 이후로 만든 커밋으로 편집자를 열어줍니다. 민감한 정보가있는 커밋을 나타내는 모든 줄에서 "선택"을 "선택"으로 변경하고 저장 및 종료하십시오. Git은 변화를 안내하고 할 수있는 곳에 떠날 것입니다.
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
민감한 정보로 각 변경에 대해. 결국, 당신은 당신의 지점으로 돌아가서 새로운 변경 사항을 안전하게 밀어 넣을 수 있습니다.
다른 팁
비밀번호를 변경하는 것이 좋습니다. 그러나 리포지토리 기록에서 비밀번호를 제거하는 프로세스를 위해서는 다음을 추천합니다. BFG 리포 클리너, 더 빠르고 간단한 대안 git-filter-branch
Git Repos에서 개인 데이터를 제거하기 위해 명시 적으로 설계되었습니다.
a private.txt
제거하려는 비밀번호를 나열한 파일 (한 줄 당 항목 1 개)을 실행 한 다음이 명령을 실행하십시오.
$ java -jar bfg.jar --replace-text private.txt my-repo.git
리포 기록의 임계 값 크기 (기본적으로 1MB)의 모든 파일은 스캔되며 일치하는 문자열 (귀하의 안에 있지 않습니다. 최신 Commit)은 "*** 제거 ***"로 교체됩니다. 그런 다음 사용할 수 있습니다 git gc
죽은 데이터를 정리하기 위해 :
$ git gc --prune=now --aggressive
BFG는 일반적으로 실행보다 10-50 배 빠릅니다 git-filter-branch
그리고 옵션은이 두 가지 일반적인 사용 사례를 중심으로 단순화되고 조정됩니다.
- 풀이 미친 큰 파일
- 풀이 암호, 자격 증명 & 다른 개인 데이터
전체 공개 : 저는 BFG 리포 클리너의 저자입니다.
추천합니다 이 스크립트 David Underhill에 의해, 나에게 매력처럼 일했습니다.
이 명령을 추가하여 Natacado의 필터 브랜치를 추가하여 뒤에 남겨진 혼란을 정리합니다.
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
전체 대본 (David Underhill에 대한 모든 크레딧)
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we're at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter \
"git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch
# otherwise leaves behind for a long time
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune
마지막 두 명령이 다음으로 변경되면 더 잘 작동 할 수 있습니다.
git reflog expire --expire=now --all && \
git gc --aggressive --prune=now
GitHub로 밀면 힘을 누르지 않아도되면 저장소를 삭제하거나 연락처가 지원합니다.
그 후 1 초를 강제로 푸시하더라도 아래에 설명 된대로 충분하지 않습니다.
유일한 유효한 행동 과정은 다음과 같습니다.
비밀번호와 같은 변하기 쉬운 자격 증명이 누출 되었습니까?
- 예 : 암호를 즉시 수정하고 더 많은 OAUTH 및 API 키 사용을 고려하십시오!
아니요 (알몸 사진) :
저장소의 모든 문제가 핵무기에 빠지면 신경 쓰나요?
- 아니오 : 저장소를 삭제합니다
예:
- 연락처 지원
- 누출이 당신에게 매우 중요하다면, 유출 가능성이 줄어들 기 위해 리포지토리 가동 중지 시간을 기꺼이받을 수있는 시점까지 비공개로 만드십시오 Github 지원을 기다리는 동안 답장을 드리겠습니다.
두 번째 후에 강제를 밀어내는 힘은 충분하지 않습니다.
Github는 오랫동안 매달려 커밋을 계속합니다.
Github 직원은 연락 할 경우 그러한 매달려 커밋을 삭제할 수있는 힘이 있습니다.
나는이 손을 처음 경험했다 모든 github 커밋 이메일을 리포에 업로드했습니다 그들은 나에게 그것을 내려달라고 부탁했고, 나는 그랬고 그들은
gc
. 데이터가 포함 된 요청을 당기십시오 그러나 삭제해야합니다:이 repo 데이터는 이로 인해 초기 테이크 다운 이후 1 년까지 액세스 할 수있었습니다.매달려 커밋은 다음을 통해 볼 수 있습니다.
- Commit Web UI : https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (웨이 백 머신)
- API : https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092BBB59F2FAA34EBA15CD89EF8E83 (웨이 백 머신)
해당 커밋에서 소스를 얻는 편리한 방법 중 하나는 다운로드 zip 메소드를 사용하는 것입니다. 이는 참조를 수락 할 수 있습니다. https://github.com/cirosantilli/myrepo/archive/sha.zip
누락 된 SHA를 다음과 같이 가져올 수 있습니다.
- API 이벤트 나열
type": "PushEvent"
. 예 : 광산 : https://api.github.com/users/cirosantilli/events/public (웨이 백 머신) - 더 편리하게, 컨텐츠를 제거하려는 풀 요청의 Shas를 보면
- API 이벤트 나열
스크랩퍼가 있습니다 http://ghtorrent.org/ 그리고 https://www.githubarchive.org/ 그것은 정기적으로 Github 데이터를 풀고 다른 곳에 저장합니다.
그들이 실제 커밋 Diff를 긁어 내는지 여부를 찾을 수 없었고, 데이터가 너무 많을 가능성은 거의 없지만 기술적으로 가능하며 NSA와 친구들은 사람과 연결된 물건 만 보관하거나 관심을 끌 수있는 필터를 가지고있을 것입니다.
그러나 강제 푸시 대신 저장소를 삭제하면 Commits는 즉시 API에서 사라지고 404를 제공합니다. https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2d653f7a3824 같은 이름으로 다른 저장소를 재현하더라도 작동합니다.
이것을 테스트하기 위해 Repo를 만들었습니다. https://github.com/cirosantilli/test-dangling 그리고 그랬습니다 :
git init
git remote add origin git@github.com:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
또한보십시오: Github에서 매달려 커밋을 제거하는 방법?
명확하게 말해서 : 받아 들여진 대답이 정확합니다. 먼저 시도하십시오. 그러나 일부 사용 사례에 대해 불필요하게 복잡 할 수 있습니다. 특히 'Fatal : Bad Revision-Prune-empty'와 같은 불쾌한 오류가 발생하거나 실제로 repo의 역사에 신경 쓰지 않는 경우.
대안은 다음과 같습니다.
- CD는 프로젝트의 기본 지점입니다
- 민감한 코드 / 파일을 제거하십시오
- rm -rf .git/ # 코드에서 모든 git 정보를 제거하십시오.
- Github로 이동하여 저장소를 삭제하십시오
- 이 안내서를 따라 코드를 평소와 같이 새 저장소로 푸시하십시오.https://help.github.com/articles/adding-an-project-to-github-using-the-command-line/
이것은 물론 모든 커밋 기록 지점과 Github Repo와 Local Git Repo의 문제를 제거 할 것입니다. 이것이 용납 할 수없는 경우 대체 접근 방식을 사용해야합니다.
이것을 핵 옵션이라고 부릅니다.
여기 Windows의 솔루션이 있습니다
git 필터 브랜치-트리 필터 "rm -f 'filedir/filename'"헤드
git 푸시 -포스
경로가 올바른지 확인하십시오. 그렇지 않으면 작동하지 않습니다.
도움이되기를 바랍니다
사용 필터 브랜치:
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all
git push origin *branch_name* -f
당신이 사용할 수있는 git forget-blob
.
사용법은 매우 간단합니다 git forget-blob file-to-forget
. 여기에서 더 많은 정보를 얻을 수 있습니다
그것은 당신의 역사, 반사, 태그 등의 모든 커밋에서 사라질 것입니다.
나는 때때로 같은 문제를 겪고 있으며,이 게시물과 다른 사람들로 돌아와야 할 때마다 프로세스를 자동화 한 이유입니다.
스택 오버플로 (Stack Overflow)의 기고자들에게 크레딧을 만들어 냈습니다.
나는 이것을 몇 번해야 할 일을해야했다. 이것은 한 번에 1 파일에서만 작동합니다.
파일을 수정 한 모든 커밋 목록을 받으십시오. 하단에있는 것은 첫 번째 커밋입니다.
git log --pretty=oneline --branches -- pathToFile
히스토리에서 파일을 제거하려면 첫 번째 Commit SHA1과 이전 명령에서 파일로가는 경로를 사용 하여이 명령으로 채우십시오.
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
따라서 다음과 같이 보입니다.
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
git에서 추적 된 파일의 캐시를 제거하고 해당 파일을 추가하십시오.
.gitignore
목록
내 안드로이드 프로젝트에서 나는 가지고 있었다 Admob_keys.xml 분리 된 XML 파일로 앱/src/main/res/values/ 폴더. 이 민감한 파일을 제거하기 위해 아래 스크립트를 사용하고 완벽하게 작동했습니다.
git filter-branch --force --index-filter \
'git rm --cached --ignore-unmatch app/src/main/res/values/admob_keys.xml' \
--prune-empty --tag-name-filter cat -- --all