Почему git скрытно объединяет и дублирует код?

#git #merge

Вопрос:

Вчера я объединил локальную ветвь разработки с моей локальной главной ветвью, после чего планировал перейти к удаленному мастеру. Я запускаю команды git из git bash, затем переключаюсь на Visual Studio для обработки конфликтов слияния.

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

Затем я заметил случай, когда строка была abcd в главной и abcd - efg во входящей ветке, и она просто… незаметно слилась. Он не отмечал конфликт и не спрашивал, чего я хочу; он просто молча выбирал, что оставить (и выбрал не тот, в придачу).

Затем я заметил if , что в слиянии был продублирован блок кода. В ходе устранения всех этих неполадок (и до того, как я заметил дублирование) я объединил ветвь с другой локальной ветвью, чтобы проверить, сохраняются ли те же проблемы, и этот if блок появлялся там 3 раза, поэтому он дублировался один раз при каждом слиянии. На случай, если вам не ясно, что я имею в виду:

Предварительное слияние:

 // code
if (condition)
{
  // do things
}
// code
 

После слияния:

 // code
if (condition)
{
  // do things
}
if (condition)
{
  // do things
}
// code
 

Затем я заметил еще один случай скрытого слияния: изменение имени переменной. В одной ветви все это было в нижнем регистре, в другой ветви это был camelCase, и он просто молча выбирал строчную версию в объявлении переменной и camelCase, где бы он ни использовался.

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

Как вы можете себе представить, я совершенно сбит с толку этим моментом. Это ненормальное поведение мерзавца. Я не так уж плох с git, а мой коллега еще лучше, и мы оба находимся на стадии «что на самом деле * * * *» с этим. Затем сегодня утром я прихожу на работу, надеясь, что это волшебным образом разрешится за ночь (предупреждение о спойлере: этого не произошло), и замечаю еще одну дублирующуюся функцию, но эта отделена от оригинала большим количеством кода, а не сразу после нее. Странный. Поэтому я начал сравнивать их и понял, что дубликат на самом деле является старой версией функции. Несколько недель назад. С несколькими фиксациями между ними.

Устранение неполадок: перезагрузил компьютер, перезагрузил VS, попытался перейти в другую ветвь, попытался переустановить git, попытался повторно клонировать репозиторий и объединить ветви с переустановленным git. Странное поведение сохранялось. Я попытался погуглить о скрытом слиянии, с ограниченным успехом, и о дублировании, но ни один из ответов не соответствовал моей проблеме.

Что происходит?! Почему это происходит?! Что мне с этим делать? Пожалуйста, помогите!

Комментарии:

1. Есть ли у вас что-нибудь в вашем .gitattributes файле, например, merge=union запись где-нибудь?

2. Если строка изменилась только в ветке, но осталась неизменной в master (но все еще отличается ), то Git выполняет свою работу и применяет изменения из ветки к вашей цели слияния. Это конфликт только в том случае, если одна и та же строка была изменена в обеих ветвях. Здесь не происходит скрытого слияния (но трудно сказать, не видя реальных команд и коммитов).

3. Что касается дублированного кода: может быть, вы разрешили конфликт с Visual Studio и выбрали обе стороны конфликта?

4. @bk2204 Нет, merge=union нигде нет, только merge = refs/heads/[branchname] . @knittl Я не уверен, что понимаю. Я изменил строку в ветке, я объединяю эту ветку в master, она сохранила версию в master, поэтому проигнорировала изменение и не спросила, какую версию я хочу. Ты хочешь сказать, что это правильное поведение? Повторный дублированный код, если это произошло, я не делал выбора, т. Е., Может быть, ПРОТИВ авто-сделал это?

5. Не существует такого понятия, как «скрытое слияние». Это просто вопрос понимания того, что такое слияние. Если вы посмотрите на различия между базой слияния и двумя объединяемыми ветвями, вы увидите вклад, который каждая ветвь вносит в ваш код, и все будет ясно. Как бы то ни было, вы говорите нам недостаточно для того, чтобы можно было дать подробное объяснение.

Ответ №1:

Вы пробовали использовать git rebase вместо git merge? Это покажет вам конфликты, и это может быть то, что происходит. Я мог бы сохранить обе копии и дублировать их.

Комментарии:

1. Я также вижу конфликты с git merge, поэтому я использую VS для обработки слияния. Я попробовал перебазировать git, согласно вашему предложению, и он сделал то же самое :/

2. Дублируются ли также коммиты? или это просто код?