2013-09-02 3 views
6

У меня есть две последовательные фиксации, где-то в локальной истории, и один файл был ошибочно добавлен ко второму. Я хочу исправить ситуацию.Перемещение файлов между коммитами

Я не понимаю, как использовать интерактивную перезагрузку. Я сделал git rebase -i HEAD~10 и выбрал для редактирования фиксации файл, чтобы проверить его. Я использую git guit, но не вижу файлов в области фиксации. Я могу выбрать изменение предыдущей фиксации, тогда я вижу файлы. Но я не могу добавить неустановленный файл к предыдущей фиксации, так как я не вижу файл в текущей фиксации для начала.

+0

Имейте в виду, что изменение любой прошлой передачи перезаписывает историю, и вы получаете совершенно новые хэши с момента совершения.Не делайте этого, если коммит уже опубликован. – aragaer

+0

@aragaer Я намеренно предусмотрел, что переписываю историю _LOCAL_. – Val

ответ

8

Если я не получаю это неправильно, что вы хотите переместить некоторые изменения, включенную совершить 2 совершить 1.

Я считаю, что самый простой способ сделать это делает два последовательных интерактивных rebases.

В первом вы разделите фиксацию 2 на две коммиты: первая включает только изменение, которое вы хотите переместить, а второе включает все остальное. Мы теперь совершили 1, 2.1 и 2.2.

Тогда вы перебазироваться снова, и на этот раз выбрать сквош совершить 2.1 в 1.

16

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

pick 8de731b Commit with missing file. 
pick bbef925 Commit with too many files. 
pick 52490ce More history. 

мне нужно изменить его

edit bbef925 Commit with too many files. 
edit 8de731b Commit with missing file. 
pick 52490ce More history. 

Затем

# In the commit containing an extra file 
git reset HEAD^ badfile.c 
git commit --amend 
git rebase --continue 

# Now in the commit to add it to 
git add badfile.c 
git commit --amend 
git rebase --continue 

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

pick 7cd915f Commit with missing file. 
fixup 8de731b Commit with missing file. #This was the higher of the two entries 
pick 8b92c5a Commit with too many files. 
fixup bbef925 Commit with too many files. #This was the higher of the two entries 
pick 94c3f7f More history. 
fixup 52490ce More history. #This was the higher of the two entries 

Late edit: Я только что заметил, что я случайно переупорядочил историю фиксации как перенос из моего первоначального ответа. Перестановка строк в rebase изменяет порядок, который вы совершаете; после редактирования вы можете снова переустановить и поменять их обратно, чтобы вернуться к первоначальному порядку фиксации.

+0

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

+0

Мне удалось перенести файл в новую ветку, которая имела вторую фиксацию вверху. Но теперь у меня проблема, сводящая всю историю к вершине этой ветки. Кажется, что два коммитов основного конфликта с двумя коммитами новой ветви. – Val

+0

Я обновил ответ, но, к сожалению, единственным способом, который я знаю, чтобы исправить это, является изменение истории во всех ветвях, так или иначе. – dwarduk

5

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

mv-changes <source-commit> <destination-commit> <path>... 

Вы также можете запустить скрипт в Git-Баш оболочки на Windows.

Обратите внимание, что в случае изменений <path> в промежутках между source-commit и destination-commit, это не сработает.

Дополнительные сведения предоставлены here.

+0

Он не работает полностью автоматически, поскольку он всплывает в редакторе, но это здорово. Благодаря.. – Hunsu

Смежные вопросы