Git: Изменения теряются из-за случайных слияний - PullRequest
11 голосов
/ 26 мая 2011

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

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

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

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

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

TortoiseGit log

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

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

Ответы [ 2 ]

11 голосов
/ 26 мая 2011

В вашем примере кто-то объединяет 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
0 голосов
/ 26 мая 2011

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

http://progit.org/book

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

...