Подтвердить что ты не робот

GIT: фиксировать изменения в старой/безопасной ветке, в то время как в новой/грязной/dev ветке, не проверяя или не потеряв неустановленные данные

Я создал новую ветвь, прежде чем начал работать над чем-то экспериментальным. Обычно я забываю (что не проблема), но теперь я сделал это заранее.
С тех пор я обновил 3 файла.

  • В 2 только экспериментальные изменения, которые я НЕ хочу передать безопасной ветке.
  • В 1 только безопасные (незначительные) изменения, которые я определенно хочу передать в безопасную ветку. Я в порядке с этими последними изменениями, которые должны быть привязаны к новой ветке (а скорее нет).

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

Единственное, о чем я могу думать, это переключение ветвей (без проверки), фиксация изменений в 1 файле и возврат обратно, но я не знаю, что произойдет с изменениями при переключении обратно в грязную ветвь ( они все еще там или "исчезли" из-за фиксации?)...

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

Спасибо! На данный момент я просто сделаю кусок бумаги удобной с изменениями, чтобы "совершить безопасную ветку позже".

4b9b3361

Ответ 1

Итак, ваша ситуация

x--x--x (safe)
       \
        <a,b,c> (3 private evolutions in exp branch)

И вы хотите перейти на

x--x--x--a (a committed only in safe banch)
       \
        b,c (b and c commited in exp branch)

Вы можете:

git add a
git commit -m        # in exp branch, gasp!
git stash save       # save the rest of the exp work in progress
git checkout master
git merge exp        # fast-forward merge

x--x--x--a (safe,exp)
          \
           [b,c] (stashed)

git branch -f exp HEAD~1  # reset branch exp to before 'a'
git checkout exp
git stash pop
git add -A
git commit -m "..."

x--x--x--a (a committed only in safe banch)
      \
        b,c (b and c commited in exp branch)

Ответ 2

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

Простой случай: просто используйте git checkout

При переключении ветвей проверка git сохраняет незафиксированные изменения или отказывается переключаться (если вы не используете --force, --merge или --conflict). Таким образом, до тех пор, пока ваши незаблокированные изменения будут касаться только тех файлов, которые совпадают как в HEAD (текущая ветка), так и в ветке назначения, git checkout оставит эти изменения в индексе и/или рабочем дереве при переключении ветвей. Если ваши незафиксированные изменения удовлетворяют этому условию, вы можете сделать это:

git checkout safe-branch
git add -- files-with-safe-changes
git commit
git checkout -

Вы также можете использовать git add --patch для создания и фиксации только некоторых изменений в файлах.

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

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

git stash save
git merge safe-branch
git stash pop --index

Если ваши другие изменения не зависят от "безопасных изменений", то вы, вероятно, не должны беспокоиться о слиянии или перебазе. В конце концов вы объедините эти ветки вместе (например, объединив их обоих в "qa-ветку для тестирования перед выпуском" ), но нет причин для их слияния преждевременно.

Все еще легко, но немного рискованно: git checkout -m

Если первая проверка git жалуется "У вас есть локальные изменения на some‑file, а не на переключение ветвей". Это означает, что у вас есть несоответствующие изменения в some-file и что файл отличается в советах "безопасных", ветвь и текущая ветка; вам понадобится другой подход.

Если вы уверены, что изменения будут применяться чисто к версии some‑file, которая находится в разделе "безопасная ветвь", вы можете использовать опцию -m/--merge, чтобы сообщить git checkout, чтобы попытаться адаптируйте изменения, чтобы они применимы к файлам в "безопасной ветке". Если слияние не может быть выполнено чисто, тогда вы столкнетесь с конфликтом слиянием, и может быть сложно восстановить исходные изменения (поэтому я называю это "рискованным" ).

Сейф: git stash + git checkout -m

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

git stash save
git checkout stash -- files-with-save-changes
git checkout -m safe-branch
git commit
git checkout -
git stash pop --index

Возможны и другие варианты. Вы можете использовать git checkout -p stash -- files, чтобы выбрать только некоторые изменения в этих файлах. Если в индексе нет ступенчатых изменений, вы можете сначала выполнить "безопасные изменения" , git add -- files (опять же, при необходимости с -p), использовать git stash save --keep-index, переключить ветки (слиянием), а затем зафиксировать ( т.е. замените git checkout stash -- files на предустановленные "безопасные изменения" и git stash --keep-index).

В этой ситуации я считаю git checkout -m безопасным, потому что мы использовали git stash для сохранения копии текущих изменений; если попытка трехстороннего слияния приводит к безнадежной беспорядку, то вы можете легко отказаться от идеи "безопасных изменений" на "безопасной ветке" и вернуться к работе: вернитесь к своей исходной ветке и поместите занос (git checkout -f - && git stash pop).

Опять же, если ваши другие изменения зависят от "безопасных изменений", вам необходимо объединить или переустановить. Вы также можете сделать это, прежде чем выталкивать кошелек (поскольку для выполнения слияния/переустановки вам нужен чистый индекс и рабочее дерево).

Если вы не собираетесь объединить свою рабочую ветку с (или переадресовать ее) на "безопасную ветвь" сразу, вы, вероятно, захотите отменить "безопасные изменения" после того, как вы закроете тайник ( "безопасные изменения" "были сохранены в исходном кошельке, и вы, вероятно, не хотите заканчивать коммитами, которые вносят те же самые изменения с нуля в две разные ветки 2). После того, как вы вытащили тайник, используйте git checkout -- files-with-safe-changes, чтобы вернуть эти файлы обратно в версии на кончике рабочей ветки.


<суб > 1 Интерфейс "сантехника" предназначен для использования в сценариях. Было бы громоздко использовать их непосредственно в командной строке. Ранними версиями команд git commit (и большинства других git) были shell-скрипты, основанные на этом интерфейсе. Они все еще могут быть написаны как сценарии оболочки сегодня, но версии C, как правило, намного быстрее. Шаги, необходимые для фиксации альтернативной ветки:
настройте альтернативный индекс на основе дерева в конце "безопасной ветки",
обновить индекс с помощью "безопасных" изменений (что, если изменения не могут быть применены чисто? приятно иметь рабочее дерево, чтобы позволить пользователю разрешить конфликты),
напишите индекс как объект дерева,
создать новый объект фиксации, который указывает на новое дерево и имеет текущий совет "безопасной ветки" в качестве родительского объекта,
обновите ссылку "безопасная ветка", чтобы указать на новую фиксацию.
Суб >

<суб > 2 Нет ничего технически неверного в том, что вы совершаете свои "безопасные изменения" в двух ветвях, но обычно рекомендуется убедиться, что каждое изменение происходит только из одного места. Суб >

Ответ 3

Так как ветвящиеся операции на GIT настолько дешевы, я бы просто использовал следующий рабочий процесс:

  • Создайте новую ветку с вашей "экспериментальной" ветки
  • передать любые неустановленные файлы.
  • вернуться к мастеру
  • cherrypick независимо от того, что происходит от вашего "экспериментального" и нового ветки, только что созданного на шаге 1.
  • вернуться к "экспериментальной" ветке