سؤال

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

أعرف أنه إذا كنت تستخدم git stash ثم .بوابة/الحكام/مخبأ يحتوي على الإشارة ارتكاب المستخدمة لإنشاء خبأ.و .بوابة/سجلات/الحكام/مخبأ يحتوي على كلها خبا.ولكن هذه الإشارات قد ولت بعد git stash pop.وأنا أعلم أن الالتزام لا يزال في مستودع في مكان ما, ولكن أنا لا أعرف ما كان عليه.

هل هناك طريقة سهلة لاستعادة أمس خبأ ارتكاب مرجع ؟

لاحظ أن هذه ليست حاسمة بالنسبة لي اليوم لأن لدي النسخ الاحتياطي اليومي و يمكن العودة إلى الأمس شجرة العمل على التغييرات.أنا أسأل لأنه يجب أن يكون هناك طريقة أسهل!

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

المحلول

بمجرد أن تعرف تجزئة خبأ ارتكاب أسقطت ، يمكنك تطبيقه كما خبأ:

git stash apply $stash_hash

أو يمكنك إنشاء فرع مستقل مع

git branch recovered $stash_hash

بعد ذلك يمكنك أن تفعل ما تريد مع كل أداة عادي.عند الانتهاء من ذلك, مجرد ضربة فرع بعيدا.

العثور على تجزئة

إذا كان لديك فقط برزت و المحطة لا تزال مفتوحة ، سوف لا تزال لديها تجزئة القيمة المطبوعة من قبل git stash pop على الشاشة (شكرا ، Dolda).

وإلا, يمكنك العثور عليه باستخدام هذه لينكس, يونكس أو جيت باش ويندوز:

git fsck --no-reflog | awk '/dangling commit/ {print $3}'

أو باستخدام Powershell ويندوز:

git fsck --no-reflog | select-string 'dangling commit' | foreach { $bits = $_ -split ' '; echo $bits[2];}

هذا وسوف تظهر لك جميع يرتكب على نصائح من ارتكاب الرسم البياني التي لم تعد المشار إليها من أي فرع أو الوسم – كل المفقودة ارتكابها ، بما في ذلك كل خبأ ارتكاب كنت قد أي وقت مضى خلق ، سوف يكون في مكان ما في هذا الرسم البياني.

أسهل طريقة للعثور على مخبأ ارتكاب تريد على الأرجح لتمرير تلك القائمة إلى gitk:

gitk --all $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' )

أو ترى ... الجواب من emragins إذا باستخدام Powershell ويندوز.

هذا وسوف إطلاق مستودع المتصفح يظهر لك كل واحد يرتكب في مستودع من أي وقت مضى, بغض النظر عن ما إذا كان يمكن الوصول إليه أو لا.

يمكنك استبدال gitk هناك مع شيء من هذا القبيل git log --graph --oneline --decorate إذا كنت تفضل لطيفة الرسم البياني على وحدة التحكم أكثر منفصل واجهة التطبيق.

إلى بقعة خبأ يرتكب البحث عن ارتكاب رسائل من هذا النموذج:

WIP على somebranch: commithash قديمة ارتكاب رسالة

ملاحظة:رسالة الاعتماد سيكون فقط في هذا الشكل (بدءا من "WIP على") إذا لم تقدم رسالة عندما كنت فعلت git stash.

نصائح أخرى

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

$ git stash pop
[...]
Dropped refs/stash@{0} (2ca03e22256be97f9e40f08e6d6773c7d41dbfd1)

(لاحظ أن git stash drop كما تنتج نفس الخط.)

للحصول على هذا المخبأ مرة أخرى ، git branch tmp 2cae03e, و ستحصل على أنها فرع.لتحويل هذا إلى كمية تشغيل:

git stash apply tmp
git stash

بعد ذلك كفرع أيضا يسمح لك لمعالجة ذلك بحرية ؛ على سبيل المثال ، أن ينتقي أو دمجها.

