GIT: كيفية إزالة الملف من الفهرس دون حذف الملفات من أي مستودع

StackOverflow https://stackoverflow.com/questions/2604625

سؤال

عندما تستخدم

git rm --cached myfile

لا يحذف من نظام الملفات المحلي ، وهو الهدف. ولكن إذا قمت بالفعل بإصدار الملف وارتكبته ، ودفعته إلى مستودع مركزي ، وسحبته إلى مستودع آخر قبل استخدام الأمر ، فسوف يحذف الملف من هذا النظام.

هل هناك طريقة لإزالة الملف فقط من الإصدار دون حذفه من أي نظام ملفات؟

تحرير: موضح ، آمل.

هل كانت مفيدة؟

المحلول

لا أعتقد أن الالتزام git يمكن أن يسجل نية مثل "التوقف عن تتبع هذا الملف ، ولكن لا تحذفه".

سيتطلب سن مثل هذه النية تدخلًا خارج GIT في أي مستودعات تندمج (أو Rebase على) الالتزام الذي يحذف الملف.


احفظ نسخة ، تطبيق الحذف ، استعادة

ربما يكون أسهل شيء القيام به هو إخبار المستخدمين في اتجاه مجرى النهر بحفظ نسخة من الملف ، وسحب الحذف الخاص بك ، ثم استعادة الملف. إذا كانوا يسحبون عبر Rebase وهم "يحملون" تعديلات على الملف ، فسيحصلون على تعارضات. لحل هذه النزاعات ، والاستخدام git rm foo.conf && git rebase --continue (إذا كان الالتزام المتضارب لديه تغييرات إلى جانب تلك الموجودة في الملف الذي تمت إزالته) أو git rebase --skip (إذا كان الالتزام المتضارب قد تغير فقط إلى الملف الذي تمت إزالته).

استعادة الملف كما لم يتم التخلص منه بعد سحب التزام يحذفه

إذا قاموا بالفعل بسحب التزام الحذف الخاص بك ، فلا يزال بإمكانهم استرداد الإصدار السابق من الملف عرض git:

git show @{1}:foo.conf >foo.conf

أو مع Git Checkout (لكل تعليق من قبل وليام Pursell ؛ لكن تذكر إعادة إضاءةه من الفهرس!):

git checkout @{1} -- foo.conf && git rm --cached foo.conf

إذا اتخذوا إجراءات أخرى منذ سحب الحذف (أو أنهم يسحبون مع Rebase إلى رأس منفصل) ، فقد يحتاجون إلى شيء آخر غير @{1}. يمكنهم استخدام git log -g للعثور على الالتزام قبل سحب الحذف.


في تعليق ، ذكرت أن الملف الذي تريد "إلغاء التركيب ، ولكن Keep" هو نوع من ملف التكوين المطلوب لتشغيل البرنامج (مباشرة خارج المستودع).

احتفظ بالملف كـ "افتراضي" وقم بتنشيته يدويًا/تلقائيًا

إذا لم يكن من غير المقبول تمامًا الاستمرار في الحفاظ على محتوى ملف التكوين في المستودع ، فقد تتمكن من إعادة تسمية الملف المسار من (على سبيل المثال) foo.conf ل foo.conf.default ثم قم بتوجيه المستخدمين إلى cp foo.conf.default foo.conf بعد تطبيق التزام إعادة تسمية. أو ، إذا كان المستخدمون يستخدمون بالفعل جزءًا موجودًا من المستودع (مثل البرنامج النصي أو برنامج آخر تم تكوينه بواسطة المحتوى في المستودع (على سبيل المثال Makefile أو ما شابه)) لإطلاق/نشر البرنامج الخاص بك ، يمكنك دمج آلية التخلف عن السداد في عملية الإطلاق/النشر:

test -f foo.conf || test -f foo.conf.default &&
    cp foo.conf.default foo.conf

مع وجود آلية التخلف عن السداد ، يجب أن يكون المستخدمون قادرين على سحب الالتزام الذي يعيد تسمية foo.conf ل foo.conf.default دون الحاجة إلى القيام بأي عمل إضافي. أيضًا ، يمكنك تجنب الاضطرار إلى نسخ ملف التكوين يدويًا إذا قمت بإجراء تثبيت/مستودعات إضافية في المستقبل.

تتطلب إعادة كتابة التاريخ تدخلًا يدويًا على أي حال ...

إذا كان من غير المقبول الحفاظ على المحتوى في المستودع ، فمن المحتمل أن ترغب في القضاء عليه تمامًا من التاريخ بشيء مثل git filter-branch --index-filter …. هذا يرقى إلى إعادة كتابة التاريخ ، والذي سيتطلب تدخلًا يدويًا لكل فرع/مستودع (انظر قسم "التعافي من Rebase" في جيت ريباس manpage). سيكون المعاملة الخاصة المطلوبة لملف التكوين الخاص بك مجرد خطوة أخرى يجب على المرء القيام بها أثناء التعافي من إعادة الكتابة:

  1. احفظ نسخة من ملف التكوين.
  2. تعافى من إعادة الكتابة.
  3. استعادة ملف التكوين.

