Git: перемещение изменений от главной ветки
Основной вопрос, но это происходит со мной все время:
- Внесите изменения в
working-branch
- Переключитесь на
master
-
git merge working-branch
-
git push
-
cap deploy
(для постановки)
- сделайте новую чашку чая
тогда я возвращаюсь и думаю о чем-то другом и начинаю вносить некоторые изменения... пока все еще на хозяине.
Какой простой способ:
- предотвращать прямые изменения на главном устройстве (возможно, предупреждение)
- чтобы переместить все изменения на
working-branch
и очистить master
, поэтому я могу продолжить редактирование на working-branch
- чтобы отменить редактирование в совершенно новую ветвь
new-working-branch
, а затем отбросить working-branch
?
Взял на себя риск и попробовал рекомендации в последней части раздела "Филиалы" на этой странице, но это просто уничтожило ВСЕ мои изменения!?! возможно, потому что после git branch dubious-experiment
и git checkout master
git status
на обеих ветвях был идентичен (не "чистый" на главном). Итак, git reset --hard <SHA1sum>
уничтожило все изменения на обоих!?!
git branch dubious-experiment
M---N-----O----P---Q ("master" and "dubious-experiment")
git checkout master
# Be careful with this next command: make sure "git status" is
# clean, you're definitely on "master" and the
# "dubious-experiment" branch has the commits you were working
# on first...
git reset --hard <SHA1sum of commit N>
Ответы
Ответ 1
Из вашего описания я предполагаю, что вы еще не совершили никаких изменений - это правильно?
Если да, то ваши ответы:
Как предотвратить прямые изменения мастера
Вам нужно будет установить это в своем редакторе, но это, вероятно, будет сложно. Отображение текущей ветки в вашем приглашении, и ваш редактор очень помогает.
Как переместить изменения в новую ветвь new-working-branch
, а затем сбросить working-branch
git checkout -b new-working-branch
git add …
git commit -m "mycommit"
Поскольку вы ничего не делали для освоения, вам не нужно ничего менять на хозяине. Теперь вы можете отказаться от своей рабочей ветки, если вам так хочется.
Как перенести изменения на working-branch
git checkout -b temp-branch
git add …
git commit -m "mycommit"
git rebase --onto working-branch master
git checkout working-branch
git reset --hard temp-branch
git branch -d temp-branch
Если ваши изменения не противоречат любым изменениям, которые находятся на главном, но не в рабочей ветке, это можно сделать намного проще:
git stash
git checkout working-branch
git stash pop
Ответ 2
Если вы уже внесли свои изменения в master
, но не нажали нигде...
создать новую ветку для последних изменений
git checkout -b newfeat master
воспроизвести все изменения (переместить фиксации) поверх ветки working-branch
git rebase --onto working-branch origin/master newfeat
измените на master
ветку и reset на состояние последнего нажатия
git checkout master
git reset --hard origin/master
В этот момент у вас есть:
-
master
, указывая на последнюю нажатую фиксацию (origin/master
)
-
working-branch
никогда не менялся
- новая ветвь
newfeat
, содержащая все новые коммиты и опережающая working-branch
.
Ответ 3
Я использовал для подобных случаев:
git branch -f <branch-name>
git checkout <branch-name>
или
git checkout -B <branch-name>
.
Оба варианта перемещают ветвь branch-name
в вашу текущую фиксацию с отсутствием рестайлинга - ваше дерево.
Ответ 4
Обычно я рекомендую следующую настройку Git:
git config push.default nothing
При этом вы, по крайней мере, должны будете назвать ветку, когда будете нажимать. Это не помешает вам совершать локальные действия, но когда вы поймете, что у вас есть, вы можете переместить эти коммиты в ветку, не затрагивая никого.
Ответ 5
Получите привычку печатать $ git status
, прежде чем на самом деле выполните команду git, которая что-то изменит.
Учитывая, что вы, вероятно, отредактировали свой файл, но не проверили его, потому что вы должны выполнить git status
перед фиксацией. В этом случае git делает правильную вещь, если вы просто переключаете ветки, а затем фиксируете.
Если вы уволили фиксацию на мастер, просто переместите файл между ветвями примерно так:
$ git checkout --patch master <somefile>
Вам действительно не нужно работать с reset master, если вы просто собираетесь объединить с ним один и тот же файл, но поскольку, предположительно, вы ничего не нажали, вы должны просто reset на свои удаленные ветки отслеживания..
$ git reset master origin/master
$ git reset stage origin/stage # whatever
Ответ 6
1. предотвращать прямые изменения на главном устройстве (возможно, предупреждение)
Вы не единственный, кто хочет этого. Лучшая идея, с которой я столкнулся, заключается в том, чтобы поместить ветвь git непосредственно в приглашение оболочки. Мое приглашение выглядит так:
[[email protected] directory:git_branch]
Я также окрашиваю запись git_branch, поэтому совершенно очевидно, над чем я постоянно работаю. Эти две ссылки на Qaru должны помочь с вашим приглашением.
2. чтобы переместить все изменения в рабочую ветвь и очистить мастер, чтобы я мог продолжить редактирование на рабочей ветке
или
3. свернуть правки в совершенно новую ветвь новой рабочей ветки, а затем отменить рабочую ветвь?
Это действительно тот же вопрос - как перемещать изменения от мастера на ветку, будь то старая ветка или новая ветка. И ваш собственный ответ правильный. Хотя на первый взгляд, если вы на хозяине, вы можете просто запустить:
git branch new_branch
git reset --hard origin/master
Я предпочитаю просто reset master для origin/master, а не беспокоиться о конкретной команде SHA. Но ваши шаги были в основном правильными. Что касается того, почему вы потеряли изменения, мне пришлось бы думать, что по ошибке не было указателя ветки на Q, когда вы reset master. Никакое другое объяснение не имеет смысла. Опять же, подсказка командной оболочки ветки поможет избежать этих ошибок. Более того, я большой поклонник использования gitk или git log -graph, чтобы проверить, где находятся мои ветки, прежде чем я их перемещу. Поскольку я не могу легко использовать gitk на работе, у меня есть псевдоним в моем .gitconfig, называемом "graph", который по существу является версией для командной строки:
[alias]
graph = log --graph --all --date=short --pretty=format':%C(yellow)%h%Cblue%d%Creset %s %Cgreen %aN, %ad%Creset'
Это покажет график слева, фиксация SHA желтым, ветки синим цветом, сообщение фиксации в белом, а автор и дата зеленым. Конечно, это может быть изменено по своему усмотрению.
[отредактировано, чтобы упростить приведенные выше команды]
==============================
В ответ на комментарий ниже:
Начните с
A-B < origin/master
\
C-D < master
Теперь выполните git checkout -b new_branch
A-B < origin/master
\
C-D < master, new_branch
Теперь мастер проверки, git checkout master
. Обратите внимание, что git checkout -b new_branch && git checkout master
совпадает с git branch new_branch
, если вы уже были на хозяине. Я отредактировал вышеупомянутый ответ, чтобы отразить это.
Теперь reset мастер в начало/мастер, git reset --hard origin/master
A-B < master, origin/master
\
C-D < new_branch
Поскольку у вас была ветка (new_branch), указывающая на D, никаких изменений не было потеряно. Если я допустил ошибку, пожалуйста, уточните, где.