أردت فقط أن أذكر هذا بالإضافة إلى حل مقبول.لم تكن واضحة بالنسبة لي أول مرة حاولت هذه الطريقة (ربما كان ينبغي أن يكون) ، ولكن تطبيق خبأ من تجزئة القيمة, مجرد استخدام "بوابة خبأ تطبيق ":

$ git stash apply ad38abbf76e26c803b27a6079348192d32f52219

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

للحصول على قائمة من مخابئ التي لا تزال في المستودع الخاص بك ولكن لا يمكن الوصول إلى أي أكثر من ذلك:

git fsck --unreachable | grep commit | cut -d" " -f3 | xargs git log --merges --no-walk --grep=WIP

إذا أعطى عنوانا خبأ الخاص بك استبدال "WIP" في -grep=WIP في نهاية الأمر جزء من الرسالة الخاصة بك ، على سبيل المثال -grep=Tesselation.

الأمر grepping ل "WIP" لأن الافتراضي ارتكاب رسالة خبأ في شكل WIP on mybranch: [previous-commit-hash] Message of the previous commit.

لقد شيدت الأمر الذي ساعدني في العثور على بلدي فقد خبأ ارتكاب:

for ref in `find .git/objects | sed -e 's#.git/objects/##' | grep / | tr -d /`; do if [ `git cat-file -t $ref` = "commit" ]; then git show --summary $ref; fi; done | less

هذه القوائم جميع الكائنات في .بوابة/الكائنات شجرة يحدد تلك التي هي من نوع يرتكبون ثم يظهر ملخص لكل واحد.من هذه النقطة كان مجرد مسألة يبحث من خلال يرتكب العثور على عرض مناسب "WIP على العمل:6a9bb2" ("العمل" فرع بلدي ، 619bb2 الأخيرة لارتكاب).

أنا ملاحظة أنه إذا كنت تستخدم "بوابة خبأ تطبيق" بدلا من "بوابة خبأ البوب" لن يكون هذا مشكلة إذا كنت تستخدم "بوابة خبأ حفظ الرسالة"ثم ارتكاب قد يكون من الأسهل العثور على.

تحديث:مع ناثان فكرة هذا يصبح أقصر:

for ref in `git fsck --unreachable | grep commit | cut -d' ' -f3`; do git show --summary $ref; done | less

git fsck --unreachable | grep commit يجب أن تظهر sha1, على الرغم من أنها قائمة العوائد قد تكون كبيرة جدا. git show <sha1> سوف تظهر إذا كان ارتكاب تريد.

git cherry-pick -m 1 <sha1> سيتم دمج لارتكاب على فرع الحالية.

إذا كنت ترغب في restash فقدت خبأ, تحتاج إلى العثور على تجزئة فقد خبأ الأولى.

كما أرسطو Pagaltzis اقترح git fsck وينبغي أن تساعدك.

شخصيا أستخدم log-all الاسم المستعار التي تظهر لي كل ارتكاب (قابلة للاسترداد يرتكب) أن يكون أفضل من الوضع :

git log --graph --decorate --pretty=oneline --abbrev-commit --all $(git fsck --no-reflogs | grep commit | cut -d' ' -f3)

يمكنك أن تفعل حتى البحث أسرع إذا كنت تبحث فقط عن "WIP على" الرسائل.

بمجرد أن تعرف الخاص بك sha1, يمكنك ببساطة تغيير خبأ الخاص بك reflog لإضافة الأشياء القديمة :

git update-ref refs/stash ed6721d

عليك ربما تفضل أن يكون بها الرسالة حتى -m

git update-ref -m "$(git log -1 --pretty=format:'%s' ed6721d)" refs/stash ed6721d

وسوف تحتاج حتى إلى استخدام هذا الاسم المستعار :

restash = !git update-ref -m $(git log -1 --pretty=format:'%s' $1) refs/stash $1

