Nano Hash - криптовалюты, майнинг, программирование

Как разделить текущие изменения на несколько новых веток git?

Я сделал несколько десятков правок в новой ветке git, которую назвал «производительность». Теперь я получил приказ разделить эти правки на несколько веток, называемых «производительность-внешний интерфейс», «производительность-регистрация» и т. д.

Я подумал: создать новую ветку, не изменяя извлеченные файлы, добавить соответствующие файлы, зафиксировать, повторить.

Можно ли это сделать? Есть ли другой (установленный) способ?

05.10.2017

  • редактирует или фиксирует? 05.10.2017
  • Если то, что вы называете правками, является фиксацией, то один из способов — использовать git cherry-pick. 05.10.2017
  • Пока ничего не сделано, чтобы оставить мои варианты разделенной фиксации открытыми. Конечно, я могу зафиксировать все в текущем каталоге, если это так работает. 05.10.2017
  • Если у вас есть незафиксированные изменения, создайте ветку, проиндексируйте некоторые изменения и зафиксируйте, снова проверьте производительность, повторите. 05.10.2017

Ответы:


1

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

Current state:
... -- A (master) -- C1 -- B1 -- B2 -- C2 -- B3 -- C3 -- B4 (devel)

Wanted state:
... -- A (master) -- B1’ -- B2’ -- B3’ -- B4’ (branch-B)
        \
         `---------- C1’ -- C2’ -- C3’ (branch-C)

В моем случае это состояние было достигнуто после беспорядочных экспериментов путем мягкого сброса до master и внесения изменений построчно с помощью git gui, помечая каждое изменение сообщением фиксации A или B. Итак, давайте предположим, что такая подготовка уже произошла, и коммиты An, Bn уже четко разделены.

Сбор вишен вручную может привести к ошибкам, так как в длинных последовательностях коммитов легко пропустить один. Поэтому вместо этого мы используем git rebase -i во временной ветке, чтобы быть в безопасности.

>> git checkout devel
>> git checkout -b tmp

... -- A (master) -- C1 -- B1 -- B2 -- C2 -- B3 -- C3 -- B4 (devel, tmp, HEAD)

>> git rebase -i master

Это откроет файл задачи перебазирования. По умолчанию это

pick 552fe03 C1
pick cbf327a B1
pick bd1ca26 B2
pick 95320e6 C2
pick 7f21156 B3
pick 910a6fe C3
pick bfda579 B4

По сути, это «сбрасывает ветку на master, затем выполняет команды, перечисленные в файле перебазирования». При настройке по умолчанию он по существу перестраивает ветку, оставляя все без изменений.

1. Изменение порядка коммитов.

Поэтому вместо этого мы переупорядочиваем коммиты.

pick cbf327a B1
pick bd1ca26 B2
pick 7f21156 B3
pick bfda579 B4
pick 552fe03 C1
pick 95320e6 C2
pick 910a6fe C3

В зависимости от того, какие изменения были внесены, могут возникать конфликты слияния, которые необходимо разрешить, прежде чем rebase можно будет продолжить с git rebase --continue.

Может быть полезно перемещать только один коммит за раз, повторяя git rebase -i master несколько раз; В противном случае вы рискуете потерять работу, если вам придется прервать перебазирование.

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

... -- A (master) -- C1 -- B1 -- B2 -- C2 -- B3 -- C3 -- B4 (devel)
        \
         `-- B1 -- B2 -- B3’ -- B4’ -- C1’ -- C2’ -- C3’ (tmp, HEAD)

2. Создайте ветки.

Теперь мы можем создать новые ветки,

>> git branch branch-C tmp
>> git branch branch-B <hash-of-B4’>

Предоставление состояния

... -- A (master) -- -- B1 -- B2 -- C1 -- B3 -- C2 -- C3 -- B4 (devel)
        \
         `-- B1’ -- B2’ -- B3’ -- B4’ (branch-B) -- C1’ -- C2’ -- C3’ (tmp, branch-C, HEAD)
         

3. Разъединить их еще одним ребазом.

Как описано в этом ответе на Разделить ветку git на две ветки?, теперь мы можем использовать команду rebase вида

>> git rebase --onto NEW_PARENT OLD_PARENT BRANCH_TO_MOVE

в таком случае:

>> git rebase --onto master branch-B branch-C 

... -- A (master) -- B1 -- B2 -- C1 -- B3 -- C2 -- C3 -- B4 (devel)
       |
       |`-- B1’ -- B2’ -- B3’ -- B4’ (branch-B) -- C1’ -- C2’ -- C3’ (tmp)
       |
        `-- C1’’-- C2’’-- C3’’ (branch-C, HEAD)
        

Если все сработало, остается только принудительно удалить устаревшие/временные ветки (обычное удаление с -d здесь не работает).

>> git branch -D devel
>> git branch -D tmp

... -- A (master) -- B1’ -- B2’ -- B3’ -- B4’ (branch-B)
        \
         `---------- C1’’-- C2’’-- C3’’ (branch-C, HEAD)
         

Без временных ответвлений.

Конечно, вам не обязательно использовать временные ветки. Тогда команды будут

>> git checkout devel
>> git rebase -i master     # for reordering
>> git branch -m branch-C   # rename ‘devel’ to ‘branch-C’
>> git branch branch-B <hash-of-B4’>
>> git rebase --onto master branch-B branch-C

Но перебазирование может дать сбой, и его легче восстановить при использовании ветвей, чем восстанавливать правильное состояние из git reflog.

11.12.2020

2

Ну, вы можете сделать это несколькими способами. Но самое простое имхо это:

Сбросьте свою ветку обратно к коммиту, с которого вы начали (нет --hard!). После этого вы должны увидеть все изменения, которые вы сделали в git status.

Теперь, после этого, используйте свой любимый git gui, или git add -i, для выборочной подготовки только тех изменений, которые вы хотите, и повторите их, как вам нравится.

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

Черт, вы даже можете скопировать свои изменения, проверить начальную точку и скопировать их обратно, а затем зафиксировать их. (это не так основано на git: D), и есть и другие способы

Так что, как обычно, с git вы можете сделать это множеством разных способов.

05.10.2017

3

Вы можете сделать git add/git commit в текущей ветке и создать несколько коммитов (каждый коммит должен влиять на набор файлов, которые вы хотите рассматривать в одной ветке). Затем создайте ветки и выберите вишню, как предлагает @axiac. Или создайте ветки, проверьте каждую ветку и скопируйте соответствующие файлы: это сложнее, если вы не используете рабочие деревья, поскольку при извлечении новой ветки измененные файлы в ветке производительности не обязательно будут видны.

05.10.2017
Новые материалы

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

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..