Как мне объединить мои локальные незафиксированные изменения в другую ветку Git? - PullRequest
590 голосов
/ 17 февраля 2009

Как я могу сделать следующее в Git?

Моя текущая ветвь - это branch1, и я сделал некоторые локальные изменения. Однако теперь я понимаю, что на самом деле я хотел применить эти изменения к branch2. Есть ли способ применить / объединить эти изменения, чтобы они стали локальными изменениями на branch2 без их фиксации на branch1?

Ответы [ 6 ]

853 голосов
/ 17 февраля 2009

Поскольку ваши файлы еще не зафиксированы в 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
83 голосов
/ 17 февраля 2009

Сокрытие, временные коммиты и перебазирование могут быть излишними. Если вы еще не добавили измененные файлы в индекс, вы можете просто извлечь другую ветку.

git checkout branch2

Это будет работать до тех пор, пока никакие файлы, которые вы редактируете, не различаются между branch1 и branch2. Он оставит вас на branch2 с сохраненными рабочими изменениями. Если они отличаются, вы можете указать, что вы хотите объединить свои локальные изменения с изменениями, внесенными путем переключения веток с опцией -m на оформление заказа.

git checkout -m branch2

Если вы добавили изменения в индекс, то сначала нужно отменить эти изменения, сбросив их. (Это сохранит вашу рабочую копию, она просто удалит подготовленные изменения.)

git reset
11 голосов
/ 23 августа 2014

Более короткая альтернатива ранее упомянутому подходу тайника была бы:

Временно перенести изменения в тайник.

  1. git stash

Создайте и переключитесь на новую ветку, а затем вставьте в нее тайник всего за один шаг.

  1. git stash branch new_branch_name

Тогда просто add и commit внесите изменения в эту новую ветвь.

8 голосов
/ 08 апреля 2015

ВНИМАНИЕ: Не для мерзавцев-новичков.

Этого достаточно в моем рабочем процессе, и я почти попытался написать для него новую команду 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 вместо того, чтобы скрываться в моей ветке функций.

IMO git stash и git checkout - это настоящая PIA, когда вы работаете над какой-то большой функцией.

2 голосов
/ 17 февраля 2009

Если бы речь шла о совершенных изменениях, вам следует взглянуть на git-rebase, но, как указано в комментарии VonC, когда вы говорите о локальных изменениях, git-stash, безусловно, будет хорошим способом сделать это. .

1 голос
/ 15 августа 2014

Ответы, данные до сих пор, не идеальны, потому что они требуют много ненужной работы по разрешению конфликтов слияния, или они делают слишком много предположений, которые часто бывают ложными. Вот как это сделать отлично. Ссылка на мой собственный сайт.

Как выполнить фиксацию в другой ветке в 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 unstages все, что получается из 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.

...