Как я могу объединить два коммита в один, если я уже начал rebase?


Я пытаюсь объединить 2 коммита в 1, поэтому я следовал "squashing commits with rebase" от git ready.

я побежал

git rebase --interactive HEAD~2

в появившемся редакторе, я меняю pick to squash а затем save-quit, но перебазировать не удается с ошибкой

не может 'сквош' без предшествующего совершению

теперь, когда мое рабочее дерево достигло этого состояния, у меня возникли проблемы с восстановлением. Команда git rebase --interactive HEAD~2 не с

интерактивная перебазировка уже началась

и git rebase --continue выдает

не может 'сквош' без предшествующего совершению

11   1017   2010-04-02 00:56:53

11 ответов:

резюме

сообщение об ошибке

не может 'сквош' без предшествующего совершению

означает, что вы, вероятно, пытались " раздавить вниз."ГИТ всегда патиссоны новый коммит в старой совершения или "вверх", как показано в интерактивном списке rebase todo, то есть в фиксацию на предыдущей строке. Изменение команды в самой первой строке списка задач на squash всегда будет производить эту ошибку как есть ничего для первого коммита, чтобы раздавить В.

Исправления

сначала вернитесь туда, где вы начали с

$ git rebase --abort

скажите, что ваша история

$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a

то есть a был первым коммитом, затем b и, наконец, c. после совершения c мы решили раздавить b и c вместе:

(Примечание: Работает git log трубит свой выход в пейджер,less по умолчанию на большинстве платформ. Для выхода из пейджера и вернуться к в командной строке нажмите кнопку q ключ.)

под управлением git rebase --interactive HEAD~2 дает вам редактор с

pick b76d157 b
pick a931ac7 c

# Rebase df23917..a931ac7 onto df23917
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

(обратите внимание, что этот список в обратном порядке по сравнению с выходом git log.)

изменение b pick до squash приведет к ошибке, которую вы видели, но если вместо этого вы раздавите c в b (более новая фиксация в более старую или "раздавливание вверх"), изменив список задач на

pick   b76d157 b
squash a931ac7 c

и сохранить-выход из вашего Редактор, вы получите другой редактор, содержимое которого

# This is a combination of 2 commits.
# The first commit's message is:

b

# This is the 2nd commit message:

c

когда вы сохраняете и выходите, содержимое отредактированного файла становится сообщением фиксации новой комбинированной фиксации:

$ git log --pretty=oneline
18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c
df239176e1a2ffac927d8b496ea00d5488481db5 a

Примечание О Переписывании Истории

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

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

уже опубликованные переписывание истории на ветке, в которой вы работаете с другими людьми без очень хорошая причина, такая как утечка пароля или других конфиденциальных деталей заставляет работать на ваших сотрудников и является антисоциальным и будет раздражать других разработчиков. Элемент "восстановление из раздела" Перемещение "вверх" в git rebase документация объясняет, с дополнительным акцентом.

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

Если есть несколько коммитов, вы можете использовать git rebase -i чтобы раздавить два коммита в один.

Если есть только два коммита, которые вы хотите объединить, и они являются "самыми последними двумя", для объединения двух коммитов в один можно использовать следующие команды:

git reset --soft "HEAD^"
git commit --amend

Rebase: вам это не понадобится:

простой способ для наиболее частого сценария.

в большинстве случаев:

на самом деле, если все, что вы хотите, это просто просто объединить несколько последних коммитов в один но не нужно drop,reword и другие работы по перебазированию.

вы можете просто сделать:

git reset --soft "HEAD~n"
  • предполагая, что ~n это количество коммитов для мягко un-commit (т. е. ~1, ~2,...)

затем используйте следующую команду для изменения сообщения фиксации.

git commit --amend

что довольно то же самое, что и большой диапазон squash и pick.

и он работает для n коммитов, но не только для двух коммитов, как указано выше.

сначала вы должны проверить, сколько совершает у вас есть:

git log

есть два состояния:

что есть только два коммита:

например:

commit A
commit B

(в этом случае вы не можете использовать git rebase для этого) вам нужно сделать следующее.

$ git reset --soft HEAD^1

$ git commit --amend

другой заключается в том, что существует более двух коммитов; вы хотите объединить коммит C и D.

например:

commit A
commit B
commit C
commit D

(под этим условие, вы можете использовать git rebase)

git rebase -i B

и чем использовать "сквош" делать. Остальное разжижается очень легко. Если вы все еще не знаете, пожалуйста, прочитайте http://zerodie.github.io/blog/2012/01/19/git-rebase-i/

предполагая, что вы были в своей собственной ветке темы. Если вы хотите объединить последние 2 коммита в один и выглядеть как герой, отделите коммит непосредственно перед тем, как вы сделали последние два коммита.

git checkout -b temp_branch HEAD^2

затем сквош совершает другую ветвь в этой новой ветви:

