Почему бы не зафиксировать нерешенные изменения?


15

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

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

Возможность фиксации в процессе слияния имеет несколько преимуществ (на мой взгляд):

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

Вы также можете иметь набор изменений, которые будут действовать как слияние, а не как один. Это позволит вам по-прежнему использовать такие инструменты, как git rerere.

Итак, почему фиксация с неразрешенными файлами не одобряется? Есть ли какая-либо причина, кроме традиции?


1
Кем это осуждается или предотвращается?
фунтовые

@pdr Некоторые разработчики, с которыми я работал, нахмурились. По крайней мере, hg 1.6после слияния файлы помечаются как неразрешенные. hgбудет не позволит вам совершить , пока вы не пометив их как разрешенные (не обязательно означает , что вы на самом деле должны решать их, но я предположил бы , что это идея).
Взрыв таблетки

1
Итак, под «неразрешенными файлами» вы на самом деле подразумеваете «неразрешенные слияния»?
фунтовые

@pdr no, hgфактически поддерживает список файлов, которые были или не были помечены как «разрешенные» (использующие hg resolve). Если Uв этом списке есть какие-либо файлы, он не позволит вам зафиксировать.
Взрыв таблетки

1
hg resolveиспользуется специально для слияния с конфликтами; см. selenic.com/mercurial/hg.1.html#resolve . Note that Mercurial will not let you commit files with unresolved merge conflicts. You must use hg resolve -m ... before you can commit after a conflicting merge.
Майк Партридж

Ответы:


6

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

Одна вещь, которую вы могли бы сделать, это сделать локальные коммиты для вашего слияния, а затем объединить их в один большой коммит, когда вы нажимаете (хотя я не уверен, как (если?) Какой-либо vcs поддерживает это). Хотя это может дать некоторые из упомянутых вами преимуществ, я не уверен, что это стоит дополнительной сложности (мы уже имеем дело с довольно запутанной и сложной областью).


5
Я не знаю, согласен ли я с возможностью извлекать любой коммит и заставить его работать. Большая часть коммитов в DVCS - это фиксация вашего прогресса , так что большая часть времени неизбежно будет нарушена или неполна ,
Взрыв таблетки

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

1
Git поддерживает связанные коммиты.
Deltree

3

Я больше всего знаком с Git, поэтому буду отвечать за эту перспективу.

Я не вижу причины, по которой вы или какая-либо хорошая VCS захотите разрешить фиксацию незагруженного файла, особенно если это был код. Вы должны поддерживать репозиторий в согласованном состоянии, и то, что вы предлагаете, нарушит атомарность коммитов. Многие VCS физически изменяют файл, чтобы показать, где находятся конфликты - Git, SVN и CVS используют >>>> <<<< маркеры типов. В VCS с атомарными фиксациями и слияниями уровня хранилища вы просто создали бы узел, который не имеет смысла ни для кого, кроме вас. В разработке программного обеспечения ваш проект не может быть построен. В документе группы никто не знает, какие изменения являются правильными.

Теперь Git предоставляет некоторые инструменты, которые могли бы облегчить это, если бы тип коммитов, которые вы предлагаете, был разрешен. Например, вы можете раздавить все коммиты, которые вы объединяете, прежде чем вы нажмете. В итоге получается то же самое, что и типичный коммит слияния.

Особые опасения по поводу вашего списка преимуществ:

  1. Фактические изменения слияния находятся в истории. Зачем вам нужна дополнительная информация? DVCS очень хорошо умеют ограничивать конфликты в ограниченном пространстве. Как только вы выберете, какой набор изменений сохранить, сравнение копии узла фиксации слияния с предыдущей копией даст вам именно это.
  2. Если слияние было очень большим, вы можете делать периодические коммиты. Это серьезная проблема, но вы никогда не должны сюда попасть. Ветви должны постоянно вносить изменения в восходящий поток, чтобы этого никогда не происходило. Такие инструменты, как rebaseили выбор вишни по одному коммиту за раз, также могут помочь вам в некоторых ситуациях.
  3. Если вы допустили ошибку, было бы намного проще откатиться назад (без необходимости повторного слияния). Смотрите выше - ваши конфликты не должны стать такими неуправляемыми.

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


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