Windows PowerShell ما يعادل باستخدام gitk:

gitk --all $(git fsck --no-reflog | Select-String "(dangling commit )(.*)" | %{ $_.Line.Split(' ')[2] })

ربما هناك طريقة أكثر كفاءة للقيام بذلك في أحد الأنابيب ، ولكن هذا لا وظيفة.

أحببت أرسطو النهج ، ولكن لم يكن مثل استخدام GITK...كما اعتدت على استخدام بوابة من سطر الأوامر.

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

git show $( git fsck --no-reflog | awk '/dangling commit/ {print $3}' ) > ~/stash_recovery.diff

الآن يمكنك تحميل ما يصل الناتج مهرجان دبي السينمائي الدولي/ملف txt (في مجلد المنزل) إلى txt محرر ترى رمز الفعلي و مما شاء.

ثم مجرد استخدام

git stash apply ad38abbf76e26c803b27a6079348192d32f52219

في OSX مع بوابة v2.6.4, أنا فقط تشغيل بوابة خبأ قطرة عن طريق الخطأ ، ثم وجدت ذلك عن طريق الذهاب الحوض الخطوات التالية

إذا كنت تعرف اسم خبأ ثم استخدام:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show | grep -B 6 -A 2 <name of the stash>

وإلا سوف تجد معرف من النتيجة يدويا مع:

$ git fsck --unreachable | grep commit | cut -c 20- | xargs git show

ثم عندما تجد ارتكاب معرف مجرد ضرب بوابة خبأ تطبيق {لارتكاب-id}

آمل أن يساعد هذا شخص بسرعة

لماذا لا يسأل الناس هذا السؤال ؟ لأنهم لا يعرفون أو يفهمون reflog.

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

أنصح الجميع مع هذا السؤال على مجرد التحقق من reflog (بوابة reflog), ليس أكثر من ذلك بكثير.مرة واحدة ترى أن قائمة من كل ما يرتكب هناك مئات الطرق لمعرفة ما يرتكبون كنت تبحث عن انتقاء أو إنشاء فرع منه.في عملية تكون قد تعلمت عن reflog و الخيارات المفيدة في مختلف الأساسية بوابة الأوامر.

يمكنك سرد كافة قابلة للوصول يرتكب عن طريق كتابة هذا الأمر في الطرفية -

git fsck --unreachable

تحقق إليه ارتكاب التجزئة

git show hash

وأخيرا تطبيق إذا وجدت مخبأة البند -

git stash apply hash

أريد أن أضيف إلى قبول حل آخر وسيلة جيدة للذهاب من خلال جميع التغييرات عندما لا يكون gitk المتاحة أو أي X الانتاج.

git fsck --no-reflog | awk '/dangling commit/ {print $3}' > tmp_commits

for h in `cat tmp_commits`; do git show $h | less; done

ثم يمكنك الحصول على جميع بيانات الاختلاف عن تلك التجزئة عرض واحد بعد آخر.اضغط على 'س' إلى مهرجان دبي السينمائي الدولي.

الجواب المقبول من قبل أرسطو سوف تظهر يمكن الوصول إلى كل من يرتكب ، بما في ذلك غير خبأ مثل يرتكب.لتصفية الضوضاء:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3

هذا وسوف تشمل فقط يرتكب التي لديك بالضبط 3 الوالد يرتكب (الذي خبأ سوف يكون) ، والتي تتضمن رسالة "WIP على".

نضع في اعتبارنا أنه إذا كنت حفظ خبأ الخاص بك مع رسالة (مثلا ، git stash save "My newly created stash"), وهذا تجاوز الافتراضي "WIP على..." الرسالة.

يمكنك عرض المزيد من المعلومات حول ارتكاب مثلعرض ارتكاب رسالة أو تمريرها إلى git stash show:

git fsck --no-reflog | \
awk '/dangling commit/ {print $3}' | \
xargs git log --no-walk --format="%H" \
  --grep="WIP on" --min-parents=3 --max-parents=3 | \
