Есть ли способ автоматически отбрасывать измененные коммиты в git rebase?

Следующая ситуация возникает время от времени, когда я работаю с Git. Я начинаю с линейной истории, с двумя ответвлениями. Мастер в настоящее время указывает на C. Ветвь A — это ветвь, которую я прошу своих коллег объединить с мастером, а ветвь B имеет незавершенную работу, которую я еще не опубликовал.

 C
  \ 
   A - B

Во время проверки кода мой коллега замечает опечатку в последнем коммите в ветке A. Вместо того, чтобы создавать новый коммит только для исправления опечатки, я исправляю ошибочный коммит, и мы объединяем его с мастером. Мастер теперь указывает на A', что является фиксацией, исправляющей опечатку.

C - A'
 \
   A - B

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

C - A'
     \
      B

Однако по умолчанию Git предполагает, что коммиты A и A' совершенно не связаны, и вместо этого пытается сделать это:

C - A'
     \
      A - B

Что, наконец, подводит нас к моему вопросу:

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


person hugomg    schedule 06.07.2020    source источник


Ответы (2)


Это может быть достигнуто через git rebase --skip.

C - A'
     \
      B

Когда ветка B перебазируется на master, это будет то, что вы увидите:

error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

Затем вы можете сделать git rebase --skip, что пропустит коммит, и история git будет выглядеть чистой.

person bash    schedule 06.07.2020

Это не делает то, что вы просите, но в таких ситуациях я привык всегда использовать git rebase -i. Это позволяет:

  • Сначала удалите A из списка дел.
  • Избегайте создания фиксации A', которая еще не является предком для B. Вместо этого вы можете зафиксировать исправление опечатки как D:
    C
     \
      A - B - D
    
    А затем при запуске git rebase -i C вы можете изменить порядок списка дел, чтобы сделать D фиксацией исправления до A. Тогда вы получите:
    C
     \
      A' - B
    
    , которое является вашим желаемым конечным состоянием. (Если вы зафиксируете D через git commit --fixup A, то переупорядочение произойдет автоматически при запуске git rebase -i, если git.autosquash = true.)
person jamesdlin    schedule 06.07.2020
comment
К сожалению, это не помогает, если у меня есть две ветки, одна указывает на A, а другая на B. Если я перебазирую одну из них, то другая продолжит указывать на старую версию истории, которая будет включать A вместо A' . (Если нет способа перебазировать обе ветки одновременно... Есть ли?) - person hugomg; 07.07.2020