Как создать ветку из конкретного коммита в другой ветке - PullRequest
58 голосов
/ 13 декабря 2011

Я сделал несколько коммитов в ветке master и затем объединил их в ветку dev.

Я хочу создать ветку из определенного коммита в ветке dev, который сначала был зафиксирован в master ветке.

Я использовал команды:

git checkout dev
git branch  <branch name> <commit id>

Однако это создает ветку из главной ветви, а не ветку dev, которую я ожидал. Идентификатор коммита одинаков в ветке master и dev. Итак, как я могу различить один и тот же идентификатор коммита в другой ветке?

PS: я сделал пример в github здесь https://github.com/RolandXu/test_for_branch

Я использовал команды:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8

Я ожидаю, что тестовая ветка содержит aa.txt bb.txt cc.txt. Тем не менее, тестовая ветвь содержит только aa.txt и cc.txt. Скорее всего, он создал ветку из главной ветви.

Ответы [ 5 ]

97 голосов
/ 13 декабря 2011

Если вы используете эту форму команды branch (с начальной точкой), не имеет значения, где находится ваш HEAD.

Что вы делаете:

git checkout dev
git branch test 07aeec983bfc17c25f0b0a7c1d47da8e35df7af8
  • Сначала вы установите HEAD для ветви dev,

  • Во-вторых, вы начинаете новую ветвь при коммите 07aeec98. На этом коммите нет bb.txt (согласно вашему репозиторию github).

Если вы хотите начать новую ветку в месте, которое вы только что извлекли, вы можете запустить ветку без начальной точки:

git branch test

или, как ответили другие, разветвите и оформите там за одну операцию:

git checkout -b test

Я думаю, что вы можете быть смущены тем фактом, что 07aeec98 является частью ветви dev. Это правда, что этот коммит является предком dev, его изменения необходимы для достижения последнего коммита в dev. Тем не менее, это другие коммиты, необходимые для достижения последней версии dev, и они не обязательно входят в историю 07aeec98.

8480e8ae (где вы добавили bb.txt), например, отсутствует в истории 07aeec98. Если вы переходите с 07aeec98, вы не получите изменений, внесенных 8480e8ae.

Другими словами: если вы объедините ветвь A и ветвь B в ветвь C, а затем создадите новую ветвь при коммите A, вы не получите изменений, внесенных в B.

То же самое здесь, у вас было две параллельные ветви master и dev, которые вы объединили в dev. Выход из коммита master (старше слияния) не даст вам изменений в dev.


Если вы хотите навсегда интегрировать новые изменения из master в ваши ветви функций, вы должны объединить master в них и продолжить. Тем не менее, это создаст коммиты слияния в ваших ветках объектов.

Если вы не опубликовали свои ветви функций, вы также можете перебазировать их на обновленном мастере: git rebase master featureA. Будьте готовы решать возможные конфликты.

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

  • основывать каждую новую функциональную ветвь на коммите master
  • создать ветку dev на коммите master
  • когда вам нужно увидеть, как ваша ветвь функций интегрируется с новыми изменениями в master, объедините как master, так и ветку Feature в dev.

Не используйте dev напрямую, используйте его только для объединения других ветвей.

Например, если вы работаете с функциями A и B:

a---b---c---d---e---f---g -master
    \       \
     \       \-x -featureB
      \
       \-j---k -featureA

Объедините ветви в ветку dev, чтобы проверить, хорошо ли они работают с новым мастером:

a---b---c---d---e---f---g -master
    \       \            \
     \       \            \--x'---k' -dev
      \       \             /    /   
       \       \-x----------    /    -featureB
        \                      /
         \-j---k--------------- -featureA

Вы можете продолжить работу над ветвями компонентов и регулярно добавлять новые изменения из основной и функциональных веток в dev.

a---b---c---d---e---f---g---h---i----- -master
    \       \            \            \
     \       \            \--x'---k'---i'---l' -dev
      \       \             /    /         /
       \       \-x----------    /         /  -featureB
        \                      /         /  
         \-j---k-----------------l------ -featureA

Когда пришло время интегрировать новые функции, объедините ветви функций (не dev!) В мастер.

32 голосов
/ 13 декабря 2011

У вас есть аргументы в неправильном порядке:

git branch <branch-name> <commit>

и для этого не имеет значения, какая ветвь проверена; это будет делать то, что вы говорите. (Если вы пропустите аргумент commit, по умолчанию будет создана ветка в том же месте, что и текущая.)

Если вы хотите проверить новую ветку при ее создании:

git checkout -b <branch> <commit>

с тем же поведением, если вы пропустите аргумент фиксации.

8 голосов
/ 13 декабря 2011

Вы должны сделать:

git branch <branch_name> <commit>

(вы обменивались именем ветви и коммитом)

Или вы можете сделать:

git checkout -b <branch_name> <commit>

Если на местеесли вы используете название ветки, вы получаете ветку из кончика ветки.

5 голосов
/ 13 декабря 2011

Попробуйте

git checkout <commit hash>
git checkout -b new_branch

Коммит должен существовать только один раз в вашем дереве, а не в двух отдельных ветвях.

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

1 голос
/ 11 мая 2019

Вы можете сделать это локально, как все упоминали, используя

git checkout -b <branch-name> <sha1-of-commit>

В качестве альтернативы, вы можете сделать это в самом github, следуя инструкциям:

1- В репозитории нажмите на Commits.

2- на коммите, с которого вы хотите разветвиться, нажмите <>, чтобы просмотреть хранилище на этом этапе истории.

commits history

3 - Нажмите на tree: xxxxxx в левом верхнем углу. Просто введите имя новой ветви и нажмите Create branch xxx, как показано ниже.

create new branch

Теперь вы можете получить изменения из этой ветки локально и продолжить оттуда.

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