мерзавцы не-перемотки вперед. Как побороть? - PullRequest
2 голосов
/ 09 декабря 2010

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

Я настроил свою рабочую структуру git следующим образом (благодаря рекомендации в другом вопросе git: Небольшая работа над проектом )

 /live/website
       |
       |
/path/to/staging (bare)
  |          |
  |          |
dev1        dev2

В настоящее время и dev1, и dev2 выдвигают проекты в /path/to/staging repo. У меня есть хук в / path / to / staging, который автоматически вызывает cd /live/website && git pull из моего / path / to / staging. Таким образом, у меня есть рабочая копия всех файлов. Таким образом, dev1, dev2 и / live / website являются git-клонами /path/to/staging.

Руди, рекомендовал выяснить, было ли установлено значение receive.denyNonFastforwards на path/to/staging, выполнив:

cd path/to/staging/ && git config --get-all receive.denyNonFastforwards

И, к сожалению, оно установлено на true. Так, например, если я выполнил git reset --hard <SHA-1> на сервере / live / website, он будет выполнен успешно. Однако, когда я пытаюсь перенести мои изменения с / live / website на / path / to / staging:

error: failed to push some refs to '/path/to/staging/' To prevent you from losing history, non-fast-forward updates were rejected. Merge the remote changes before pushing again. See the 'non-fast-forward'

Вероятно, я сталкиваюсь с той же проблемой, когда делаю изменения в dev1 или dev2 и пытаюсь отправить изменения в /path/to/staging.

Я хочу сделать своего рода общий сброс, где я мог бы просто войти в систему /path/to/staging или /live/website и перейти к стабильной версии, вместо того, чтобы выяснить, какой разработчик внес изменение, а затем выполнить сброс git. Можно ли это сделать? По сути, я хочу иметь возможность перейти на другую версию файла, если я решу это сделать ...

1 Ответ

1 голос
/ 10 декабря 2010

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

    current workflow:
                     /live/website    /path/to/staging     dev
1   now              1-2-3-F          1-2-3-F              1-2-3-F
2   reko             1-2-3(-F rm) ->  1-2-3                1-2-3-F
3   hack hack hack   1-2-3            1-2-3                1-2-3-F-5-6-7
4   dev push         1-2-3            1-2-3-F-5-6-7 <-     1-2-3-F-5-6-7
5   auto update      1-2-3-F-5-6-7 <- 1-2-3-F-5-6-7        1-2-3-F-5-6-7

6   revert workflow:
7   now              1-2-3-F          1-2-3-F              1-2-3-F
8   backout          1-2-3-F-~F   ->  1-2-3-F-~F           1-2-3-F
9   hack hack hack   1-2-3-F-~F       1-2-3-F-~F           1-2-3-F-5-6-7
10  dev try push     1-2-3-F-~F       1-2-3-F-~F           1-2-3-F-5-6-7
11  dev pull         1-2-3-F-~F       1-2-3-F-~F       ->  1-2-3-F-5-6-7-8
                                                                \-~F--/

12  dev push         1-2-3-F-~F       1-2-3-F-5-6-7-8  <-  1-2-3-F-5-6-7-8
                                             \-~F--/              \-~F--/

13  auto update      1-2-3-F-5-6-7-8  1-2-3-F-5-6-7-8  <-  1-2-3-F-5-6-7-8
                            \-~F--/          \-~F--/              \-~F--/

В вашем текущем рабочем процессе у вас есть один фиксированный верхний коммит (F), который вы удаляете (2) с помощью rebase или reset, а затем помещаете этот удаленный коммит в центральное хранилище. Проблемы этого рабочего процесса возникают, когда разработчик, который представил F, выполнил другие коммиты (4) поверх F (что является поведением по умолчанию в git), а затем снова запускает эту работу. Поскольку фиксация F была удалена только из центрального репо, разработчик не знает, что F там не должно быть, и поэтому F появляется снова (4). Так как вы устанавливаете хук на центральном репо, который автоматически обновляет /live/website, это означает, что после этого толчка неисправность также вновь появляется на веб-сайте. Теперь это еще хуже, потому что теперь F больше не является HEAD, поэтому вы не можете легко удалить F (вы можете сделать это сейчас, но проблема в том, что F живет в репозитории разработчиков, все еще существует).

В обратном рабочем процессе вы говорите git revert F (8), что заставляет git создать коммит, который отменяет коммит F, здесь называемый ~ F. Ваша рабочая копия теперь находится в состоянии, которое выглядит так, как будто F никогда не было, и вы можете спокойно нажать ~ F в центральном хранилище. Теперь, когда другой разработчик выполнил новую работу и хочет нажать push (10), git откажется от этого push, поскольку коммит ~ F в центральном репозитории не является предком каких-либо коммитов в репозитории разработчиков, и git теперь заставляет разработчика вытащить ~ F из центрального хранилища (11). Затем разработчик должен слить (или перебазировать) ~ F в свою ветку (12), прежде чем новые изменения можно будет снова отправить в центральное хранилище (13).

Одно слово о репо /live/website: поскольку у вас есть хук в /path/to/staging, который автоматически обновляет это репо на пуше, внесение изменений в /live/website не очень хорошая идея. Основная проблема заключается в том, что если у вас есть локальные измененные файлы или коммиты, которые вызывают конфликты слияния, push-hook в /path/to/staging может завершиться ошибкой и оставить /live/website в очень ужасном состоянии. В сценарии с автоматическим обновлением лучше передать право собственности на каталог непосредственно механизму обновления, что означает, что все изменения файла должны происходить только из git pull, но не из-за непосредственного редактирования / фиксации там. Вы можете вносить исправления в клоне /live/website, а затем помещать эти изменения в /path/to/staging, который затем распределяет ваши изменения обратно в /live/website (но не вводите в /live/website [что приводит к тому, что git портит ваш индекс ], и не тяните туда изменения клона, потому что тогда вам может потребоваться объединить разные истории разработки из вашего клона и /path/to/staging в /live/website, что определенно не то, что вы хотите).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...