Як створити гілку з конкретного коміту в іншій гілці


102

Я зробив кілька комітів у гілці master, а потім об’єднав їх у гілку dev.

Я хочу створити гілку з конкретного коміту у гілці dev, який вперше був здійснений у майстер-гілці.

Я використовував команди:

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

Однак це створює гілку з основної гілки, а не гілки розробника, яку я очікував. Ідентифікатор коміту однаковий у гілці 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. Швидше за все це створило гілку з основної гілки.

Відповіді:


145

Якщо ви використовуєте цю форму 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, і гілку функції в 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!) У master.


Дякую. Ви відповідаєте на моє запитання. Я неправильно розумію режим git branch. І чи маєте ви пропозицію щодо моєї проблеми. У мене є головна гілка, яка має багато вчасних комітів від інших (синхронізується з perforce). У мене є відділення розробників, я займаюся особистою роботою. Я хочу гілку, яка містить усі коміти з гілки master та dev, тоді я можу легко створити гілку на основі цієї гілки, а потім почати конкретну роботу.
RolandXu

Я не міг відповісти у коментарі, тому я оновлюю свою відповідь пропонованими робочими процесами.
Готьє

Гей - дякую за блискучу та ґрунтовну відповідь! Просто цікаво: Зрештою, навіщо це робити merge the feature branches (not dev!) into master?
cassi.lup

Справжньої нової розробки у devгалузі немає. Ви повинні зберігати особливість своїх філій. devмістить лише коміти злиття. Доцільніше об’єднати всі нові функції безпосередньо master, ніж об’єднувати разом функції, а потім об’єднувати результат master.
Готьє

@Gauthier Ви не зверталися до питання, чому. Для мене це звучить як злиття a devз просто функціями A Bта Cвлиття в нього masterідентично з’єднанню A Bта Cв master. Якщо ні, це заперечує моє розуміння того, як працює git, і мені було б дуже цікаво, чому?
Steven Lu

53

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

git branch <branch-name> <commit>

і для цього не має значення, яке відділення відмічається; він зробить те, що ти скажеш. (Якщо ви пропустите аргумент коміту, він за замовчуванням створює гілку там же, де і поточний.)

Якщо ви хочете перевірити нову гілку під час її створення:

git checkout -b <branch> <commit>

з такою ж поведінкою, якщо пропустити аргумент коміту.


22

Ви можете зробити це локально, як усі згадані користувачі

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

Крім того, ви можете зробити це в самому github, виконавши кроки:

1- У сховищі натисніть на Commits.

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

здійснює історію

3- Клацніть на tree: xxxxxxвгорі ліворуч. Просто введіть нову назву гілки, клацніть там, Create branch xxxяк показано нижче.

створити нову гілку

Тепер ви можете отримати зміни з цієї гілки локально та продовжити звідти.


Це те, що мені потрібно було .. Як це зробити на веб-сайті
eharo2

Я ніколи цього не знав. Це воно. Графічний інтерфейс просто чудовий, і я хотів бути подалі від CLI.
Рохіт Гупта,

10

Спробуйте

git checkout <commit hash>
git checkout -b new_branch

Фіксація повинна існувати лише один раз у вашому дереві, а не в двох окремих гілках.

Це дозволяє вам перевірити конкретний коміт і назвати його як завгодно.


привіт, я пробую git log dev та git log master, я виявив, що ідентифікатор хеш-
коміту однаковий для коміту,

може допомогти використовувати щось на зразок gitkвізуалізації вашого журналу
ZMorek

Я нещодавно додав приклад у github. І Готьє вже відповідає на моє запитання про те, що я неправильно розумію режим git branch. Дякую :)
RolandXu

Я думаю, що це гостра відповідь. Дякую
virusss8,

9

Ви повинні зробити:

git branch <branch_name> <commit>

(ви міняли місцями назву філії та коміт)

Або ви можете зробити:

git checkout -b <branch_name> <commit>

Якщо замість вас використовується назва гілки, ви отримуєте гілку з кінчика гілки.


Це не HEADозначає. Замість цього можна сказати "кінчик гілки" або "коміт, на який вказує гілка".
Cascabel

@Jefromi - Будучи пуристами, ми можемо сказати лише гілку, оскільки сама гілка є вказівником на, ну, кінчик гілки.
manojlds
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.