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

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

Что-то происходит, так это то, что я совершаю/нажимаю некоторые изменения на сервере, и на моей копии все замечательно.

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

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

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

TortoiseGit log

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

Извините за возможное неопределенное объяснение.

Ответ 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

Ответ 2

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

http://progit.org/book

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