«Вам необходимо поддерживать репозиторий в согласованном состоянии». Я не думаю, что это правда. Локальное хранилище - это рабочее пространство, а не храм. Если это помогает зафиксировать в середине слияния, сделайте это ИМХО. Если вы делаете это, потому что вы не знаете ничего лучше, я бы предложил не делать этого. Однако, если вы опытный программист, вы должны делать все, что лучше для вас. Не впадайте в догматичность сохранения вашего локального хранилища.
Брайан Оукли

1

Мой основной опыт связан с Mercurial, хотя я также время от времени использую git.

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

Все, что вам нужно сделать в Mercurial - это получить файлы так, как вы хотите их зафиксировать:

hg resolve --mark --all
hg commit -m "I'm such a rebel"

--mark ... пометит файлы как разрешенные без запроса инструмента слияния. --all позаботится о выборе всех файлов, отмеченных конфликтами.

Если вы хотите толкать без натяжения (и, следовательно, должны объединить изменения других), сделайте как джедай :

hg push --force

Следующий парень, который тянет, получит +1 голову (каламбур не предназначен)

Я уверен, что есть способ сделать то же самое с Git (хотя он, вероятно, более запутанный).


1

Когда я сливаюсь в git, я немедленно фиксирую все изменения (включая конфликты слияния). Затем в моем следующем коммите (ях) я разрешаю конфликты слияния с помощью текстового редактора. После того, как конфликты разрешены, я при желании нажимаю.

Честно говоря, я не понимаю, почему другие так не делают, или git не применяет это.

  • «Коммит слияния» теперь представляет собой чистую историю того, что именно нужно слить.
  • Следующие коммиты показывают, что именно вы сделали для разрешения конфликтов слияния.
  • Когда вы нажимаете, конфликты к тому времени разрешаются, и сборка не прерывается на кончике ветки.
  • В любой момент, если вы испортите разрешение конфликта, вы можете просто вернуться к одному из коммитов "post merge" и повторить попытку.

Огромный недостаток стандартного рабочего процесса разрешения конфликтов перед фиксацией заключается в том, что могут проникнуть изменения из вашей локальной копии. Дополнения скрыты от проверки кода из-за большого слияния, поэтому вы не замечаете, что вы случайно зафиксировали API ключ или т. д.

Мой рабочий процесс, описанный выше, позволяет избежать этой проблемы с локальным копированием, а также позволяет рецензентам кода (только) проверять детали вашего разрешения слияния в diff-коммите, который выглядит точно так же, как стандартный diff-коммит.


0

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

Создание большого количества открытого кода с использованием git было для меня самым большим разочарованием, когда наполовину готовый код попал в репозиторий и пытался сделать сборку, но не смог, потому что парень выполнил половину работы и сказал: «Я сейчас занят» Я закончу через неделю ". Так что в итоге мне пришлось бы отказаться от этого (что раздражало бы парня) или занять время, чтобы закончить и полностью интегрировать его.

Я полагаю, с моей точки зрения, держите половину задницы на месте, отправляйте хорошие вещи по проводам.


0

Не будь рабом своих инструментов.

Цель VCS - дать вам возможность выполнять свою работу. Ваша задача - не хранить нетронутый локальный репозиторий, ваша задача - писать код. Если вы делаете ранние и часто локальные действия, вы можете работать лучше.

Вы не должны, однако, выдвигать сломанный код вверх по течению.


0

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

Я вижу, что в случае большого / сложного слияния вы можете сохранить текущую работу и установить контрольную точку, но вы все равно оставите систему в неработоспособном состоянии, которое необходимо решить.

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.