Изменить Git Commit, из которого появляется другая ветвь - PullRequest
0 голосов
/ 04 марта 2019

Допустим, у меня есть коммит A на магистрали ветки, который в данный момент не передан (например, потому что он проверяется кодом).

Тем временем я хочу начать работу над новой функцией B, основанной на коммите A, поэтому я создаю другую ветку и начинаю работать над ней.Это текущая ситуация:

--- A
     \
      -- B

Тем временем (например, из-за того, что из обзора кода выяснилось, мне нужно что-то изменить), я делаю некоторые изменения для фиксации A.Теперь я хочу изменить коммит А, чтобы включить новые изменения.То, что происходит с коммитом B, по крайней мере, в моей голове, выглядит примерно так:

   ----- A
  /
---- ?
      \
       ---- B

Где ? - это старый, еще не исправленный коммит A, который сейчас не 'больше не существует.Я предполагаю, что это не очень хорошая идея.

Так что будет правильным способом сделать это?

Я думал не вносить поправки в A, а вместо этого создать новый коммит A':

--- A ----- A'
     \
      -- B

Затем, когда я буду готов выдвинуть функцию A, "вишня" A' на B, а затем перебазировать B на A':

--- A -- A'
          \
           -- B

Наконец, сквош A и A', и нажмите A.

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

Есть ли лучший способ?

1 Ответ

0 голосов
/ 04 марта 2019

Вот почему я продолжаю говорить людям, что буквально изменить коммит буквально невозможно.

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

Если вы рисуете график немного дальше, он может выглядеть следующим образом:

...--H--A   <-- mainline
         \
          B   <-- another

Когда вы переходите к «исправлению» коммита A (предположительно с использованием git commit --amend), его буквально невозможно изменить.В конечном итоге вы делаете новый коммит A' и коммит A все еще существует , просто mainline больше не указывает на него и не включает его в набор коммитов, достижимый при запускеот вершины и работая в обратном направлении:

       A'  <-- mainline
      /
...--H--A
         \
          B   <-- another

Набор коммитов, который уникален для another, или, что эквивалентно, набор коммитов , достижимый с another, но не из mainline, выросло, и ничего в самом графике коммитов не изменилось.Это связано с тем, что набор коммитов , достижимый из mainline, изменился, поскольку изменился сам mainline.

Метки перемещаются.Коммиты не делают!

Обратите внимание, что, подобно git commit --amend, git rebase также не меняет никаких существующих коммитов.Вместо этого он (обычно) копирует фиксирует, затем перемещает метки.(«Обычно» здесь только потому, что есть несколько случаев, когда rebase решает, что не нужно выполнять работу, и оставляет существующие коммиты на месте. Вы можете принудительно копировать в любом случае, если есть какая-то причина, по которой вы хотите все новые коммиты с новыми идентификаторами хеша), но по умолчанию выявляется эта ситуация и сохраняется как можно больше.)

Следовательно, поскольку evolutionxbox и phd оба сказали в комментариях, ваша ситуация такая жеВ любом случае: вырвав имя mainline из коммита A, вы захотите скопировать коммит B в какой-то новый B', чей родитель A':

       A'  <-- mainline
      / \
...--H   B'   <-- another
      \
       A--B   [abandoned, but remembered for some time]

В конце концов - обычнокогда-нибудь через 30 дней или более, после отказа от одного или нескольких таких коммитов Git будет собирать мусор нежелательных коммитов.

Сложная часть использования git rebase для копирования *От 1064 * до B' заключается в том, что если существуют существенные различия в A против A', ваш Git по умолчанию будет считать, что коммит A должен быть скопирован снова , производя -или пытаясь получить:

       A'  <-- mainline
      / \
...--H   A"-B'   <-- another
      \
       A--B   [abandoned, but remembered for some time]

(возможно, с большим количеством конфликтов слияния между A' и A").Предотвратить это можно несколькими способами, например, используя git rebase -i или git rebase --onto.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...