xargs -n1 -I '{}' bash -c "\
  git log -1 --format=medium --color=always '{}'; echo; \
  git stash show --color=always '{}'; echo; echo" | \
less -R

لم أستطع الحصول على أي من الإجابات للعمل على نظام التشغيل ويندوز في أمر بسيط النوافذ (ويندوز 7 في حالتي). awk, grep و Select-string لم تكن معترف بها الأوامر.لذلك حاولت مقاربة مختلفة:

  • الجولة الأولى: git fsck --unreachable | findstr "commit"
  • نسخة الإخراج إلى المفكرة
  • العثور على محل "إليه ارتكاب" مع start cmd /k git show

سوف ننظر بشيء من هذا القبيل:

start cmd /k git show 8506d235f935b92df65d58e7d75e9441220537a4 start cmd /k git show 44078733e1b36962571019126243782421fcd8ae start cmd /k git show ec09069ec893db4ec1901f94eefc8dc606b1dbf1 start cmd /k git show d00aab9198e8b81d052d90720165e48b287c302e

  • حفظ كملف .bat الملف وتشغيله
  • السيناريو سيتم فتح مجموعة من الأوامر ويندوز ، عرض لكل ارتكاب
  • إذا كان يمكنك العثور على واحد كنت تبحث عنه ، تشغيل: git stash apply (your hash)

قد لا يكون أفضل حل ، ولكن عملت بالنسبة لي

ما جئت هنا أبحث عن كيفية الحصول على المخدرات مرة أخرى ، بغض النظر عن ما كنت قد سحبه.ولا سيما أنا قد خبأ شيئا, ثم خرج نسخة قديمة ، ثم تسليط هذا ، ولكن خبأ كان لا-op في وقت سابق نقطة ، حتى خبأ اختفى ، لم أستطع القيام به git stash لدفعها مرة أخرى على المكدس.هذا العمل بالنسبة لي:

$ git checkout somethingOld
$ git stash pop
...
nothing added to commit but untracked files present (use "git add" to track)
Dropped refs/stash@{0} (27f6bd8ba3c4a34f134e12fe69bf69c192f71179)
$ git checkout 27f6bd8ba3c
$ git reset HEAD^    # Make the working tree differ from the parent.
$ git stash # Put the stash back in the stack.
Saved working directory and index state WIP on (no branch): c2be516 Some message.
HEAD is now at c2be516 Some message.
$ git checkout somethingOld # Now we are back where we were.

في وقت لاحق, يجب أن يكون لديك تم استخدام git stash apply لا git stash pop.أنا كنت أفعل bisect وكان القليل من التصحيح أن أردت أن تطبق في كل bisect الخطوة.الآن أنا أفعل هذا:

$ git reset --hard; git bisect good; git stash apply
$ # Run tests
$ git reset --hard; git bisect bad; git stash apply
etc.

تعافى باستخدام الخطوات التالية:

  1. التعرف على حذف خبأ hash code:

    gitk-كل $( بوابة fsck-لا-reflog | awk '/التعلق الالتزام/ {print $3}' )

  2. الكرز اختيار خبأ:

    بوابة الكرز-اختيار -م 1 $stash_hash_code

  3. حل النزاعات إن وجدت باستخدام:

    بوابة mergetool

بالإضافة إلى ذلك قد يكون وجود مشاكل مع ارتكاب رسالة إذا كنت تستخدم غيريت.يرجى خبأ التغييرات قبل التالية البدائل:

  1. استخدام إعادة تعيين ثابت السابقة لارتكاب ثم نلزم هذا التغيير.
  2. أيضا قد خبأ التغيير ، ريبس إلزام.

لم بالصدفه إزالة خبأ في GitUP التطبيق.فقط اضغط على Ctrl+Z التراجع عن ذلك.

ربما يساعد شخص ما ;)

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