Як відновити приховані неспроможні зміни


693

У мене були деякі неспроможні зміни в моїй галузі розвитку, і я їх застосував git stash, але були деякі зміни, які були дуже важливими серед тих, що були закриті. Чи є можливість повернути ці зміни?

Крім того, я зробив деякі зміни поверх збережених файлів коду.

Чи є ймовірність отримати я сховані зміни в новій гілці, якщо це можливо?


7
ви спробували скористатись "прихованим попсом"?
Роберт

Ні. Насправді я новачок в git. Оскільки я не в курсі всіх команд, я нічого іншого не пробував! Я не хочу втрачати ці зміни.
Aswathy P Krishnan

33
Якщо ви не хочете втратити приховані зміни, спробуйте скористатися "git stash apply". Це застосує приховані зміни до вашої поточної гілки, зберігаючи приховування. Якщо все в порядку, після застосування скриньки ви можете скинути скриньку, використовуючи 'git stash drop'
Роберт

2
@robert Дякую за просту відповідь порівняно з жахливо складною (для новачків) прийнятою відповіддю.
Saheel Godhane

Відповіді:


1186

Проста відповідь на просте запитання git stash apply

Просто перевірте гілку, на якій потрібно змінити, а потім git stash apply. Потім використовуйте, git diffщоб побачити результат.

Після того, як ви все закінчите зі своїми змінами - це applyдобре виглядає, і ви впевнені, що вам більше не потрібна скринька - тоді використовуйте git stash dropдля її позбавлення.

Я завжди пропоную використовувати, git stash applyа не використовувати git stash pop. Різниця полягає в тому, що applyзалишає сховище навколо для легкої повторної спроби applyабо для перегляду тощо. Якщо popвдасться витягнути скриньку, вона негайно також dropце зробить , і якщо ви раптом зрозумієте, що хотіли її десь витягти інше (в іншій галузі), або з --index, або з деяким подібним, це не так просто. Якщо ви apply, ви можете вибрати коли drop.

Це все дуже незначно, так чи інакше, і для новачків, які гніють, це повинно бути приблизно однаково. (І все інше ви можете пропустити!)


Що робити, якщо ви робите більш досконалі або складніші речі?

