قم بإزالة الملفات الحساسة ورباطها من تاريخ GIT
-
22-08-2019 - |
سؤال
أرغب في وضع مشروع GIT على GitHub ولكنه يحتوي على ملفات معينة ذات بيانات حساسة (أسماء المستخدمين وكلمات المرور ، مثل /config/deploy.rb لـ Capistrano).
أعلم أنه يمكنني إضافة أسماء الملفات هذه إلى .gitignore, ، لكن هذا لن يزيل تاريخهم داخل غيت.
أنا أيضًا لا أريد أن أبدأ من جديد عن طريق حذف دليل /.
هل هناك طريقة لإزالة الكل آثار ملف معين في تاريخ git الخاص بك؟
المحلول
لجميع الأغراض العملية ، أول الشيء الذي يجب أن تقلق بشأنه هو تغيير كلمات المرور الخاصة بك! ليس من الواضح من سؤالك ما إذا كان مستودع GIT الخاص بك محليًا تمامًا أو ما إذا كان لديك مستودع بعيد في مكان آخر حتى الآن ؛ إذا كانت بعيدة ولم يتم تأمينها من الآخرين ، فأنت تواجه مشكلة. إذا استنساخ أي شخص هذا المستودع قبل إصلاح هذا ، فسيحصل على نسخة من كلمات المرور الخاصة بك على جهازه المحلي ، ولا توجد طريقة لإجباره على التحديث إلى إصدار "ثابت" معه من التاريخ. الشيء الآمن الوحيد الذي يمكنك القيام به هو تغيير كلمة المرور الخاصة بك إلى شيء آخر في كل مكان استخدمته.
مع ذلك بعيدًا ، إليك كيفية إصلاحه. أجاب جيثب على هذا السؤال بالضبط باعتباره الأسئلة الشائعة:
ملاحظة لمستخدمي 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 وآخرون استنساخوا هذا المستودع البعيد ، فأنت الآن في موقف تقوم فيه بإعادة كتابة التاريخ. عندما يحاول الآخرون سحب التغييرات الأخيرة بعد ذلك ، سيحصلون على رسالة تشير إلى أنه لا يمكن تطبيق التغييرات لأنها ليست سريعة.
لإصلاح هذا ، سيتعين عليهم إما حذف مستودعهم الحالي وإعادة النقر عليه ، أو اتباع التعليمات تحت "التعافي من Rebase في المنبع" في 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 Repo-Cleaner, بديل أسرع وأبسط عن git-filter-branch
مصمم بشكل صريح لإزالة البيانات الخاصة من GIT Repos.
إنشاء private.txt
الملف يسرد كلمات المرور ، إلخ ، التي تريد إزالتها (إدخال واحد لكل سطر) ثم قم بتشغيل هذا الأمر:
$ java -jar bfg.jar --replace-text private.txt my-repo.git
سيتم فحص جميع الملفات تحت حجم العتبة (1 ميجابايت افتراضيًا) آخر سيتم استبدال الالتزام) بالسلسلة "*** تمت إزالتها ***". يمكنك بعد ذلك الاستخدام git gc
لتنظيف البيانات الميتة:
$ git gc --prune=now --aggressive
عادة ما يكون BFG أسرع 10-50x من الركض git-filter-branch
ويتم تبسيط الخيارات وتصميمها حول هذين الحالات الشائعة:
- إزالة ملفات كبيرة مجنونة
- إزالة كلمات المرور ، بيانات الاعتماد & آخر بيانات خاصة
الإفصاح الكامل: أنا مؤلف كتاب BFG Repo-Cleaner.
انصح هذا السيناريو بقلم ديفيد أندرهيل ، عمل مثل سحر بالنسبة لي.
يضيف هذه الأوامر بالإضافة إلى فرع مرشح Natacado لتنظيف الفوضى التي يتركها وراءها:
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
السيناريو الكامل (كل الائتمان لديفيد أندرهيل)
#!/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 ، فإن القوة لا تكون كافية ، قم بحذف المستودع أو دعم الاتصال
حتى لو كنت تجبر الدفع بعد ثانية واحدة ، فهذا لا يكفي كما هو موضح أدناه.
المسارات الوحيدة الصالحة للعمل هي:
هل تسرب بيانات اعتماد قابلة للتغيير مثل كلمة المرور؟
- نعم: قم بتعديل كلمات المرور الخاصة بك على الفور ، وفكر في استخدام المزيد من مفاتيح Oauth و API!
لا (صور عارية):
هل تهتم إذا حصلت جميع المشكلات في المستودع على قناة نووية؟
- لا: حذف المستودع
نعم:
- اتصل بالدعم
- إذا كان التسرب أمرًا بالغ الأهمية بالنسبة لك ، لدرجة أنك على استعداد للحصول على بعض وقت تعطل المستودع لجعله أقل عرضة للتسرب ، اجعلها خاصة بينما تنتظر دعم جيثب للرد عليك
إن دفع دفع ثانية في وقت لاحق لا يكفي لأن:
Github يحافظ على التداخل الالتزامات لفترة طويلة.
يتمتع موظفو GitHub بسلطة حذف هذه الالتزامات المتدلية إذا اتصلت بهم.
لقد واجهت هذا مباشرة عندما أنا تم تحميل جميع رسائل البريد الإلكتروني الالتزام بـ GitHub لإلى الريبو طلبوا مني أن أسقطها ، هكذا فعلت ، وفعلوا أ
gc
. سحب الطلبات التي تحتوي على البيانات ومع ذلك ، يجب حذفها: ظلت بيانات الريبو متاحة لمدة تصل إلى عام واحد بعد الإزالة الأولية بسبب هذا.يمكن رؤية الالتزامات المتدنية إما من خلال:
- واجهة المستخدم على شبكة الإنترنت الالتزام: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (آلة Wayback)
- واجهة برمجة التطبيقات: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (آلة Wayback)
إحدى الطرق المريحة للحصول على المصدر في هذا الالتزام ثم تتمثل في استخدام طريقة تنزيل zip ، والتي يمكن أن تقبل أي مرجع ، على سبيل المثال: https://github.com/cirosantilli/myrepo/archive/sha.zip
من الممكن جلب Shas المفقود إما عن طريق:
- سرد أحداث API مع
type": "PushEvent"
. على سبيل المثال الألغام: https://api.github.com/users/cirosantilli/events/public (آلة Wayback) - في بعض الأحيان بشكل أكثر ملاءمة ، من خلال النظر إلى طلبات السحب التي حاولت إزالة المحتوى
- سرد أحداث API مع
هناك خربز مثل http://ghtorrent.org/ و https://www.githubarchive.org/ أن تجمع بيانات github بانتظام وتخزينها في مكان آخر.
لم أتمكن من العثور على ما إذا كانوا يتخلصون من اختلاف الالتزام الفعلي ، وهذا غير مرجح لأنه سيكون هناك الكثير من البيانات ، لكن من الممكن تقنيًا ، ومن المحتمل أن يكون لدى NSA والأصدقاء عوامل ترشيح لأرشفة الأشياء المرتبطة بالأشخاص أو الاهتمامات ذات الاهتمام.
إذا قمت بحذف المستودع بدلاً من مجرد قوة الدفع ، فإن الالتزامات تختفي حتى من واجهة برمجة التطبيقات على الفور وتعطي 404 ، على سبيل المثال https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2d653f7a3824 هذا يعمل حتى لو قمت بإعادة إنشاء مستودع آخر بنفس الاسم.
لاختبار هذا ، قمت بإنشاء ريبو: 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
أنظر أيضا: كيفية إزالة الالتزام المتدلي من جيثب؟
لتوضيح: الإجابة المقبولة صحيحة. جربه أولاً. ومع ذلك ، قد يكون الأمر معقدًا بشكل غير ضروري بالنسبة لبعض حالات الاستخدام ، خاصة إذا واجهت أخطاء بغيضة مثل "القاتل: المراجعة السيئة-الإرهاق" ، أو لا تهتم حقًا بتاريخ إعادة الريبو الخاص بك.
سيكون بديل:
- قرص مضغوط إلى فرع الأساس للمشروع
- قم بإزالة الكود / الملف الحساس
- RM -RF .GIT/ # قم بإزالة جميع معلومات GIT من التعليمات البرمجية الخاصة بك
- انتقل إلى github وحذف مستودعك
- اتبع هذا الدليل لدفع الكود الخاص بك إلى مستودع جديد كما تفعل عادة -https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
سيؤدي ذلك بالطبع إلى إزالة جميع فروع التاريخ الالتزام ، والمشكلات من كل من Github Repo ، وإعادة ريبو GIT المحلية. إذا كان هذا غير مقبول ، فسيتعين عليك استخدام نهج بديل.
نسمي هذا الخيار النووي.
هذا هو الحل في Windows
GIT Filter-Branch-TREE-FILTER "RM -F 'Filedir/Filename" "Head"
دفع 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 التي سمحت لي بوضع هذا معًا
اضطررت للقيام بذلك عدة مرات حتى الآن. لاحظ أن هذا يعمل فقط على ملف واحد في وقت واحد.
احصل على قائمة بجميع الالتزامات التي قامت بتعديل الملف. واحد في الأسفل سوف الالتزام الأول:
git log --pretty=oneline --branches -- pathToFile
لإزالة الملف من السجل ، استخدم الالتزام الأول 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
قائمة
في مشروع Android الخاص بي كان لدي addob_keys.xml كما منفصل ملف XML في APP/SRC/MAIN/RES/DAWER مجلد. لإزالة هذا الملف الحساس الذي استخدمته أدناه البرنامج النصي وعملت بشكل مثالي.
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