Git обновить мою удаленную ветку из другой удаленной ветви

У нас есть основная ветвь, называемая "разработка", поэтому всякий раз, когда мы разрабатываем функцию, мы делаем локальную ветку функции из "разработки", а затем объединяем ее для разработки.

Теперь дело в том, что
1. Пользователь1 должен был создать ветку функций из 'Develop' (скажем, Feature1), и он должен опубликовать ее в Git. Готово.
Так что теперь, "разработка" и "функция1" - это две разные ветви в Git, и изменения в "функция1" не объединены в "разработка", поскольку "функция1" все еще находится в стадии разработки.
2. Позже функция, которую я начал реализовывать, имела некоторую зависимость от "feature1". Поэтому я клонировал ветку 'feature1' из git и решил обновить свои изменения, думая, что 'feature1' уже был обновлен из ветки 'Develop'.
3. Но позже я обнаружил, что ветка 'feature1' НЕ обновляется с некоторыми недавними изменениями из ветки 'Develop'.
4. Теперь мне нужно, чтобы изменения в ветке 'development' были обновлены в ветке 'feature1' перед обновлением моих изменений.

Любой возможный способ сделать это с помощью команд GIT?

2 ответа

Решение

Из того, что я собрал, это ситуация в вашем хранилище:

                  develop
                    ↓
A -- A -- B -- C -- C
           \
            F -- F -- F
                      ↑
                   feature1

Итак, совершает A это коммиты на разработку, которые существовали раньше. B является базовым коммитом, который был разработан при создании ветки объектов. F коммиты, которые были сделаны в ветви функций, и C это коммиты, которые были сделаны при разработке после того, как ветка возможностей уже была создана и над ней работали.

Теперь, что вы хотите сделать, это продолжить работу над веткой возможностей, в то время как в зависимости от изменений, которые были внесены с коммитами C, Это правильно?

В этом случае, предполагая, что вы не являетесь тем же разработчиком, что и пользователь 1, самый безопасный способ ввести эти изменения в ветку возможностей - просто объединить их. Так что, выбрав Feature1, просто объедините развитие с помощью `git merge develop*. Тогда история будет выглядеть так:

                      develop
                         ↓
A -- A -- B ---- C ----- C
           \              \
            F -- F -- F -- M
                           ↑
                        feature1

Таким образом, вы просто объединяете изменения, а затем можете продолжить работу над ними. Фактически, вы можете продолжать делать это несколько раз по мере роста как функции1, так и разработки:

                                     develop
                                        ↓
A -- A -- B ---- C ----- C -- C -- C -- C
           \              \         \    \
            F -- F -- F -- M -- F -- M -- M -- F
                                               ↑
                                            feature1

И как только вы закончите с веткой возможностей, вы можете просто объединить ее с разработкой:

                                              develop
                                                 ↓
A -- A -- B ---- C ----- C -- C -- C -- C ------ M
           \              \         \    \      /
            F -- F -- F -- M -- F -- M -- M -- F

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


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

Допустим, вам нужен только первый коммит C из самого первого графика, показанного выше. Тогда вы могли бы сделать git cherry-pick C1 чтобы скопировать его в ветку функций:

                  develop
                     ↓
A -- A -- B -- C1 -- C2
           \
            F -- F -- F -- C1'
                            ↑
                        feature1

Это создает копию C1' который включает в себя те же изменения, что и его оригинал C1 (но все еще другой объект фиксации). Затем вы можете продолжить работу над веткой функций с учетом этих изменений.


Наконец, оставшаяся альтернатива будет перебазировать. Перебазирование переписывает историю, поэтому снова, начиная с самого первого графика, вы можете получить следующее, запустив git rebase develop:

                 develop
                    ↓
A -- A -- B -- C -- C
                     \
                      F' -- F' -- F'
                                  ↑
                               feature1

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

Это заставляет других разработчиков, в частности, вашего "пользователя 1", который работает и над веткой feature1, сталкиваться с конфликтами, когда они пытаются включить ваши изменения. Исправление, которое потребует от них ручного исправления, и, если вы не скажете им, они могут даже не заметить (что делает историю очень грязной и в результате несколько сломанной).

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

  1. Rebase feature1 в develop в локальном репо. Это перемотает любые изменения в feature1, объединить develop в feature1, а затем повторите ваши изменения.

git checkout feature1

git rebase develop

  1. Принудительно подтолкнуть локальное репо к основному репо.

git push -f

  1. Перебазируй свою ветку (скажем, feature2) чтобы feature1,

git checkout feature2

git rebase feature1


Ссылка: https://git-scm.com/book/en/v2/Git-Branching-Rebasing

Надеюсь это поможет!

РЕДАКТИРОВАТЬ: прочитайте ответ poke, потому что это сделает локальный репо других разработчиков несколько сломанным.

Другие вопросы по тегам