Перебазируйте один коммит Git


117

Есть ли способ перенести одну фиксацию из ветки в другую?

У меня такая структура веток:

-- -- -- -- -- (Master)
            \
              -- -- -- -- -- XX (Feature-branch)

Все, что я хочу сделать, это переустановить последний коммит Feature-branchна master и откатить Feature-branchодин коммит.

-- -- -- -- -- XX (Master)
            \
              -- -- -- -- -- (Feature-branch)

Как я могу это сделать?


3
Если вы можете перебазировать любое количество коммитов, то почему вы спрашиваете о перебазировании одного? Если бы я мог задавать вопросы в SO, я бы спросил, в чем разница между перебазированием (одной фиксацией) и выбором вишни.
Val

9
Потому что я не знал, что существует выбор вишни, и я делаю «Фафф о ветке», «Получить запрос на исправление в другой ветке», «исправить», «Зафиксировать в неправильной ветке», «Ничего подобного!» достаточно, чтобы задать вопрос было полезно.
Кевин Мейер

Ответы:


116

Вы можете выбрать XX, чтобы освоить.

git checkout master
git cherry-pick <commit ID of XX>

И удалите последний коммит из ветки функций с помощью git reset.

git checkout Feature-branch
git reset --hard HEAD^

64
как может вопрос, конкретно называемый "git rebase ...", иметь принятый ответ, чем содержит вишневый выбор, который является совершенно другой концепцией и иногда сам по себе считается нечистым?
Bondax

1
Не уверен, что это актуально, но в коммите, который я хотел перебазировать, были некоторые файлы, которые были перемещены, и cherry-pickони выглядели так, как будто они были удалены из старого местоположения и созданы в новом месте. Я полагаю, что rebase позаботится об этом, но к настоящему времени я продвинулся вверх по течению, поэтому я не могу это проверить. В любом случае будьте осторожны, если у вас возникнет подобная ситуация.
waldyrious

Примечание: чтобы подтолкнуть вас к изменениям в Feature-branchorigin, вам нужно это сделать, так git push -f origin Feature-branchкак Feature-branchтеперь считается, что за вами стоит 1 фиксация origin/Feature-branch.
jojo

1
В чем практическая разница между этим решением и решением CharlesB ?
Lii

98
git rebase --onto master branch~1 branch 

Это говорит: «переустановить диапазон коммитов между последней перед веткой и веткой (то есть XX фиксацией) на кончике основной ветки»

После этой операции branchподсказка перемещается в фиксацию XX, поэтому вы хотите вернуть ее с помощью

git checkout branch
git reset --hard branch@{1}^

В котором говорится: «сбросить кончик ветки до фиксации до его предыдущего состояния»

Так что вишня - более простое решение ...


5
Похоже, у меня это не работает, я теряю коммиты до XX, и ветка перебазируется на master с одной фиксацией, но я никогда раньше не использовал, --ontoпоэтому я могу делать что-то не так. Кстати, ОП сказал перебазирование, но похоже, что он хочет сделать вишневый выбор.
tewe

1
моя ошибка, rebase действительно перемещает ветку на master, она должна быть сброшена
CharlesB

1
В чем практическая разница между этим решением и решением от tewe ?
Lii

1
@Lii только я вижу, что он использует 3 шага вместо 4
CharlesB

52

На самом деле это довольно просто сделать. Решение состоит в том, чтобы выполнить интерактивную перебазировку и «отбросить» все коммиты, которые вы не хотите включать в перебазирование.

git rebase -i <target_branch>где target_branchнаходится ветка, на которую вы хотите переустановить

Затем вы отредактируете открытый файл и pickкоммиты, которые вам нужны, и drop(или dдля краткости) все коммиты, которые вы не хотите брать с собой.


6
IMO - гораздо лучшее решение, и оно действительно решает вопрос.
GabrielOshiro

Это должно быть приемлемым решением, учитывая, насколько оно общее, интуитивно понятное и краткое.
Пабло Ариас,

1

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

  * a8f9182 (HEAD -> production) производственная конфигурация
  | * daa18b7 (предварительная) подготовительная конфигурация
  | /  
  | * d365f5f (локальная) локальная конфигурация
  | /  
  * 27d2835 (dev) потрясающая новая функция, которая спасет мир
* | 56d2467 (мастер) скучный по последнему слову техники для проекта
| /

что я создаю для него новую команду:

$ cat ~ / bin / git-rebaseshot 
COMMIT = 1 доллар США
DEST = $ {2: -HEAD}
git rebase $ {COMMIT} ^ $ {COMMIT} --onto $ DEST

обычно вы хотите автоматически заполнять имена веток для этой команды, поэтому добавьте ее в источник этой функции (добавив в .bashrc или .profile):

_git_rebaseshot () 
{ 
    __gitcomp_nl "$ (__ git_refs)"
}

git autocomplete будет искать его

вы можете использовать эту команду так:

# rebase config on prepro on actual HEAD
$ git rebaseshot prepro 
# rebase config on local onto dev
$ git rebaseshot local dev
# rebase production config on master
$ git rebaseshot pro master

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

* a8f9182 (HEAD -> postgres) Конфигурация BBDD
* a8f9182 (локальный) локальный конфиг
* a8f9182 (отладка) конфигурация уровня журнала
* a8f9182 (dev) новая функция
|

Думаю, это то, что любят делать люди, занимающиеся лоскутным одеялом .

эта команда будет работать в любом случае с любым предоставленным вами sha / ref:

$ git rebaseshot <Feature branch> master
$ git rebaseshot <commit of XX> master

//, можете ли вы ссылаться на какой-либо проект, где мы можем увидеть это в действии?
Натан Басанезе,

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

//, я столкнулся с некоторыми проблемами. Я попробую еще раз.
Натан Басанезе,

0

Вот еще вариант:

  1. Убедитесь, что у вас есть пульт с копией функциональной ветки
  2. Удалить ветку локальной функции
  3. Создайте и извлеките новую ветку с тем же именем, что и старая ветка функции, которую вы только что удалили из мастера.
  4. выберите один коммит из удаленной копии нужной функциональной ветки.

Команды выглядят так:

git checkout Feature-branch
git push -u origin HEAD
git checkout master
git branch -D Feature-branch
git checkout -b Feature-branch
git cherry-pick HASH-OF-XX

Это не команда rebase, нет, но это по духу rebase.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.