Як з'єднати свої місцеві неприйняті зміни в іншу гілку Git?


621

Як я можу зробити наступне в Git?

Моя нинішня філія - ​​філія1, і я внесла деякі місцеві зміни. Однак зараз я розумію, що я насправді мав намір застосувати ці зміни до гілки2. Чи є спосіб застосувати / об'єднати ці зміни, щоб вони стали локальними змінами в гілці2, не вчиняючи їх на гілку1?


2
Існує велика Гіт Підручник прямо тут на SO. Він є центральним для всіх питань git щодо переповнення стека.
Decio Lira

Відповіді:


897

Оскільки ваші файли ще не здійснені branch1:

git stash
git checkout branch2
git stash pop

або

git stash
git checkout branch2
git stash list       # to check the various stash made in different branch
git stash apply x    # to select the right one

Як зазначила по benjohn (див довідкової git stashсторінці ):

Щоб також приховувати поточні неактивовані (нещодавно додані) файли, додайте аргумент -u, таким чином:

git stash -u

2
Будь ласка. Інші приклади використання збирати на unethicalblogger.com/posts/2008/11 / ... .
VonC

2
Якщо ви шукаєте рішення тієї самої проблеми, але з TFS, еквівалентним рішенням є призупинення змін, то використовуйте електроінструменти TFS, щоб перейти до правильної гілки за допомогою перемикача / migrate.
xr280xr

1
Це працювало для мене. Однак мені також довелося створити місцеве відділення для роботи "прихованого попу". Отримайте замовлення stackoverflow.com/questions/1783405/git-checkout-remote-branch, якщо з вами щось подібне відбувається.
mimoralea

21
Для того, щоб також збирати в даний час неотслежіваемих (недавно додані файли) , додайте аргумент -u, так: git stash -u.
Бенджон

2
@Benjohn Добре. Я включив ваш коментар у відповідь для більшої наочності.
VonC

84

Закриття, тимчасові зобов’язання та повернення коштів можуть бути надмірними. Якщо ви ще не додали змінені файли до індексу, можливо, ви зможете просто перевірити іншу гілку.

git checkout branch2

Це буде працювати до тих пір, поки жодні файли, які ви редагуєте, не відрізняються між відгалуженням1 та гілкою2. Він залишить вас на відділенні2, з вами збережені робочі зміни. Якщо вони різні, то ви можете вказати, що ви хочете об'єднати свої локальні зміни зі змінами, введеними перемиканням гілок з -mможливістю оформлення замовлення.

git checkout -m branch2

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

git reset

3
Я думав, що сховище "простіше" якось зрозуміти, але ваш підхід краще враховувати робочий каталог у різних галузях. +1
VonC

6
Простий традиційний замовлення здавався більш підходящим для проблеми. каса легша за вагу, вона просто оновлює файли, які потрібно змінити. Можливо, простіше зрозуміти підхід у сховищах, а може бути просто так, що недостатньо очевидно, що замовлення в цьому випадку "безпечне".
CB Bailey

Якщо checkout -mв певній ситуації не є "безпечним" (можливо, це призведе до конфлікту злиття), приховуватиметься схована скринька (наприклад, чи можете ви скасувати скрипт)?
Крейг МакКуїн

1
@craigMcQueen Ви не можете скасувати вискочений скрипт, але при цьому скарб скаржиться на конфлікти. Ви можете виправити конфлікти, а потім скористатись, але оригінальний скрипт у цьому випадку все ще стоїть! :)
Shaun F

У випадку конфлікту злиття, чи не резервні копії файлів як .orig?
jocull

13

Більш короткою альтернативою раніше згаданому підходу є:

Тимчасово перемістіть зміни в сховище.

  1. git stash

Створіть та перейдіть на нову гілку, а потім викладіть на неї лише один крок.

  1. git stash branch new_branch_name

Тоді просто addі commitзміни до цієї нової гілки.


10

ПОПЕРЕДЖЕННЯ: Не для новонароджених, що входять в груди

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

Також корисно - якщо ви стикаєтеся з подібними ситуаціями - мати ще один робочий каталог поряд із вашим поточним, який завжди masterперевіряє гілку.

Тож як я цього досягаю, йде так:

  1. git commit зміни одразу з хорошим повідомленням про фіксацію.
  2. git reset HEAD~1 скасувати комісію з поточної гілки.
  3. (необов’язково) продовжуйте роботу над функцією.

Іноді пізніше (асинхронно) або відразу в іншому вікні терміналу:

  1. cd my-project-master яка є ще однією WD, яка поділяє те саме .git
  2. git reflog щоб знайти помилку, яку я щойно створив.
  3. git cherry-pick SHA1 комітету.

