2009-07-03 3 views
134

У меня возникла проблема: у меня была проблема-специфическая ветка 28s в Git, которую я объединил в общей ветке develop. Оказывается, я сделал это слишком быстро, поэтому я использовал git-revert, чтобы отменить слияние. Теперь, однако, настало время объединить 28s в develop, но команда git-merge видит исходное слияние и счастливо объявляет, что все хорошо, а ветви уже объединены. Что мне теперь делать? Создайте «Revert» Revert «28s -> develop» «commit»? Кажется, это не лучший способ сделать это, но я не могу представить ни одного другого на данный момент.Повторное выполнение слияния в Git

Что древовидная структура выглядит следующим образом:

Git log output

+0

Какой графический интерфейс? –

+3

Это GitX (http://gitx.frim.nl). –

ответ

110

Вы должны "вернуться к Revert". В зависимости от того, как вы это сделали, это может быть не так просто, как кажется. Посмотрите на official document on this topic.

---o---o---o---M---x---x---W---x---Y 
      /
     ---A---B-------------------C---D 

чтобы:

---o---o---o---M---x---x-------x-------* 
      /     /
     ---A---B-------------------C---D 

Но это делает всю работу? Конечно. Вы можете вернуть слияние, и с чисто технического угла , git сделал это очень естественно и не имел реальных проблем .
Он просто считал это изменением от «state before merge» до «state after merge», и все.
Ничего сложного, ничего странного, ничего действительно опасного. Гит сделает это, даже не подумав об этом.

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

Если это вообще возможно, например, если вы столкнулись с проблемой, что получил слиты в основное дерево, , а не вернуть слияния, попробуйте действительно трудно:

  • разрез`ать проблему вниз в ветку, которую вы объединили, и просто исправить ее,
  • или попытаться вернуть индивидуальное совершение, вызвавшее его.

Да, это сложнее, и нет, это не всегда будет работать (иногда ответ: «Ой, я действительно не должен объединить его, потому что он был не готов, и Мне действительно нужно отменить все of merge "). Итак, вы должны действительно возвратить слияние, но если вы хотите повторно выполнить слияние, вам нужно сделать , обратившись обратно.

+5

Хорошая ссылка (+1). Я взял на себя смелость скопировать часть документа в свой ответ, чтобы позволить читателям сразу увидеть соответствующие варианты в этом случае. Если вы не согласны, не стесняйтесь возвращаться. – VonC

+3

Мы просто столкнулись с тем случаем, когда нам нужно было это сделать, и обнаружили, что здесь не совсем весело. Это была длинная ветка, которая была объединена, поэтому нам нужно было продолжать ее обновлять. Мой подход здесь: http://tech.patientslikeme.com/2010/09/29/dealing-with-git-merge-revisions/ – jdwyah

+0

Я следил за сообщением в блоге @ jdwyah, и это было великолепно (серьезно, было здорово, что это просто работал). – hellatan

2

Вместо использования git-revert вы могли бы использовать эту команду в devel филиал в забросить подальше (отменить) неправильное слияние фиксации (вместо того, чтобы просто возвращаясь его).

git checkout devel 
git reset --hard COMMIT_BEFORE_WRONG_MERGE 

Это также отрегулирует содержимое рабочего каталога соответствующим образом. Будьте осторожны:

  • Сохраните изменения в разработке отрасли (с неправильным слиянием), потому что они тоже будут удалены с помощью git-reset. Все коммиты после того, как вы указали как , аргумент git reset исчезнет!
  • Кроме того, не делайте этого, если ваши изменения уже были вытащены из других репозиториев , потому что сброс перепишет историю.

Я рекомендую внимательно изучить man-страницу git-reset, прежде чем пытаться это сделать.

Теперь, после перезагрузки вы можете повторно применить изменения в devel, а затем сделать

git checkout devel 
git merge 28s 

Это будет реальным слияние с 28s в devel как исходной (который теперь стирается из Git и история).

+5

Для тех, кто не очень хорошо знаком с git и может захотеть следовать этим инструкциям: аккуратно сочетая «reset -hard» и «push origin». Также имейте в виду, что силовой толчок к происхождению может действительно замалчивать открытые PR на GitHub. – funroll

+0

Очень полезно для исправления некоторых проблем с объединением на частном git-сервере. Благодаря! – mix3d

+2

изменение истории. – njzk2

29

Давайте предположим, что у вас есть такая история

---o---o---o---M---W---x-------x-------* 
      /      
     ---A---B 

Где A, B не удался фиксации и W - это вновь обратиться М

Итак, прежде чем я Начало фиксируя нашла проблемы, я вишневый выбрать из W обязующихся мой филиал

git cherry-pick -x W 

Затем я возвращаюсь W совершить на моей ветке

git revert W 

После этого я могу продолжить исправление.

Заключительная история могла бы выглядеть следующим образом:

---o---o---o---M---W---x-------x-------* 
      /     / 
     ---A---B---W---W`----------C---D 

Когда я посылаю PR это ясно показывает, что PR является отменить Revert и добавляет некоторые новые коммиты.

+1

Это похоже на то, что это может быть полезно, но настолько скудны по деталям (что такое C, D на последней диаграмме), что это более неприятно, чем полезно – Isochronous

+0

@ Изохронные C и D, похоже, являются фиксациями, которые устраняют проблемы, и B. – Thomas

+0

@Thomas точно –

2

Для возврата к Revert без завинчивания рабочего процесса слишком много:

  • Создать локальную копию хлама разработки
  • Возвратить Revert фиксации на локальной копии разработка
  • Merge, что скопировать в ваш и переместите ветвь вашей функции на ваш сервер git.

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

1

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

Вместо этого я проверил фиксацию, я хотел, чтобы ветка вернулась к, например. git checkout 123466t7632723. Затем преобразуется в ветвь git checkout my-new-branch. Затем я удалил ветку, в которой я больше не хотел. Конечно, это будет работать, только если вы сможете выбросить ветку, которую вы испортили.

+0

'git reflog' защитит вас от жесткого сброса в течение нескольких месяцев, если вы позже обнаружите, что вам нужны потерянные коммиты. Reflog ограничен вашим местным репо. – Todd

Смежные вопросы