гіт перемикання гілки, не відкидаючи локальних змін


181

Гаразд, скажімо, одного разу ми робимо купу модифікацій, і коли ми йдемо їх робити, ми помічаємо, що працювали над неправильною гілкою.

Як ми можемо змусити git перемикати гілки, не відкидаючи місцевих змін .

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

  • Резервне копіювання змінено репо
  • git reset --hard
  • git checkout right-branch
  • Відновити зміни
  • git commit -m "changes"

Відповіді:


342

Існує маса різних способів, залежно від того, як далеко ви знаходитесь і на якій галузі ви їх хочете.

Візьмемо класичну помилку:

$ git checkout master
... pause for coffee, etc ...
... return, edit a bunch of stuff, then: oops, wanted to be on develop

Тож тепер ви хочете, щоб ці зміни, яких ви ще не зобов’язали master, відбулися develop.

  1. Якщо ви НЕdevelop тим НЕ менш, метод тривіальний:

    $ git checkout -b develop
    

    Це створює нову developгілку починаючи з того місця, де ви зараз знаходитесь. Тепер ви можете взяти на себе зобов’язання, і нові речі все активовано develop.

  2. Ви єdevelop . Подивіться, чи дозволить вам Git переходити, не роблячи нічого:

    $ git checkout develop
    

    Це або вдасться, або скаржиться. Якщо це вдасться, чудово! Просто покладіть. Якщо ні ( error: Your local changes to the following files would be overwritten ...), у вас ще багато варіантів.

    Найпростіше, мабуть, git stash(як postсказали всі інші відповіді, які мене перебили на натискання ). Виконати git stash saveабо git stash push, 1 або просто простий, git stashякий короткий для save/ push:

    $ git stash
    

    Це змушує ваш код (так, він дійсно робить деякі зобов’язання), використовуючи дивний метод, не відгалужуючий y. Команди, які він робить, не є "жодною" гілкою, але тепер безпечно зберігаються у сховищі, тому тепер ви можете перемикати гілки, а потім "застосовувати" сховище:

    $ git checkout develop
    Switched to branch 'develop'
    $ git stash apply
    

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

Цей applyкрок робить злиття прихованих змін, використовуючи потужну базову техніку злиття Git, таку саму річ, яку він використовує, коли ви здійснюєте злиття філій. Це означає, що ви можете отримати «конфлікти злиття», якщо галузь, над якою ви працювали помилково, досить відрізняється від тієї галузі, над якою ви мали намір працювати. Тож корисно уважно ознайомитись з результатами, перш ніж припустити, що приховування застосовано правильно навіть якщо сам Git не виявив жодних конфліктів злиття.

Багато людей використовують git stash pop, що короткочасно git stash apply && git stash drop. Наскільки це добре, але це означає, що якщо програма призведе до безладу, і ви вирішите, що не хочете продовжувати цей шлях, ви не зможете легко повернути сховку назад. Тому я рекомендую окремо applyперевіряти результати, dropлише якщо / коли це задоволено. (Це, звичайно, вводить ще один момент, коли ви можете зробити ще одну перерву на каву і забути, що ви робили, повертатися і робити неправильну справу, так що це не ідеальне лікування.)


1save в git stash saveстарому дієслово для створення нового кубла. Git версія 2.13 представила нове дієслово, щоб зробити речі більш узгодженими popта додати більше параметрів до команди створення. Версія Git 2.16 формально заставила старе дієслово (хоча воно все ще працює в Git 2.23, що є останнім випуском на той момент, коли я це редагую).


3
Що робити, якщо я хочу переключитися на іншу гілку, не зобов'язавшись до поточної гілки (наприклад, зміни не закінчені) і пізніше переключитись назад, щоб продовжувати роботу?
stt106

@ stt106: ви все одно зобов’язані виконувати, але ви можете це зробити, як у цій та інших відповідях, через git stashте, що коміти - бо git stashви отримуєте два коміти за запис у сховищі, у незвичному порядку - не мають жодної гілки. За винятком дуже короткотермінових спеціальних випадків, я, як правило, вважаю за краще взяти на себе звичайні зобов'язання. Ви можете git reset --softабо git reset --mixedпізніше, або скористатися, git commit --amendщоб відсунути це вбік, коли ви знову працюєте над цією гілкою. (У сучасному Git ви також можете використовувати git worktree add, що може бути ще кращим рішенням.)
torek

"Це або вдасться, або скаржиться." Які можуть бути причини успіху чи помилки при оформленні каси?
nanocv


всі мої локальні зміни втрачаються, коли я перемикаюсь з вищезазначеними кроками, я перебуваю у <a> гілці та роблю зміни, і я хочу перейти до <b> гілки та натиснути на це всі мої зміни. коли я роблю схованку в git і переїжджаю на інші гілки, її тягнуть усі файли <b> гілки, і мої локальні зміни втрачаються
Mukul Munjal

38

Використовуйте git stash

git stash

Це підштовхує зміни до стека. Коли ви хочете відтягнути їх назад, використовуйте

 git stash apply

Можна навіть витягувати окремі предмети. Для повного видування сміття:

 git stash clear

7
Остання команда, мабуть, повинна бути git stash drop; git stash clearвидалить весь стек скриптів, включаючи, можливо, непов'язані сташі для цього набору команд.
Леланд

15
  • git stash щоб зберегти невмілі зміни
  • git stash list щоб перелічити збережені некомплектні скриньки
  • git stash apply stash@{x} де х може становити 0,1,2..не заготовок, які ви зробили

4

Ви можете:

  • Використовуйте git stashдля приховування змін або,

  • Створіть іншу гілку та введіть там свої зміни, а потім об'єднайте її у свою робочу директорію

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