2010-05-31 3 views
495

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

Итак, Как я могу сделать, что нефиксированные изменения (или изменения, хранящиеся в индексе), будут переданы в другую ветку, чем текущая?

ответ

727

Другие ответы, предлагающие проверить другую ветвь, а затем совершить ее, работать, только если проверка возможна с учетом локальных изменений. Если нет, то вы в самом общем случае использования для git stash:

git stash 
git checkout other-branch 
git stash pop 

Первый stash прячет свои изменения (в основном делает временной фиксации), и последующее stash pop повторно применяет их. Это позволяет git использовать возможности слияния.

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

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

# Unstage everything (warning: this leaves files with conflicts in your tree) 
git reset 
# Add the things you *do* want to commit here 
git add -p  # or maybe git add -i 
git commit 
# The stash still exists; pop only throws it away if it applied cleanly 
git checkout original-branch 
git stash pop 
# Add the changes meant for this branch 
git add -p 
git commit 
# And throw away the rest 
git reset --hard 

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

git add -p 
git commit 
git stash 
git checkout other-branch 
git stash pop 

И, конечно, помните, что все это занимает немного работы, и избежать его в следующий раз, возможно, наложив свое текущее имя ветки в вашей строке путем добавления $(__git_ps1) к вашему PS1 в вашем bashrc. (См. Например, документы Git in Bash.)

+0

Когда вы сказали: 'Проверка ветви, а затем фиксация будет работать, только если проверка возможна с учетом локальных изменений'. Что вы имеете в виду? Не могли бы вы дать или обсудить один простой пример, если это не удастся? –

+5

@ user815423426 Если у вас есть незафиксированные изменения, вы можете проверить другую ветку, если и только если набор файлов, которые вы изменили, и набор файлов, которые отличаются между двумя ветвями, не пересекаются. То есть, если вы изменили файл A, вы можете проверить другую ветку, только если файл A в обеих ветвях одинаковый. – Cascabel

+0

Спасибо! Когда вы сказали, что «A» одинаково в обеих ветвях, вы имеете в виду «A» перед моими изменениями (т. Е. 'A' в HEAD каждой ветви). Верный? –

18
  1. git checkout my_other_branch
  2. git add my_file my_other_file
  3. git commit -m

и обеспечить коммиттера сообщение.

+1

вы можете написать, что * co * и * ci * есть ... хотя можно догадаться (checkout, commit) ^^ – tanascius

+2

@tanascius Хорошее предложение и сделано. Я использую псевдонимы так долго, что забыл, что они не являются стандартными. –

45

Вы можете просто создать новую ветку и переключиться на нее. Фиксировать изменения затем:

git branch dirty 
git checkout dirty 
// And your commit follows ... 

В качестве альтернативы, вы можете также оформить существующую ветвь (только git checkout <name>). Но только, если нет коллизий (база всех отредактированных файлов такая же, как в вашей текущей ветке). В противном случае вы получите сообщение.

+9

Обратите внимание, что в случае переключения на ** существующую ветвь *** *** *** с веткой вы можете использовать опцию '-m', чтобы сообщить git, чтобы попытаться объединить изменения, то есть' git checkout -m ' –

+2

@ Jefromi's Ответ лучше всего в каждом случае, я думаю. –

+3

Короткая версия: 'git checkout -b dirty' – user1338062