Git: Изменения продолжают теряться из-за кажущихся случайными слияний

#git #version-control #tortoisegit

#git #контроль версий #tortoisegit

Вопрос:

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

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

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

Где-то в середине выполнения этого мои изменения теряются, поскольку их нажатие (326c8fd0 …) вызывает слияние с большим количеством строк удаления / добавления, сбрасывающих репозиторий обратно на гораздо более старую версию. Это происходило уже несколько раз даже со свежими копиями репозитория.

Выделенная строка ниже (8def6e9 ..) была моим коммитом, следующие коммиты должны были быть в этой же ветке, предполагая, что другой разработчик внес изменения. Слияние происходит в 326c8fd0, что приводит к неправильному сбросу репозитория, потере предыдущих изменений.

Журнал TortoiseGit

Я упускаю что-то очень очевидное относительно того, почему это происходит? Мы оба используем TortoiseGit.

Извините за, вероятно, расплывчатое объяснение.

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

1. Можете ли вы попытаться воспроизвести проблему с новым репозиторием и небольшим количеством коммитов? Было бы очень полезно иметь возможность просматривать полную историю, включая любое разрешение конфликта слияния. Если вы используете новый репозиторий, то вам не нужно скрывать авторов и фиксировать сообщения, и вы сможете дать более четкое описание проблемы.

Ответ №1:

В вашем примере кто-то объединяет f36908d (первый родительский элемент; их HEAD на момент слияния) и 8def6e9 (второй родительский элемент; вероятно, вершина исходной ветви на момент слияния) для получения 326c8fd0.

Если в фиксации слияния (326c8fd0) отсутствуют значительные фрагменты содержимого по отношению к любому из его родителей (f36908d и 8def6e9; вы говорите, что отсутствуют фрагменты последнего), то тот, кто создает фиксацию слияния, вероятно, выполняет слияние ненадлежащим образом.

Возможно, этот человек использует ours стратегию слияния (слияние или извлечение с помощью -s ours / --strategy=ours ), ours вариант стратегии рекурсивного слияния по умолчанию (слияние или извлечение с помощью -X ours / --strategy-option=ours ), или они могут просто принимать неправильные решения при ручном разрешении конфликтов слияния.

ours Стратегия полностью игнорирует любые изменения содержимого, внесенные в историю всеми родителями, кроме первого. Обычно вы можете идентифицировать этот тип слияния, потому что фиксация слияния и ее первый родительский элемент (т. Е. Их изменения) будут иметь идентичные деревья (т. Е. git diff f36908d 326c8fd0 не будут показывать различий).

ours Опция стратегии слияния также будет игнорировать изменения из истории второго родительского элемента (т. Е. ваши изменения), но только те, которые конфликтуют с изменениями, внесенными в историю первого родительского элемента (т. Е. их изменения). В этом случае некоторые изменения от второго родительского сервера могут попасть в результат, но другие могут быть полностью удалены.

Другой вероятной альтернативой является то, что они просто принимают неправильные решения при разрешении конфликтов, сгенерированных во время слияния по умолчанию.

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


Чтобы восстановить, вы можете повторить слияние самостоятельно, и они объединят результат в текущую подсказку истории:

 git checkout -b remerge f36908d
git merge 8def6e9
# resolve conflicts and commit
git checkout develop
git merge remerge
# maybe resolve more conflicts

# eventually: git branch -d remerge
  

Или, если вы согласны с переписыванием истории:

 git checkout -b remerge f36908d
git merge 8def6e9
# resolve conflicts and commit
git rebase --onto remerge 326c8fd0 develop
# maybe more conflicts to resolve at each rebased commit
  

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

1. Большое спасибо за ваш очень подробный ответ. Теперь это имеет гораздо больше смысла в отношении того, что могло произойти, а также побудило меня задать вопрос, который, я думаю, нашел источник проблемы. Что делал другой разработчик, так это то, что когда возник конфликт, вместо разрешения конфликтов с помощью TortoiseMerge он просто различал файлы и выполнял «ручное слияние». Предположительно, это привело к тому, что родительский файл конфликтующего файла указывал на исходный файл, а не обновлялся до последней копии ветви, и, таким образом, вызвало все эти нечетные слияния. Теперь пришло время отменить эти изменения :).

Ответ №2:

Если вы теряете коммиты, убедитесь, что ни один из вас не использует —force или флаг force в вашем графическом интерфейсе, чтобы избавиться от отклоненных. Взгляните на объяснение DAG.

http://progit.org/book

надеюсь, это поможет.