(Git) Какой самый практичный способ зафиксировать исправление в другой ветке, когда в вашей текущей ветке много изменений? - PullRequest
1 голос
/ 26 февраля 2020

Это сценарий:

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

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

Теперь, каков наиболее практичный способ получения изменений, не связанных с функциями, в другой ветви?


Разработка

"Прямой" способ справиться с этим - сохранить sh ваши изменения, проверить правильную ветку, зафиксировать ваши изменения, проверить функцию Снова ответвление, вставьте команду sh, возобновите работу. (При желании объединить в новую ветку.)

Хотя теоретически это просто, во многих случаях это может быть крайне непрактично и утомительно. Прежде всего, изменения, которые вы хотите перенести, спрятаны ... Так как именно вы вносите их в новую ветку? Вы могли бы, возможно, вставлять sta sh в новую ветку? Но если у вас есть несколько коммитов глубоко в вашей ветви функций, я бы не ожидал, что текущий sta sh будет совместим с ветвью разработки.

I wi sh Я мог бы просто зафиксировать офф-топи c изменяется, затем перемещайте этот коммит в другую ветку одной командой, не покидая мою текущую ветку.

NB: Я видел другие подобные вопросы к этому на SO, а именно, «как я могу зафиксировать изменения в другой ветви без проверки его». Ответы почти всегда «ты не можешь». Но это не то, о чем я здесь спрашиваю, я хочу знать наиболее практичный способ перенести ваши изменения в другую ветвь, когда вы в данный момент находитесь глубоко в ветви функций.

Ответы [ 4 ]

1 голос
/ 01 марта 2020

Я считаю полезным использовать git worktree.

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

  1. Sta sh Изменения очистки: Запустите git stash -p и выберите блоки, которые должны быть частью фиксации очистки. (Вы можете захотеть зафиксировать файлы, содержащие только изменения функций, чтобы уменьшить количество фрагментов до go.) Если блок содержит изменения как функций, так и очистки, вам нужно будет вручную удалить их, поэтому оставайтесь sh или нет, в зависимости от того, где вы хотите, чтобы этот блок изначально составлял go.

  2. Добавьте рабочее дерево (или перезапустите): Запустите git worktree add -b cleanup/the-thing-to-fix ../name_for_new_directory develop, чтобы создать ветку с именем cleanup/the-thing-to-fix основано на develop и проверено на новом рабочем дереве в ../name_for_new_directory.

  3. Переключиться на рабочее дерево: Выполнить cd ../name_for_new_directory

  4. Unsta sh изменяется с шага 1: Выполнить git stash pop. Это работает, потому что мы все еще в том же git репо / клоне, что и раньше, просто в отдельной ветке, извлеченной в отдельном каталоге.

  5. Передайте изменения очистки как обычно: Запустите git commit -a (или используйте любые опции, которые вы обычно используете для фиксации.

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

1 голос
/ 26 февраля 2020

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

Теперь, когда вы все зафиксировали или нет, следующий шаг зависит от того, можно ли с ним связываться текущий индекс и рабочее дерево . Если нет, и у вас есть Git 2.5 или более поздняя версия, предпочтительно 2.15 или более поздняя, ​​из-за довольно неприятной ошибки, впервые исправленной в 2.15, используйте git worktree add для создания нового рабочего дерева , настроенного на работайте в / в ветке, где вы хотите внести следующие исправления:

# this assumes you're in the top level of your repository
git worktree add ../quick-fix develop
cd ../quick-fix

Здесь ../quick-fix - это новое рабочее дерево, которое вы создадите, которое находится в ветке develop. Делая cd ../quick-fix - или, возможно, открывая новое окно терминала на вашем Ma c и заходя в каталог там - вы теперь работаете в своем основном репозитории, но в ветви develop, а не в ветви функций .

На данный момент, поскольку вы уже зафиксировали в своей ветке feature, у вас есть доступ к всем коммитам, которые вы сделали в своей ветви функций и можете использовать git cherry-pick, или git show | git apply, или , как вам нравится - любой из инструментов Git или любой из инструментов вашей системы - для работы в ветке develop. Если вы не сделали коммит, вы, конечно, не можете выбрать этот последний коммит.

Когда вы закончите обновлять ветку develop, вы можете вернуться к работе feature на ветке. дерево, запустите rm -rf ../quick-fix, чтобы удалить другое рабочее дерево, и запустите git worktree prune, чтобы получить git worktree, чтобы понять, что другое рабочее дерево теперь пропало. (Можно безопасно удалить, как только вы сделали все коммиты, которые вы намереваетесь сделать, но в какой-то момент вам нужно запустить git worktree prune, чтобы напомнить Git, что у вас больше нет develop.)

Если вы не можете или не хотите sh использовать git worktree add, вам придется работать в своем основном рабочем дереве, поэтому вам определенно нужно это сделать git commit. Теперь вы можете git checkout develop здесь, работать как обычно, и фиксировать как обычно Когда вы закончите, git checkout feature снова, чтобы вернуться к вашей функции.

В любом случае, вы вернулись к одному рабочему дереву, для которого feature извлечено. Теперь настало время удалить коммит, который вы сделали на feature, при условии, что вы сделали один на фиче. Чтобы удалить этот один коммит, запустите:

git reset HEAD^

(или используйте HEAD~ вместо HEAD^, если вам проще набирать текст и / или лучше в вашей оболочке / CLI, например, если ^ имеет особое значение для вашей оболочки). Это удаляет фиксацию и сбрасывает индекс, но сохраняет рабочее дерево от сделанного вами временного коммита.

Ключевые моменты

Мы делаем временный коммит , если необходимо. Это необходимо, если:

  • вы хотите выбрать из него вишню или
  • вы хотите повторно использовать ваше основное рабочее дерево и соответствующий ему индекс

В противном случае в этом нет необходимости.

Мы используем git worktree add для создания новой пары дерево-работа / индекс, которая позволяет вам выполнять работу в другой ветке, не мешая основной работе. дерево и главный индекс Git.

Мы используем git reset в режиме по умолчанию (--mixed), чтобы стереть временную фиксацию, как только мы закончим с ней. Это также сбрасывает индекс, поэтому, если вы используете индекс для специальных приемов - разреженного извлечения, или git update-index с --assume-unchanged или --skip-worktree - будьте здесь хотя бы немного осторожнее (но git reset действительно сочетается с этими ).

1 голос
/ 26 февраля 2020

Вы можете сделать следующее:

  1. Добавить и зафиксировать только те изменения, которые вы хотите использовать, используя git add --interactive (или, более конкретно, git add --patch). Подробнее здесь .
    git add --patch
    git commit
Sta sh другие изменения, go в develop ответвление.
    git stash
    git checkout develop
Применить только коммит с шага 1. к develop с feature.
    git cherry-pick <commit-id-from-step-1-in-feature>
Go вернуться в feature ветку и восстановить другие изменения.
    git checkout feature
    git stash pop
0 голосов
/ 27 февраля 2020
  • Работая над кодом, который вы не написали, вы замечаете и сразу исправляете ошибку
  • В качестве альтернативы вы замечаете, что в функции отсутствует документация, поэтому вы быстро добавляете несколько профессиональных советов для следующий разработчик, который придет

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

git checkout otherbranch
git commit -- files to change
git checkout -

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

Если вы сделали Изменения в файлах, которые также были изменены otherbranch, вы можете узнать о проверках слияния, добавить переключатель -m (также произносится как "magi c"). Практикуйте это с работой, которую вы git stash; git stash apply выполнили, чтобы вы могли легко git read-tree -um вернуть содержимое.

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