Вы должны использовать индекс. После смешанного сброса (« git reset HEAD ^») добавьте первый набор изменений в индекс, а затем зафиксируйте их. Тогда совершите остальное.
Вы можете использовать « git add », чтобы поместить все изменения, сделанные в файле, в индекс. Если вы не хотите ставить все изменения, сделанные в файле, только некоторые из них, вы можете использовать «git add -p».
Давайте посмотрим на пример. Предположим, у меня есть файл myfile, который содержит следующий текст:
something
something else
something again
Я изменил его в моем последнем коммите, так что теперь это выглядит так:
1
something
something else
something again
2
Теперь я решаю, что хочу разделить его на две части, и хочу, чтобы вставка первой строки была в первом коммите, а вставка последней строки - во втором коммите.
Сначала я возвращаюсь к родителю HEAD, но я хочу сохранить изменения в файловой системе, поэтому я использую «git reset» без аргументов (что будет делать так называемый «смешанный» сброс):
$ git reset HEAD^
myfile: locally modified
$ cat myfile
1
something
something else
something again
2
Теперь я использую «git add -p», чтобы добавить изменения, которые я хочу зафиксировать в индексе (= я их ставлю). «git add -p» - это интерактивный инструмент, который спрашивает вас о том, какие изменения в файле следует добавить в индекс.
$ git add -p myfile
diff --git a/myfile b/myfile
index 93db4cb..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,5 @@
+1
something
something else
something again
+2
Stage this hunk [y,n,a,d,/,s,e,?]? s # split this section into two!
Split into 2 hunks.
@@ -1,3 +1,4 @@
+1
something
something else
something again
Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y # yes, I want to stage this
@@ -1,3 +2,4 @@
something
something else
something again
+2
Stage this hunk [y,n,a,d,/,K,g,e,?]? n # no, I don't want to stage this
Затем я фиксирую это первое изменение:
$ git commit -m "Added first line"
[master cef3d4e] Added first line
1 files changed, 1 insertions(+), 0 deletions(-)
Теперь я могу зафиксировать все остальные изменения (а именно цифру «2», вставленную в последнюю строку):
$ git commit -am "Added last line"
[master 5e284e6] Added last line
1 files changed, 1 insertions(+), 0 deletions(-)
Давайте проверим журнал, чтобы увидеть, какие коммиты у нас есть:
$ git log -p -n2 | cat
Commit 5e284e652f5e05a47ad8883d9f59ed9817be59d8
Author: ...
Date: ...
Added last line
Diff --git a/myfile b/myfile
Index f9e1a67..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -2,3 +2,4 @@
something
something else
something again
+2
Commit cef3d4e0298dd5d279a911440bb72d39410e7898
Author: ...
Date: ...
Added first line
Diff --git a/myfile b/myfile
Index 93db4cb..f9e1a67 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,4 @@
+1
something
something else
something again
git reset [--patch|-p] <commit>
которую вы можете использовать, чтобы избавить вас от необходимостиgit add -p
после перезагрузки. Я прав? Использование git 1.7.9.5.Цели:
splitme
) на два.План:
splitme
.splitme
.Шаги перебазирования (1 и 7) можно пропустить, если
splitme
это самый последний коммит.Если бы я хотел, чтобы сплит-файлы были зафиксированы в первую очередь, я бы затем перебазировал -i и изменил порядок
источник
git reset HEAD^
был недостающий кусок головоломки. Хорошо работает с-p
тоже. Спасибо!-- $files
аргументgit reset
. С пройденными путямиgit reset
восстанавливает эти файлы до состояния указанной фиксации, но не изменяет никакие фиксации. Если вы уйдете с пути, вы «потеряете» коммит, который вы хотите изменить на следующем шаге.git reset HEAD^ -- .
. Крайне удивительно, это не совсем поведениеgit reset HEAD^
.Чтобы изменить текущий коммит на два коммита, вы можете сделать что-то вроде следующего.
Либо:
Это отменяет последний коммит, но оставляет все готовым. Затем вы можете удалить некоторые файлы:
При желании переназначить части этих файлов:
Сделайте новый первый коммит:
Этап и зафиксировать остальные изменения во второй фиксации:
Или:
Отмените и удалите все изменения из последнего коммита:
Выборочно этап первого раунда изменений:
Commit:
Зафиксируйте остальные изменения:
(В любом случае, если вы отменили коммит, в который был добавлен новый файл, и хотите добавить его во второй коммит, вам придется добавить его вручную, поскольку
commit -a
только этапы изменения уже отслеженных файлов.)источник
Запустите
git gui
, выберите переключатель «Изменить последний коммит» и отмените (коммит> Unstage From Commit или Ctrl- U) изменения, которые вы не хотите вносить в первый коммит. Я думаю, что это самый простой способ сделать это.Еще одна вещь, которую вы можете сделать, это выбрать изменения без фиксации (
git cherry-pick -n
), а затем вручную или с помощьюgit gui
выбора нужных изменений перед фиксацией.источник
- жесткое то, что убивает ваши изменения.
источник
Я удивлен, что никто не предложил
git cherry-pick -n forum
. Это отстраивает изменения от последнегоforum
коммита, но не фиксирует их - тогда вы можетеreset
отменить изменения, которые вам не нужны, и зафиксировать то, что вы хотите сохранить.источник
Метод двойного обратного сквоша
git checkout HEAD~1 -- files with unwanted changes
иgit commit
. Если нет, файлы со смешанными изменениями могут быть частично подготовленыgit reset file
иgit add -p file
как промежуточный шаг.) Назовите это обратным .git revert HEAD
- Сделайте еще один коммит, который добавляет нежелательные изменения. Это двойной возвратgit rebase -i HEAD~3
). Этот коммит теперь освобождается от нежелательных изменений, так как они находятся во втором коммите.Преимущества
источник
Так как вы собираете вишню, вы можете:
cherry-pick
это с--no-commit
добавленной опцией.reset
и использоватьadd --patch
,add --edit
или простоadd
поставить то, что вы хотите сохранить.commit
постановочные изменения.--reuse-message=<old-commit-ref>
или--reedit-message=<old-commit-ref>
опции кcommit
команде.reset --hard
.Другой способ, сохранение или редактирование исходного сообщения о коммите:
cherry-pick
оригинальный коммит как обычно.add
для постановки аннулирования.commit --amend
чтобы изменить направление на выбранный вишней коммит.источник
Это может быть другое решение, предназначенное для случаев, когда существует огромный коммит, и небольшое количество файлов необходимо перенести в новый коммит. Это будет работать, если набор
<path>
файлов должен быть извлечен из последнего коммита в HEAD и все перемещены в новый коммит. Если требуется несколько коммитов, могут использоваться другие решения.Сначала внесите исправления в поэтапную и непостановленную области, в которых будут содержаться изменения, к которым будет возвращаться код до модификации и после модификации соответственно:
Чтобы понять, что произойдет (стрелка и комментарии не являются частью команды):
Отменить
<path>
изменения в последнем коммите:Создать новый коммит с
<path>
изменениями:В результате создается новый коммит, содержащий изменения, извлеченные из последнего коммита.
источник