Перемещение зафиксированных (но не выдвинутых) изменений в новую ветвь после извлечения
Я выполнил справедливую работу ( "Ваша ветка впереди" происхождение/мастер "на 37 коммитов" ), которая действительно должна была входить в свою ветвь, а не в master
. Эти коммиты существуют только на моей локальной машине и не были нажаты на origin
, но ситуация несколько осложняется тем, что другие разработчики нажимают на origin/master
, и я потянул эти изменения.
Как мне ретроактивно переместить мои 37 локальных коммитов на новую ветку? Основываясь на документах, кажется, что git rebase --onto my-new-branch master
или ...origin/master
должны это сделать, но оба просто дают мне ошибку "фатальный: требуется одна ревизия". man git-rebase
ничего не говорит о предоставлении исправления для rebase
, и его примеры этого не делают, поэтому я понятия не имею, как разрешить эту ошибку.
(Обратите внимание, что это не дубликат Перемещение существующей, неработающей работы в новую ветвь в Git или Как объединить мои локальные незафиксированные изменения в другой ветвь Git?), поскольку эти вопросы касаются незафиксированных изменений в локальном рабочем дереве, а не изменений, которые были совершены локально.)
Ответы
Ответ 1
Это должно быть хорошо, поскольку вы еще не нажали свои коммиты в другом месте, и вы можете переписать историю своего ветки после origin/master
. Сначала я запустил git fetch origin
, чтобы убедиться, что origin/master
обновлен. Предполагая, что вы в данный момент находитесь в master
, вы должны иметь возможность:
git rebase origin/master
..., который будет воспроизводить все ваши коммиты, которые не находятся в origin/master
на origin/master
. По умолчанию действие rebase состоит в том, чтобы игнорировать комманды слияния (например, те, которые были добавлены вашим git pull
), и он просто попытается применить патч, введенный каждым вашим коммитом, на origin/master
. (Возможно, вам придется разрешить некоторые конфликты на этом пути.) Затем вы можете создать свою новую ветку на основе результата:
git branch new-work
... и затем reset ваш master
вернуться к origin/master
:
# Use with care - make sure "git status" is clean and you're still on master:
git reset --hard origin/master
При выполнении такого рода манипулирования ветвями с помощью git branch
, git reset
и т.д. Мне полезно часто просматривать граф фиксации с помощью gitk --all
или аналогичного инструмента, просто чтобы убедиться, что я понимаю, где все различные ссылки указывают.
В качестве альтернативы вы могли бы просто создать ветвь темы, основанную на том, где находится ваш мастер (git branch new-work-including-merges
), а затем reset master
, как указано выше. Однако, поскольку ваша ветка темы будет включать в себя слияния из origin/master
, и вы еще не изменили свои изменения, я бы предложил сделать перестановку, чтобы история была более аккуратной. (Кроме того, когда вы, в конце концов, соедините свою ветку темы с мастером, изменения будут более очевидными.)
Ответ 2
Если у вас низкое количество коммитов и вам все равно, если они объединены в один мегакмит, это работает хорошо и не так страшно, как при выполнении git rebase
:
разархивируйте файлы (замените 1 на число коммитов)
git reset --soft HEAD~1
создать новую ветку
git checkout -b NewBranchName
добавить изменения
git add -A
сделать коммит
git commit -m "Whatever"
Ответ 3
Я придерживался той же проблемы. Я нашел самое простое решение, которое мне нравится делиться.
1) Создайте новую ветку с изменениями.
git checkout -b mybranch
2) Нажмите новый код ветвления на удаленном сервере.
git push origin mybranch
3) Возврат к главной ветке.
git checkout master
4) Reset код главной ветки с удаленным сервером и удалить локальную фиксацию.
git reset --hard origin/master
Ответ 4
Еще один способ
предполагать
branch1 - это ветка с фиксированными изменениями
branch2 - желательная ветвь
git fetch && git checkout branch1
git log
выберите идентификаторы фиксации, которые необходимо переместить
git fetch && git checkout branch2
git cherry-pick commit_id_first..commit_id_last
git push
Теперь отмените разблокированные коммиты из начальной ветки
git fetch && git checkout branch1
git reset --soft HEAD~1
Ответ 5
Как насчет:
- От ветвления от текущего HEAD.
- Убедитесь, что вы находитесь на хозяине, а не на своей новой ветке.
-
git reset
вернитесь к последнему фиксации, прежде чем приступать к изменениям.
-
git pull
, чтобы повторно удалить удаленные изменения, которые вы выбрали с помощью reset.
Или это произойдет, когда вы попытаетесь повторно объединить ветку?
Ответ 6
В качестве альтернативы, сразу после фиксации в неправильной ветки выполните следующие действия:
git log
git diff {previous to last commit} {latest commit} > your_changes.patch
git reset --hard origin/{your current branch}
git checkout -b {new branch}
git apply your_changes.patch
Я могу себе представить, что есть более простой подход к первым и вторым шагам.
Ответ 7
-
Оформить заказ свежих копий источников
git clone ........
-
Сделать ветку из желаемой позиции
git checkout {position}
git checkout -b {branch-name}
-
Добавить удаленный репозиторий
git remote add shared ../{original sources location}.git
-
Получить удаленные источники
git fetch shared
-
Оформить требуемую ветку
git checkout {branch-name}
-
Объединить источники
git merge shared/{original branch from shared repository}
Ответ 8
Для меня это был лучший способ:
- Проверить изменения и слить конфликты
git fetch
- Создайте новую ветку
git branch my-changes
и нажмите на удаленный
- Изменить восходящий поток на новую созданную ветку
git master -u upstream-branch remotes/origin/my-changes
- Нажмите свои коммиты на новую ветку вверх.
- Вернитесь к предыдущему восходящему потоку
git branch master --set-upstream-to remotes/origin/master
Ответ 9
Более простой подход, который я использовал (предполагая, что вы хотите переместить 4 коммита):
git format-patch HEAD~4
(посмотрите каталог, из которого вы выполнили последнюю команду для 4 файлов .patch
)
git reset HEAD~4 --hard
git checkout -b tmp/my-new-branch
Тогда:
git apply /path/to/patch.patch
В любом порядке, который вы хотели.
Ответ 10
Вот гораздо более простой способ:
Создать новую ветку
В новой ветке сделайте git merge master
- это объединит ваши зафиксированные (не отправленные) изменения с вашей новой веткой
Удалите свою локальную главную ветвь git branch -D master
. Используйте -D
вместо -d
, потому что вы хотите принудительно удалить ветку.
Просто сделайте git fetch
в своей мастер-ветке и git pull
в своей мастер-ветке, чтобы убедиться, что у вас есть последний код вашей команды.