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, сталкиваться с конфликтами, когда они пытаются включить ваши изменения. Исправление, которое потребует от них ручного исправления, и, если вы не скажете им, они могут даже не заметить (что делает историю очень грязной и в результате несколько сломанной).
Поэтому, если вы не знаете, что делаете, вы никогда не должны отменять коммиты, которые были опубликованы ранее. Даже если это означает, что ваша история в результате будет выглядеть не так красиво.
- Rebase
feature1
вdevelop
в локальном репо. Это перемотает любые изменения вfeature1
, объединитьdevelop
вfeature1
, а затем повторите ваши изменения.
git checkout feature1
git rebase develop
- Принудительно подтолкнуть локальное репо к основному репо.
git push -f
- Перебазируй свою ветку (скажем,
feature2
) чтобыfeature1
,
git checkout feature2
git rebase feature1
Ссылка: https://git-scm.com/book/en/v2/Git-Branching-Rebasing
Надеюсь это поможет!
РЕДАКТИРОВАТЬ: прочитайте ответ poke, потому что это сделает локальный репо других разработчиков несколько сломанным.