git merge branch_with_two_commits --squash

это внесет изменения, но не зафиксирует их. Так что просто совершите их, и все готово.

git commit -m "my message"

Теперь вы можете объединить эту новую ветку обратно в основную ветку.

вы можете отменить перебазирование с помощью

git rebase --abort

и когда вы снова запускаете интерактивную команду rebase, ' squash; commit должен быть ниже фиксации pick в списке

Я часто использую git reset --mixed чтобы вернуть базовую версию перед несколькими коммитами, которые вы хотите объединить, тогда я сделаю новую фиксацию, таким образом, вы можете позволить вашей фиксации самой новой, убедитесь, что ваша версия-это голова после того, как вы нажмете на сервер.

commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date:   Tue Jun 11 10:23:07 2013 +0500

    Added algorithms for Cosine-similarity

commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date:   Tue Jun 11 13:02:14 2013 -0700

    Set stage for similar objects

commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date:   Thu Jun 13 16:44:12 2013 -0700

    Fixed a bug in space world automation

если я хочу объединить два коммита head в один, сначала я использую:

git reset --mixed 249cf9392da197573a17c8426c282

"249cf9392da197573a17c8426c282" была третья версия, также ваша базовая версия перед слиянием, после этого я делаю новый совершают :

git add .
git commit -m 'some commit message'

Это все, надеюсь, это еще один способ для всех.

к вашему сведению, от git reset --help:

 --mixed
     Resets the index but not the working tree (i.e., the changed files are
     preserved but not marked for commit) and reports what has not been
     updated. This is the default action.

$ git rebase --abort

запустите этот код в любое время, если вы хотите отменить git rebase

$ git rebase -i HEAD~2

для повторного применения последних двух коммитов. Эта команда откроет редактор кода

  • [ последний коммит будет внизу ]. Изменить последнее совершите сквош(ы). Так сквош сольется с предыдущим коммитом.
  • затем нажмите клавишу esc и введите: wq для сохранения и закрытия

после :wq вы будете находиться в активном режиме перебазирования

Примечание: вы получите другой редактор, если нет предупреждений / сообщений об ошибках, если есть ошибка или предупреждение другой редактор не будет отображаться, вы можете прервать выполнение $ git rebase --abort Если вы видите ошибку или предупреждение еще просто продолжить, запустив $ git rebase --continue

вы увидите сообщение о фиксации 2. Выберите один или напишите свое собственное сообщение фиксации, сохраните и закройте [:wq]

Примечание. 2: возможно, вам придется принудительно перенести изменения в удаленное РЕПО, если вы запустите команду rebase

$ git push -f

$ git push -f origin master

если ваша главная ветвь git log выглядит примерно так:

commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date:   Tue Jun 11 10:23:07 2013 +0500

    Added algorithms for Cosine-similarity

commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date:   Tue Jun 11 13:02:14 2013 -0700

    Set stage for similar objects

commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date:   Thu Jun 13 16:44:12 2013 -0700

    Fixed a bug in space world automation

и вы хотите объединить два верхних коммита, просто выполните следующие простые шаги:

  1. во-первых, чтобы быть на безопасной стороне проверки второй последний фиксации в отдельной ветке. Вы можете назвать ветку чем угодно. git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
  2. теперь, просто вишня-выберите свои изменения из последнего фиксации в эту новую ветку как:git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e. (Разрешить конфликты, если они возникают)
  3. так что теперь, ваш изменения в последнем коммите есть в вашем втором последнем коммите. Но вам все равно нужно совершить, поэтому сначала добавьте изменения, которые вы просто выбрали, а затем выполните git commit --amend.

вот и все. Вы можете нажать эту объединенную версию в ветке "merged-commits", если хотите.

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

git checkout master
git reset --hard origin/master (CAUTION: This command will remove any local changes to your master branch)
git pull

С git cherry-pick для почти всего, для меня это естественно сделать даже здесь.

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

git checkout HEAD^ // Checkout the privious commit
git cherry-pick --no-commit branchX // Cherry pick the content of the second commit
git commit --amend // Create a new commit with their combined content

если я хочу обновить branchX а также (и я полагаю, что это обратная сторона этого метода) я также должен:

git checkout branchX
git reset --hard <the_new_commit>

Если вы хотите объединить два последних коммита и просто использовать сообщение старого коммита, вы можете автоматизировать процесс с помощью expect.

Я предполагаю, что:

  • вы используете vi в качестве редактора
  • ваши коммиты состоят из одной строки каждый

Я тестировал с git version 2.14.3 (Apple Git-98).


#!/usr/bin/env expect
spawn git rebase -i HEAD~2

# down, delete word, insert 's' (for squash), Escape, save and quit
send "jdwis 3:wq\r"

expect "# This is a"

# down 4, delete 3 lines, save and quit
send "4j3d\r:wq\r"

interact