git - لاين - كيفية استرجاع الملفات المحذوفة من الكمبيوتر ويندوز 7 بعد الفورمات




البحث عن واستعادة ملف محذوف في مستودع Git (14)

git undelete path/to/file.ext

  1. ضع هذا في .bash_profile (أو أي ملف آخر ذي صلة يتم تحميله عند فتح shell أمر):

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
  2. ثم استخدام:

    git undelete path/to/file.ext
    

يتحقق هذا الاسم المستعار أولاً للعثور على آخر التزام حيث يوجد هذا الملف ، ثم يقوم git الخروج من مسار هذا الملف من هذا الالتزام الأخير حيث يوجد هذا الملف. source

قل أنا في مستودع Git. أنا أحذف ملفًا وارتكب هذا التغيير. أنا مستمر في العمل وجعل بعض المزيد من الالتزام. ثم أجد أنني بحاجة لاستعادة هذا الملف.

أعلم أنه يمكنني git checkout HEAD^ foo.bar أحد الملفات باستخدام git checkout HEAD^ foo.bar ، ولكن لا أعرف حقًا متى تم حذف هذا الملف.

  1. ما هي أسرع طريقة للعثور على الالتزام الذي حذف اسم ملف معين؟
  2. ما هي أسهل طريقة لإعادة هذا الملف إلى نسخة العمل الخاصة بي؟

آمل ألا أحتاج إلى تصفح سجلاتي يدويًا ، أو التحقق من المشروع بأكمله من أجل SHA معيّن ، ثم نسخ هذا الملف يدويًا في تسجيلي الأصلي للمشروع.


  1. استخدم git log --diff-filter=D --summary للحصول على كل git log --diff-filter=D --summary التي حذف الملفات والملفات المحذوفة ؛
  2. استخدم git checkout $commit~1 filename لاستعادة الملف المحذوف.

حيث أن $commit هو قيمة الالتزام الذي وجدته في الخطوة 1 ، على سبيل المثال e4cf499627


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

أدرج جميع الإلتزامات الخاصة بهذا الملف.

git log -- path/to/file

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

git checkout {second to last commit} -- path/to/file

إذا كنت تعرف الالتزام الذي حذف الملف (الملفات) ، <SHA1_deletion> بتشغيل هذا الأمر حيث <SHA1_deletion> هو الالتزام الذي حذف الملف:

git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --

يسرد الجزء الموجود قبل توجيه الإخراج كافة الملفات التي تم حذفها في الالتزام؛ انهم جميعا الخروج من الالتزام السابق لاستعادتها.


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

git rev-list -n 1 HEAD -- <file_path>

ثم الخروج من الإصدار في الالتزام من قبل ، باستخدام الرمز الإقحام ( ^ ):

git checkout <deleting_commit>^ -- <file_path>

أو في أمر واحد ، إذا كان $file هو الملف المعني.

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

إذا كنت تستخدم zsh وتم تمكين الخيار EXTENDED_GLOB ، لن يعمل رمز الإقحام. يمكنك استخدام ~1 بدلاً من ذلك.

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"

اسمي المفضل الجديد ، استنادًا إلى answer bonyiii (upvoted) ، وإجابتي الخاصة حول " تمرير حجة إلى أمر git alias ":

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

لقد فقدت ملفًا ، تم حذفه عن طريق الخطأ قبل ارتكاب بعض الأخطاء؟
بسرعة:

git restore my_deleted_file

تفادت الأزمة.

يقترح روبرت دايلي في التعليقات الاسم المستعار التالي:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

ويضيف jegan في التعليقات :

لإعداد الاسم المستعار من سطر الأوامر ، استخدمت هذا الأمر:

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

في حالتنا قمنا بحذف الملفات عن طريق الخطأ في ارتكاب وبعضها ارتكب في وقت لاحق أدركنا خطأنا وأردت استعادة جميع الملفات التي تم حذفها ولكن ليس تلك التي تم تعديلها.

استنادًا إلى إجابة تشارلز بيلي الرائعة هنا ،

git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)

في كثير من الحالات ، قد يكون من المفيد استخدام coreutils (grep ، sed ، إلخ) بالتزامن مع Git. أنا أعرف بالفعل هذه الأدوات بشكل جيد ، ولكن GIT أقل من ذلك. إذا أردت إجراء بحث عن ملف محذوف ، فسأفعل ما يلي:

git log --raw | grep -B 30 $'D\t.*deleted_file.c'

عندما أجد التنقيح / الالتزام:

git checkout <rev>^ -- path/to/refound/deleted_file.c

مثلما ذكر آخرون قبلي.

سيتم الآن استعادة الملف إلى الحالة التي كان عليها قبل الإزالة. تذكر إعادة الارتباط بها إلى شجرة العمل إذا كنت تريد الاحتفاظ بها.


لاستعادة ملف محذوف و ملتزم:

git reset HEAD some/path
git checkout -- some/path

تم اختباره على إصدار Git 1.7.5.4.


لدي هذا الحل

  1. احصل على معرف الالتزام حيث تم حذف الملف باستخدام إحدى الطرق أدناه.

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* git log --stat | grep --context=5 *word* # recommended إذا كنت نادراً ما تتذكر أي شيء
  2. يجب أن تحصل على شيء مثل:

ارتكاب bfe68bd117e1091c96d2976c99b3bcc8310bebe7 المؤلف: ألكسندر أورلوف التاريخ: الخميس 12 مايو 23:44:27 2011 +0200

replaced deprecated GWT class
- gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

ارتكب 3ea4e3af253ac6fd1691ff6bb89c964f54802302 المؤلف: ألكسندر أورلوف التاريخ: الخميس 12 مايو 22:10:22 2011 +0200

3 . الآن باستخدام ملف الالتزام bfe68bd117e1091c96d2976c99b3bcc8310bebe7:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

نظرًا لأن معرف الالتزام يشير إلى الالتزام حيث تم حذف الملف بالفعل ، يلزمك الإشارة إلى الالتزام قبل bfe68b فقط والذي يمكنك فعله بإلحاق ^1 . هذا يعني: أعطني الالتزام قبل bfe68b.


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

git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ -- 
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD 

(لاحظ المساحة الزائدة في نهاية كل أمر.)

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


لقد جئت إلى هذا السؤال وأنا أتطلع إلى استعادة ملف قمت بحذفه للتو ، لكنني لم ألتزم بعد بالتغيير. فقط إذا وجدت نفسك في هذا الموقف ، كل ما عليك القيام به هو ما يلي:

git checkout HEAD -- path/to/file.ext


git checkout /path/to/deleted.file





git-checkout