За бажанням (все ще асинхронним) ви можете потім відновити (або об'єднати) свою функціональну гілку, щоб отримати виправлення, як правило, коли ви збираєтесь подати PR та вже очистили свою гілку функції та WD:

  1. cd my-project яка головна WD, над якою я працюю.
  2. git rebase master щоб отримати виправлення.

Таким чином , я можу продовжувати працювати над функцією безперебійно і не повинні турбуватися про git stash-ву що - небудь або того , щоб очистити мій WD перед git checkout(а потім з чеку функція гілки відкату знову.) І до сих пір всі мої виправлення помилок йде до masterзамість прихований у моїй функції.

ІМА git stashі git checkoutє реальною PIA , коли ви знаходитесь в середині роботи над якою - небудь великий особливістю.


Цікава та достовірна альтернатива моїй відповіді. +1
VonC

Ви виходите з меркуріума? my-project-masterПоділяючи ті ж .gitробить звук , як він. Чому б не git checkout -b bugfixABC; git commit -a; git reset HEAD^ --hard, то пізніше (асинхронно) , а на master, git cherry-pick <SHA1 of the commit(s) in bugfixABC? (або навіть, щоб уникнути необхідності дізнатися SHA1, git rebase --onto master feature bugfixABCз того місця, де ви зараз перебуваєте. Що означає, що ви можете це робити безпосередньо після git resetвищезазначеного, перебуваючи на feature.)
Gauthier

Однак ОП звучить так, що вони не готові вчинити зміни, в цьому випадку просто checkout -mкраще.
Готьє

2

Якби мова йшла про здійснені зміни, ви б мали ознайомитися з git-rebase, але як зазначається у коментарі VonC, коли ви говорите про локальні зміни, git-stash, безумовно, був би хорошим способом це зробити.


Я не розумію цього рішення: воно переписало б історію фіксування філії2 з гілки1 ... чому отримувати всі здійснені зміни з філії1 в гілки2, коли ми хочемо лише отримати локальні незавершені зміни в галузі філія1 у галузі2? ...
VonC

@VonC: погодився, у цьому випадку ребаза отримує всі здійснені зміни з моменту останнього злиття між гілками у гілку1. Спочатку я не отримав "незахищений" параметр цього питання. Rebase не є гарною відповіддю.
клаф

@claferri: pfew ... У мене почав боліти голова;) Я би спростував вашу відповідь, але оскільки я сам опублікував її, стався "явний конфлікт інтересів". Що стосується Вашого оновленого допису, мені зараз взагалі не потрібно подавати заявки. Дякую :)
VonC

@VonC: наступного разу сміливо відмовляйся від голосування, якщо моя відповідь буде такою ж неправильною, як ця;)
claf

1

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

Як покластися на іншу гілку в git

У вас є незаконні зміни щодо того, my_branchщо ви хочете здійснити master, не вчинивши жодних змін my_branch.

Приклад

git merge master
git stash -u
git checkout master
git stash apply
git reset
git add example.js
git commit
git checkout .
git clean -f -d
git checkout my_branch
git merge master
git stash pop

Пояснення

Почніть з об'єднання masterу свою філію, оскільки вам доведеться це зробити зрештою, і зараз найкращий час для вирішення будь-яких конфліктів.

Цей -uпараметр (ака --include-untracked) git stash -uзапобігає втраті файлів, що не відслідковуються, коли пізніше це робиться git clean -f -dвсередині master.

Після git checkout masterтого, як важливо, ви НЕ будете робити git stash pop, тому що вам буде потрібна ця скринька пізніше. Якщо ви поп тайник , створений в my_branchа потім зробити git stashв master, ви будете викликати непотрібні конфлікти злиття , коли ви застосуєте цей тайник в my_branch.

git resetнестабільність все, що є результатом git stash apply. Наприклад, файли, які були змінені в сховці, але не існують в стадії masterпостановки як конфлікти "видалених нами".

git checkout .і git clean -f -dвідкиньте все, що не вчинено: усі зміни відслідковуваних файлів, а також усіх непотренованих файлів та каталогів. Вони вже зберігаються в сховці, і якщо їх не залишилося, це masterпризведе до зайвих конфліктів злиття при переході назад до my_branch.

Останній git stash popбазуватиметься на оригіналі my_branch, і тому не спричинятиме конфліктів злиття. Однак якщо у вашому сховищі містяться відслідковувані файли, які ви зобов’язалися засвоїти, git поскаржиться, що це "Не вдалося відновити відслідковувані файли із сховища". Щоб вирішити цей конфлікт, видалити ці файли з вашого робочого дерева, а потім git stash pop, git add .і git reset.


2
Вашу відповідь не було видалено, оскільки вона пов’язана з вашим веб-сайтом, вона була видалена, оскільки вона була ідентичною цій іншій відповіді з іншого облікового запису. Я бачу, що інший обліковий запис має той самий профіль, що і ваш, ви використовуєте два облікові записи? Ви можете об’єднати обидва рахунки. Крім того, позначте мод, щоб пояснити ситуацію, і ви зможете отримати оригінальну відповідь (з підсумковою заявою) невизначеною.

1
Ви не можете тримати їх окремо , якщо вони об'єднані, але які дозволено мати кілька облікових записів, до тих пір , поки ви не використовувати їх для здійснення голосування шахрайства (або у них взаємодіють один з одним в цілому). Поясніть свою ситуацію моднику. Також видалення було відвертою помилкою, як ви могли сподіватися, що хтось скаже, що ви використовуєте два різні облікові записи?

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

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