تجاهلها لمنع التكرار

مهما كانت الطريقة التي تستخدمها ، فربما تريد تضمين اسم ملف التكوين في أ .gitignore ملف في المستودع حتى لا يستطيع أحد عن غير قصد git add foo.conf مرة أخرى (ممكن ، لكنه يتطلب -f/--force). إذا كان لديك أكثر من ملف تكوين واحد ، فقد تفكر في "نقلهم" جميعًا إلى دليل واحد وتجاهل كل شيء (عن طريق "التحرك" يعني تغيير المكان الذي يتوقع فيه البرنامج العثور على ملفات التكوين الخاصة به ، والحصول على المستخدمين (أو آلية الإطلاق/النشر) لنسخ/نقل الملفات إلى موقعها الجديد ؛ من الواضح أنك لن ترغب في ذلك git mv ملف في دليل ستتجاهله).

نصائح أخرى

كان لديك نفس المشكلة هذا الأسبوع عندما ارتكبت بطريق الخطأ ، ثم حاولت إزالة ملف إنشاء من مستودع مشترك ، وهذا:

http://gitready.com/intermediate/2009/02/18/temporialy-ignoring-files.html

عملت بشكل جيد بالنسبة لي ولم يذكر حتى الآن.

git update-index --assume-unchanged <file>

لإزالة الملف الذي تهتم به من التحكم في الإصدار ، ثم استخدم جميع أوامرك الأخرى كالمعتاد.

git update-index --no-assume-unchanged <file>

إذا كنت ترغب في إعادته.

تحرير: يرجى الاطلاع على تعليقات من Chris Johnsen و KPM ، وهذا يعمل محليًا فقط ويظل الملف ضمن التحكم في الإصدار للمستخدمين الآخرين إذا لم يفعلوا ذلك أيضًا. تعطي الإجابة المقبولة أساليب أكثر اكتمالا/صحيحة للتعامل مع هذا. أيضا بعض الملاحظات من الرابط إذا كنت تستخدم هذه الطريقة:

من الواضح أن هناك عددًا قليلاً من التحذيرات التي تلعب دورها مع هذا. إذا قمت بإضافة الملف مباشرة ، فسيتم إضافته إلى الفهرس. إن دمج الالتزام بهذا العلم سيؤدي إلى فشل الدمج بأمان حتى تتمكن من التعامل معه يدويًا.

لإزالة الملف من الفهرس ، استخدم:

git reset myfile

لا ينبغي أن يؤثر هذا على نسختك المحلية أو أي شخص آخر.

بعد القيام به git rm --cached الأمر ، حاول إضافة myfile إلى .gitignore ملف (إنشاء واحد إذا لم يكن موجودًا). هذا يجب أن يخبر Git بالتجاهل myfile.

ال .gitignore يتم إصدار الملف ، لذلك ستحتاج إلى ارتكابه ودفعه إلى المستودع البعيد.

  1. git rm --cached remove_file
  2. أضف ملفًا إلى Gitignore
  3. git add .gitignore
  4. git commit -m "Excluding"
  5. استمتع ؛)

الحل الخاص بي هو سحب نسخة العمل الأخرى ثم القيام بها:

git log --pretty="format:" --name-only -n1 | xargs git checkout HEAD^1

الذي يقول الحصول على جميع مسارات الملفات في أحدث تعليق ، وتحقق منها من والد الرأس. تم انجاز العمل.

الحلول أعلاه تعمل بشكل جيد لمعظم الحالات. ومع ذلك ، إذا كنت بحاجة أيضًا إلى إزالة جميع آثار هذا الملف (أي البيانات الحساسة مثل كلمات المرور) ، فستحتاج أيضًا إلى إزالته من تاريخ الالتزام بأكمله ، حيث لا يزال من الممكن استرداد الملف من هناك.

فيما يلي حل يزيل جميع آثار الملف من تاريخ الالتزام بأكمله ، كما لو أنه لم يكن موجودًا أبدًا ، ومع ذلك يحافظ على الملف في نظامك.

https://help.github.com/articles/remove-sensitive-data/

يمكنك بالفعل الانتقال إلى الخطوة 3 إذا كنت في مستودع GIT المحلي ، ولا تحتاج إلى إجراء تشغيل جاف. في حالتي ، كنت بحاجة فقط إلى الدرجة 3 و 6 ، حيث قمت بالفعل بإنشاء ملف .gitignore الخاص بي ، وكنت في المستودع الذي أردت العمل عليه.

لرؤية التغييرات الخاصة بك ، قد تحتاج إلى الذهاب إلى جذر github من المستودع الخاص بك وتحديث الصفحة. ثم انتقل عبر الروابط للوصول إلى التزام قديم كان لديه الملف ذات مرة ، لترى أنه تمت إزالته الآن. بالنسبة لي ، ببساطة تحديث صفحة الالتزام القديمة لم تظهر التغيير.

بدا الأمر مخيفًا في البداية ، ولكن في الحقيقة ، كان سهلاً وعمل مثل سحر! :-)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top