Из ваших других вопросов, я полагаю, ваша ситуация выглядит как строка 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
, что определенно не то, что вы хотите).