Git cherry pick и целостность данных - PullRequest
16 голосов
/ 13 апреля 2010

Учитывая, что две ветви разошлись, и для другой ветки необходимо ввести конкретную фиксацию от одной ветви (и не от всего), Git cherry pick достигает именно этого.

Через некоторое время возникает необходимость полностью объединить две ветви. Как git узнает, что у него уже есть коммит, который был выбран вишней в прошлом, чтобы он не вводил его заново?

Ответы [ 2 ]

28 голосов
/ 13 апреля 2010

Статья " избегая дублирования коммитов ", упомянутая в ответе tonio , гласит:

Представьте, что у нас есть основная ветвь и ветвь b:

  o---X   <-- master
   \
    b1---b2---b3---b4   <-- b

Теперь нам срочно нужны коммиты b1 и b3 в master, но не остальные коммиты в b. Итак, мы проверяем мастер-ветку и коммиты cherry-pick b1 и b3:

$ git checkout master
$ git cherry-pick “b1’s SHA”
$ git cherry-pick “b3’s SHA”

Результат будет:

  o---X---b1'---b3'   <-- master
   \
    b1---b2---b3---b4   <-- b

Допустим, мы делаем еще один коммит на master и получаем:

  o---X---b1'---b3'---Y   <-- master
   \
    b1---b2---b3---b4   <-- b

Если бы мы теперь слили ветку b в master:

$ git merge b

Мы получили бы следующее:

  o---X---b1'---b3'---Y--- M  <-- master
   \                     /
     b1----b2----b3----b4   <-- b

Это означает, что изменения, внесенные b1 и b3, появятся дважды в истории. Чтобы избежать этого, мы можем сделать ребаз вместо слияния:

$ git rebase master b

Что даст:

  o---X---b1'---b3'---Y   <-- master
                       \
                        b2---b4   <-- b

Наконец:

$ git checkout master
$ git merge b

дает нам:

  o---X---b1'---b3'---Y---b2---b4   <-- master, b

(после этой темы )


ОП добавляет в комментарии:

Но все же кажется, что я не совсем понимаю, как работает rebase ... Я имею в виду, что даже после перебазирования все равно не должны появляться выбранные вишни коммиты?

Нет. В справочной странице git commit прямо упоминается:

Если вышестоящая ветвь уже содержит изменения, которые вы внесли (например, из-за того, что вы отправили исправление, которое было применено в восходящем направлении), , тогда эта фиксация будет пропущена .
Например, запустив git rebase master в следующей истории (в которой A 'и A вводят одинаковый набор изменений, но имеют разную информацию о коммитере):

      A---B---C topic
     /
D---E---A'---F master

приведет к:

               B'---C' topic
              /
D---E---A'---F master

Вы можете определить наличие коммита на мастере с помощью git cherry master (если вы находитесь на ветке topic).

16 голосов
/ 13 апреля 2010

Возможно, вы захотите прочитать

Git Cherry-pick против Merge Workflow для хорошего сравнения между слиянием и cherry-pick, особенно в том, что cherry-pick не хранит родительский идентификатор и, следовательно, не знает, что у него уже есть коммит, который был выбран вишней в прошлом, чтобы он не вводил его заново.

и

http://davitenio.wordpress.com/2008/09/27/git-merge-after-git-cherry-pick-avoiding-duplicate-commits/ о том, как избежать дублирования коммитов в этом случае, используя rebase.

...