문제

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 지원을 기다리는 동안 답장을 드리겠습니다.

두 번째 후에 강제를 밀어내는 힘은 충분하지 않습니다.

그러나 강제 푸시 대신 저장소를 삭제하면 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의 역사에 신경 쓰지 않는 경우.

대안은 다음과 같습니다.

  1. CD는 프로젝트의 기본 지점입니다
  2. 민감한 코드 / 파일을 제거하십시오
  3. rm -rf .git/ # 코드에서 모든 git 정보를 제거하십시오.
  4. Github로 이동하여 저장소를 삭제하십시오
  5. 이 안내서를 따라 코드를 평소와 같이 새 저장소로 푸시하십시오.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. 여기에서 더 많은 정보를 얻을 수 있습니다

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

그것은 당신의 역사, 반사, 태그 등의 모든 커밋에서 사라질 것입니다.

나는 때때로 같은 문제를 겪고 있으며,이 게시물과 다른 사람들로 돌아와야 할 때마다 프로세스를 자동화 한 이유입니다.

스택 오버플로 (Stack Overflow)의 기고자들에게 크레딧을 만들어 냈습니다.

나는 이것을 몇 번해야 할 일을해야했다. 이것은 한 번에 1 파일에서만 작동합니다.

  1. 파일을 수정 한 모든 커밋 목록을 받으십시오. 하단에있는 것은 첫 번째 커밋입니다.

    git log --pretty=oneline --branches -- pathToFile

  2. 히스토리에서 파일을 제거하려면 첫 번째 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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top