2016-12-02 3 views
1

В настоящее время у меня есть две ветви, называем его А и В:Как сказать git, что два коммита одинаковы?

B1-...many dirty checkouts...-B2 
/
--O-A1-A2-......................-A3 

В настоящее время, В2 и А3 одинаковы (git diff A B дает пустой выход).

Теперь проблема заключается в том, что это состояние было достигнуто путем частичной проверки от A. I.e. много раз git checkout -- dir1 dir2 ... произошло, а не git merge.

Простое слияние B с A полностью craps A, что невозможно.

Я не хочу потерять историю Б.

Как-то я должен сказать git, что git merge A на ветке B ничего не должен делать.

Конечно, я мог бы просто заменить B2 на A3, но в этом случае я потерял бы историю B.

Как это возможно?

+1

Я не понимаю, что вы пытаетесь сделать. Если нет различий, почему слияние проблемы? –

+0

Вы пытаетесь сохранить историю B и заменить историю A = B? –

+0

@MadPhysicist «грязная проверка» означает, что некоторые «git checkout - dir1», «git checkout - dir2» и т. Д. Произошли (и некоторые другие слияния между ними тоже). Теперь A3 и B2 точно совпадают, поэтому diff пуст, но git его не знает. – peterh

ответ

2

Что может помочь здесь другая стратегия в git merge с помощью опции -s, как ours:

ours 
     This resolves any number of heads, but the resulting tree of the 
     merge is always that of the current branch head, effectively 
     ignoring all changes from all other branches. It is meant to be 
     used to supersede old development history of side branches. Note 
     that this is different from the -Xours option to the recursive 
     merge strategy. 

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

+0

Как я вижу, он, вероятно, не перезаписывает историю Б, правильно? – peterh

+1

Ничто не перезаписывает историю в git, кроме ... изменений без перемотки вперед. – Kaz

+1

Это был бы путь, но здесь есть какая-то загадка, если график в исходном вопросе правильный, потому что 'git merge' работает, отличая базу слияния с двумя концами. Если оба кончика совершают «B2» и «A3», идентичны, и существует только одна база слияния «O», тогда два различия будут идентичны, и результат слияния будет тем же самым деревом, что и в «B2», 'A3'. – torek

-1

Я нашел решение:

  1. I проверка B с git checkout B.

  2. Я сливаю A в B с git merge A. Теперь B локально находится в состоянии дерьма.

  3. Но теперь я делаю справочную проверку с git checkout remotes/origin/B -- .. Это восстанавливает B в желаемое состояние.

  4. Теперь, подталкивая B (git push --all), при необходимости обновляйте стрелки слияния.

+0

Если у кого-то есть лучшее решение, я готов принять это. – peterh

+0

* «Теперь B локально в состоянии дерьма». * - почему? Если 'diff A3 B2' не показывает никакой разницы, то' B' указывает на фиксацию слияния, которая идентична (как содержимое) на 'A3' и' B2'. Возможно, ваше рабочее дерево не было в чистом состоянии, прежде чем начать? – axiac

+0

@axiac Это было в чистом состоянии, но многие изменения между B1 и B2 произошли с 'git merge', в то время как другие изменения произошли с' git checkout A - dir1' и тому подобное. В результате многие коммиты воспринимаются git как несвязанные, поэтому «git merge B» на A заставляет git объединить их снова. Это приводит к полному состоянию A (вероятно, только удача в том, что у меня нет слияния конфликтов). – peterh