Існує як мінімум три-чотири різних "способи використання git stash", як би там не було. Сказане вище для "шлях 1", "простий шлях":

  1. Ви почали з чистої гілки, працювали над деякими змінами, а потім зрозуміли, що робите їх у неправильній гілці. Ви просто хочете прийняти зміни, які у вас є, і "перемістити" їх до іншої гілки.

    Це простий випадок, описаний вище. Виконати git stash save(або просто git stash, те саме). Ознайомтеся з іншою галуззю та використовуйте git stash apply. Це отримує git для об'єднання у ваші попередні зміни, використовуючи досить потужний механізм злиття git. Огляньте результати уважноgit diff), щоб побачити, чи вони вам сподобалися, а якщо вам це потрібно, скористайтеся, git stash dropщоб скинути скриньку. Ви закінчили!

  2. Ви розпочали деякі зміни та приховали їх. Потім ви перейшли в іншу гілку і почали ще зміни, забувши, що у вас були приховані.

    Тепер ви хочете зберегти ці зміни або навіть перемістити ці зміни та застосувати також свої сховища.

    Фактично ви можете git stash saveзнову, як це git stashробить "стек" змін. Якщо ви робите це, у вас є два сташі, один що називається stash- але ви також можете писати - stash@{0}і один написаний stash@{1}. Використовуйте git stash list(у будь-який час), щоб побачити їх усіх. Найновіший - це завжди найменший номер. Коли ви git stash drop, це скидає найновіший і той, який stash@{1}рухався до вершини стека. Якщо у вас ще більше, той , який був stash@{2}стає stash@{1}, і так далі.

    Ви можете, applyа потім dropі певний сховище: git stash apply stash@{2}і так далі. Відкинувши певну скриньку, перераховуйте лише ті, хто перелічується вище. Знову ж і той без числа stash@{0}.

    Якщо ви накопичите багато стасів, це може вийти досить безладним (це хотілося, stash@{7}чи я хотів, чи це stash@{4}? Зачекайте, я просто штовхнув іншого, зараз їх 8 та 5?). Я особисто вважаю за краще перенести ці зміни в нову гілку, тому що гілки мають назви, а cleanup-attempt-in-Decemberдля мене значить набагато більше, ніж stash@{12}. ( git stashКоманда приймає необов'язкове повідомлення збереження, і вони можуть допомогти, але якимось чином всі мої статистичні дані просто закінчуються назвами WIP on branch.)

  3. (Екстра-вдосконалений) Ви перед тим, як запустити, ви використовували git stash save -pабо ретельно git add-ed та / або git rm-ed певні біти коду git stash save. У вас була одна версія в області індексу / інсценізації та інша (інша) версія в робочому дереві. Ви хочете зберегти все це. Отже, тепер ви використовуєте git stash apply --index, а це часом не вдається:

    Conflicts in index.  Try without --index.
    
  4. Ви використовуєте git stash save --keep-indexдля перевірки "що буде вчинено". Цей виходить за межі цієї відповіді; перегляньте натомість цю іншу відповідь StackOverflow .

Для складних випадків я рекомендую спершу запуститись у «чистий» робочий каталог, внісши будь-які зміни, які у вас є зараз (у новій гілці, якщо вам подобається). Таким чином, "десь", що ви їх застосовуєте, немає нічого іншого в ньому, і ви просто будете намагатися приховати зміни:

git status               # see if there's anything you need to commit
                         # uh oh, there is - let's put it on a new temp branch
git checkout -b temp     # create new temp branch to save stuff
git add ...              # add (and/or remove) stuff as needed
git commit               # save first set of changes

Тепер ви на "чистому" стартовому пункті. А може, це виглядає більше так:

git status               # see if there's anything you need to commit
                         # status says "nothing to commit"
git checkout -b temp     # optional: create new branch for "apply"
git stash apply          # apply stashed changes; see below about --index

Головне пам’ятати, що «приховування» - це фіксація, це лише трохи «смішне / дивне» вчинення, яке не «на гілці». В applyоперації дивиться на те , що Комміт змінилося, і намагається повторити його там , де ви зараз перебуваєте . Сховище все ще буде там ( applyтримає його навколо), тож ви можете подивитися на це більше, або вирішити, що це було неправильне місце для applyнього та спробувати ще раз по-іншому, чи що завгодно.


Кожен раз, коли у вас є копія, ви можете git stash show -pпереглянути спрощену версію того, що є в сховищі. (Ця спрощена версія розглядає лише зміни "остаточного дерева робіт", а не збережені зміни індексу, які --indexвідновлюються окремо.) Команда git stash applyбез цього --indexпросто намагається внести ті самі зміни у свою робочу директорію.

Це справедливо, навіть якщо ви вже маєте деякі зміни. applyКоманда рада застосувати притон до модифікованої робочої директорії (або , по крайней мере, спробувати застосувати його). Наприклад, ви можете зробити це:

git stash apply stash      # apply top of stash stack
git stash apply stash@{1}  # and mix in next stash stack entry too

Тут ви можете обрати порядок "застосувати", вибравши певні сташі, які слід застосувати у певній послідовності. Однак зауважте, що кожен раз ви робите "git merge", і як попереджує документація на об'єднання:

Запущене злиття git з нетривіальними невмілими змінами не рекомендує: хоча це можливо, воно може залишити вас у стані, від якого важко відмовитися у випадку конфлікту.

Якщо ви почнете з чистого каталогу та виконуєте декілька git applyоперацій, відмовитись легко: використовуйте, git reset --hardщоб повернутися до чистого стану та змінити свої applyоперації. (Ось чому я рекомендую спочатку починати з чистого робочого каталогу для цих складних випадків.)


А як щодо найгіршого можливого випадку?

Скажімо, ви робите багато розширених Git Stuff, і ви зробили сховище, і хочете git stash apply --index, але застосувати збережений прихований файл більше не можна --index, тому що гілка розбіглася занадто багато з часу, коли ви її зберегли.

Це для чого git stash branch.

Якщо ви:

  1. ознайомтеся з точною фіксацією ви були, коли ви зробили оригінал stash, то
  2. створити нову гілку, і нарешті
  3. git stash apply --index

спроба відновити зміни, безумовно , спрацює. Це те, що робить. (А потім він скидає приховування, оскільки він був успішно застосований.)git stash branch newbranch


Кілька заключних слів про --index(що це за чорт?)

Що --indexможна зробити, пояснити просто, але все-таки трохи складно:

  • Коли у вас є зміни, ви повинні git add(або "поетапно") їх перед початком commit.
  • Таким чином, коли ви бігли git stash, ви, можливо , редагували обидва файли fooта zorg, але лише ставили один із них.
  • Так що, коли ви просите , щоб отримати збирати назад, було б добре , якщо це git addвляет addред речі і зовсім НЕ git add в не-додані речі. Тобто, якщо ви addредагували, fooале не zorgповерталися до того stash, як це зробили , може бути непогано мати таку саму настройку. Те, що було поставлено, слід знову поставити; те, що було видозмінено, але не інсценоване, знову має бути змінено, але не поетапно.

--indexПрапор applyнамагається встановити речі таким чином. Якщо ваше робоче дерево є чистим, це зазвичай просто працює. Якщо у вашому робочому дереві вже є речі add, ви можете побачити, як тут можуть виникнути деякі проблеми. Якщо ви вийдете з роботи --index, applyоперація не намагатиметься зберегти всю поетапну / нестандартну установку. Натомість він просто викликає механізм злиття git, використовуючи команду робочого дерева у "сумці" . Якщо ви не дбаєте про те, щоб зберегти поетапні / нестандартні, виведення з --indexнього робить його набагато простішим git stash apply.


2
Я не розумію вашого коментаря. Ви маєте на увазі: ви побігли git stash pop? Або ви маєте на увазі: ви відредагували деякі файли, але ще не запустилися git stash? Або ти маєш на увазі щось інше цілком?
torek

1
Так. Зауважте, що в моїй (довгій) редакції я рекомендую зробити те, що у вас зараз, перед тим, applyяк приховати. Вам не потрібно цього робити, але це робить речі набагато простішими для вас. Ви можете rebase -iпізніше скопіювати декілька комітетів або вибирати певні зміни, або що завгодно, пізніше.
torek

1
Так: git stash apply --index(згадайте два тире). Якщо ви залишитесь --index, нічого не робити; Єдиним моментом --indexє збереження поетапної / нестандартної настройки. (Ви , ймовірно , не мають будь - яких спеціальних налаштувань , в першу чергу.) Тоді і git statusт.д., і додати / зробити за бажанням і т.д. Коли (і тільки коли) ви все зробили з тайника, використовуйте , git stash dropщоб скасувати його.
torek

1
До тих пір , поки ви зберігаєте (НЕ dropабо pop) схованку, у вас завжди є оригінальний захованих код сейф на Комміт, тому що тайник є Комміт! Якщо ви хочете отримати його точно, але на гілці, скористайтеся git stash branch(див. Цей розділ вище або книгу Pro Git у відповіді Шуні ). Ви можете потім git checkoutцю гілку або git cherry-pickскористатися цією гілкою тощо.
Торек

2
@ChuckWolber: Конвенції про іменування Гіта залишають бажати кращого (скільки різних значень ми можемо присвоїти словам "віддалений", "стеження" та "гілка" ?!). Варто зазначити, що ви можете застосувати сховище до чогось, не пов’язаного з оригінальним сховищем.
торек

57
git stash pop

поверне все на свої місця

як запропоновано в коментарях, ви можете git stash branch newbranchзастосувати сховище до нової гілки, що є тим же, що і для запуску:

git checkout -b newbranch
git stash pop

Дякую за допомогу. Чи можу я змінити ці зміни в новій галузі? Зараз я перебуваю на розробці галузі
Aswathy P Krishnan

3
git stash branch newbranch, створить нову гілку із прихованими змінами.
Роберт

3
@robert: git stash branch newbranchдійсно це зробить; але майте на увазі, що він створює нову гілку разом із своїм батьківським набором для виконання зобов'язань, які були HEADна той момент, коли це stashбуло зроблено. Іншими словами, це коли ви повернетеся після того, як якийсь - то довгої сесії ножівкою або що - то, погляд на безлад, і вирішити , «я повинен покласти , що на гілці, а не приховати» :-)
Торека

Я відредагував своє запитання. Я хотів би отримати ці зміни, якщо це можливо.
Aswathy P Krishnan

1
Іноді просто хочеться відповісти TLDR :)
sachinruk

24

Щоб зробити це просто, у вас є два варіанти, щоб повторно застосувати сховище:

  1. git stash pop - Відновлення назад до збереженого стану, але він видаляє приховування з тимчасового сховища.
  2. git stash apply - Відновлення назад до збереженого стану та залишає список сховища для можливого подальшого повторного використання.

Більш детально про git stas ви можете прочитати в цій статті.


19

Щоб перевірити вміст сховища: -

git скринька

застосувати певний прихований ні зі списку сховища: -

git stash застосувати скриньку @ {2}

або для застосування лише першого сховища: -

git stash pop

Примітка: git stash pop видалить сховище зі списку сховища, тоді як git stash застосує звичай. Тому використовуйте їх відповідно.


2

На mac це працювало для мене:

git stash list (дивіться всі свої скриньки)

git stash list

застосувати git stash (лише номер, який ви хочете зі свого списку сховищ)

подобається це:

git stash apply 1

0

ви можете зберігати незапрошені зміни за допомогою "git stash", а потім перейти до нової гілки за допомогою "git checkout -b", а потім застосувати приховані комісити "git stash apply"

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.