كيف يمكنك تخزين ملف لم يتم تعقبه؟
سؤال
لقد أجريت تغييرات على ملف، بالإضافة إلى ملف جديد، وأرغب في استخدام git stash لوضعها جانبًا أثناء التبديل إلى مهمة أخرى.لكن git stash في حد ذاته يخزن فقط التغييرات التي تم إجراؤها على الملف الموجود؛ويظل الملف الجديد في شجرة العمل الخاصة بي، مما يؤدي إلى تشوش عملي المستقبلي.كيف يمكنني تخزين هذا الملف الذي لم يتم تعقبه؟
المحلول
تحديث 17 مايو 2018:
الإصدارات الجديدة من git لديها الآن git stash --all
الذي يخفي كافة الملفات، بما في ذلك الملفات التي لم يتم تعقبها والتي تم تجاهلها.
git stash --include-untracked
لم يعد يمس الملفات التي تم تجاهلها (تم اختبارها على git 2.16.2).
الإجابة الأصلية أدناه:
اعتبارا من الإصدار 1.7.7 يمكنك استخدامه git stash --include-untracked
أو git stash save -u
لتخزين الملفات التي لم يتم تعقبها دون تنظيمها.
يضيف (git add
) الملف وابدأ في تتبعه.ثم خبأ.نظرًا لأن محتويات الملف بالكامل جديدة، فسيتم تخزينها، ويمكنك معالجتها حسب الضرورة.
نصائح أخرى
اعتبارًا من البوابة 1.7.7، git stash
يقبل --include-untracked
الخيار (أو قصيرة اليد -u
).لتضمين الملفات التي لم يتم تعقبها في مخبأتك، استخدم أحد الأوامر التالية:
git stash --include-untracked
git stash -u
وإضافة ملف إلى الفهرس:
git add path/to/untracked-file
git stash
وومحتويات المؤشر، بالإضافة إلى أي تغييرات unstaged إلى الملفات الموجودة، سوف تجعل كل ما في خبأ.
في git bash، يتم تخزين الملفات التي لم يتم تعقبها باستخدام الأمر
git stash --include-untracked
أو
git stash -u
http://git-scm.com/docs/git-stash
يقوم git stash بإزالة أي ملفات غير متعقبة أو غير ملتزم بها من مساحة العمل الخاصة بك.ويمكنك إرجاع git stash باستخدام الأوامر التالية
git stash pop
سيؤدي هذا إلى إعادة الملف إلى مساحة العمل المحلية الخاصة بك.
تجربتي
اضطررت إلى إجراء تعديل على ملف gitIgnore الخاص بي لتجنب نقل ملفات .classpath و.project إلى الريبو البعيد.لا يُسمح لي بنقل هذا .gitIgnore المعدل في الريبو البعيد اعتبارًا من الآن.
تعد ملفات .classpath و.project مهمة لـ Eclipse - وهو محرر Java الخاص بي.
لقد قمت أولاً بإضافة بقية الملفات بشكل انتقائي والتزمت بالتدريج.ومع ذلك، لا يمكن إجراء الدفع النهائي ما لم يتم تعديل ملفات .gitIgnore والملفات التي لم يتم تعقبها.لا يتم تخزين .project و.classpath.
إستعملت
git stash
لإخفاء ملف .gitIgnore المعدل.
لإخفاء ملف .classpath و.project، استخدمت
git stash --include-untracked
وقام بإزالة الملفات من مساحة العمل الخاصة بي.يؤدي غياب هذه الملفات إلى إبعاد قدرتي على العمل في موقع عملي في Eclipse.لقد شرعت في إكمال الإجراء الخاص بدفع الملفات الملتزمة إلى جهاز التحكم عن بعد.وبمجرد الانتهاء من ذلك بنجاح، استخدمت
git stash pop
أدى هذا إلى لصق نفس الملفات مرة أخرى في مساحة العمل الخاصة بي.لقد أعاد لي هذا قدرتي على العمل في نفس المشروع في Eclipse.آمل أن يكون هذا جانباً من المفاهيم الخاطئة.
وكما قيل في مكان آخر فالجواب هو git add
الملف.على سبيل المثال:
git add path/to/untracked-file
git stash
ولكن السؤال مطروح في إجابة أخرى:ماذا لو كنت لا تريد حقًا إضافة الملف؟حسنا، بقدر ما أستطيع أن أقول، عليك أن تفعل ذلك.والإرادة التالية لا عمل:
git add -N path/to/untracked/file # note: -N is short for --intent-to-add
git stash
وهذا سوف يفشل، على النحو التالي:
path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state
ذلك ما يمكن أن تفعله؟حسنًا، يجب عليك إضافة الملف حقًا، لكن, ، يمكنك إلغاء إضافته لاحقًا بشكل فعال، باستخدام git rm --cached
:
git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file
ومن ثم يمكنك مواصلة العمل بنفس الحالة التي كنت عليها قبل git add
(أي مع ملف لم يتم تعقبه يسمى path/to/untracked-file
;بالإضافة إلى أي تغييرات أخرى قد تكون أجريتها على الملفات المتعقبة).
الاحتمال الآخر لسير العمل في هذا الأمر سيكون مثل:
git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack
[ملحوظة:كما هو مذكور في تعليق من @mancocapac، قد ترغب في الإضافة --exclude-standard
إلى git ls-files
أمر (لذا، git ls-files -o --exclude-standard
).]
...والتي يمكن أيضًا كتابتها بسهولة - حتى الأسماء المستعارة ستفعل (مقدمة في بناء جملة zsh؛اضبط حسب الحاجة) [أيضًا، قمت بتقصير اسم الملف بحيث يتناسب مع الشاشة دون التمرير في هذه الإجابة؛لا تتردد في استبدال اسم ملف بديل من اختيارك]:
alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'
لاحظ أن الأخير قد يكون أفضل كبرنامج نصي أو وظيفة، للسماح بتوفير المعلمات لها git stash
, ، في حال كنت لا تريد pop
لكن apply
, و/أو تريد أن تكون قادرًا على تحديد مخبأ معين، بدلاً من أخذ المخبأ العلوي فقط.ربما يكون هذا (بدلاً من الاسم المستعار الثاني أعلاه) [تم تجريد المسافة البيضاء لتلائم دون التمرير؛إعادة الإضافة لزيادة الوضوح]:
function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}
ملحوظة:في هذا النموذج، تحتاج إلى توفير وسيطة إجراء بالإضافة إلى المعرف إذا كنت ستقوم بتوفير معرف مخبأ، على سبيل المثال. unstashall apply stash@{1}
أو unstashall pop stash@{1}
والتي بالطبع ستضعها في حسابك .zshrc
أو ما يعادلها لجعلها موجودة على المدى الطويل.
نأمل أن تكون هذه الإجابة مفيدة لشخص ما، حيث تجمع كل شيء معًا في إجابة واحدة.
على بوابة الإصدار 2.8.1:الأعمال التالية بالنسبة لي.
لحفظ الملفات المعدلة والتي لم يتم تعقبها في المخزن بدون اسم
git stash save -u
لحفظ الملفات المعدلة والتي لم يتم تعقبها في المخزن باسم
git stash save -u <name_of_stash>
يمكنك استخدام أي من البوبين والتقديم لاحقًا على النحو التالي.
git stash pop
git stash apply stash@{0}
لقد تمكنت من الاختباء فقط الملفات التي لم يتم تعقبها عن طريق القيام بما يلي:
git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}
يقوم الأخير بإخراج مخزون الملفات المتعقبة، وبالتالي يترك فقط الملفات التي لم يتم تعقبها مخفية.
إذا كنت تريد لتخبئة الملفات لا يمكن تقفي أثرها، ولكن الحفاظ على الملفات المفهرسة (تلك التي على وشك ارتكاب على سبيل المثال)، وأضيف -k
(الحفاظ على مؤشر) الخيار لل-u
git stash -u -k
ويمكنك ببساطة أن تفعل ذلك مع الأمر أدناه
git stash save --include-untracked
أو
git stash save -u
لمزيد من المعلومات حول بوابة خبأ زيارة هذا المنصب (اضغط هنا)
ودعونا نفترض يسمى ملف جديد وغير المتتبعة: "views.json". إذا كنت ترغب في تغيير فرع من بإخفاء حالة التطبيق الخاص بك، وأنا اكتب عموما:
git add views.json
وبعد ذلك:
git stash
وسيكون من مخبأة. ثم يمكنني تغيير مجرد فرع مع
git checkout other-nice-branch
توجد العديد من الإجابات الصحيحة هنا، لكني أردت الإشارة إلى أنه بالنسبة للأدلة الجديدة بالكامل، 'git add path'
سوف لا عمل.لذا، إذا كان لديك مجموعة من الملفات الجديدة مسار غير متعقب وافعل هذا:
git add untracked-path
git stash "temp stash"
سيتم إخفاء هذا بالرسالة التالية:
Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty
و إذا مسار غير متعقب هو المسار الوحيد الذي تخبئه، وسيكون المخبأ "المخبأ المؤقت" مخبأً فارغًا.الطريقة الصحيحة هي إضافة المسار بأكمله، وليس فقط اسم الدليل (أي.إنهاء المسار بـ '/'):
git add untracked-path/
git stash "temp stash"
وأعتقد أن هذا يمكن حلها عن طريق إخبار بوابة بأن وجود الملف، بدلا من ارتكاب كل محتويات منه إلى منطقة التدريج، ومن ثم استدعاء git stash
. Araqnid يصف كيفية القيام السابق.
git add --intent-to-add path/to/untracked-file
أو
git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file
ولكن، وهذه الأخيرة لا تعمل:
$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state
واعتدت على التأمل والرغبة نفس الميزة. لكن مع مرور الوقت، لاحظت أنه حقا ليست هناك حاجة. عند خبأ، لا بأس من ترك الملفات الجديدة. لا شيء "سيئة" يمكن أن يحدث لهم (عند سحب شيء آخر، وبوابة وخطأ لا الكتابة فوق الملف لا يمكن تقفي أثرها القائمة)
ومنذ عادة الإطار الزمني بين git stash
وgit stash pop
صغير بدلا من ذلك، عليك أن تكون الحاجة الملف لا يمكن تقفي أثرها بسرعة مرة أخرى.
لذلك أود أن أقول إزعاج من الملف تظهر في git status
بينما كنت تعمل على شيء آخر (بين git stash
وgit stash pop
) هو أصغر ثم الإزعاج الناجم عن العمل وبحاجة إلى عناية سيكلف ذلك في محاولة لإضافة ملف لا يمكن تقفي أثرها إلى خبأ الخاص بك.