2014-09-12 8 views
0

У меня есть локальный сервер-разработчик, где я делаю все свои изменения, мы будем называть это local. У меня есть установка git repo в папке git на моем webserver, мы назовем это gitfolder. И тогда у меня есть мои живые файлы, которые выталкиваются из gitfolder каждый раз, когда я нажимаю push, мы назовем это live.Git head через пост-обновление

Мой рабочий процесс.

Редактировать файлы, фиксировать изменения, нажимать на webserver. Затем послезаголовок берет на себя следующее:

#!/bin/sh 
export GIT_WORK_TREE=/path/to/live 
git checkout -f 

Это прекрасно работает. Однако здесь лежит мой вопрос. Я хочу вернуть git change, и я бы обычно делал это через git reset --hard commit - но я, если я перейду к live, очевидно, что это не git-репо.

Когда я иду к gitfolder и запустить ту же команду git reset --hard commit она не обновляется live, и я получаю ошибку «фатальным: Эта операция должна выполняться в рабочем дереве»

шаги предпринять? На данный момент я пошел и скопировал свою папку local и сделал local2 - и на local2 я вернул изменение, а затем нажал на live, так что моя папка local все еще имеет все изменения.

Я НЕ ХОЧУ REVERT local - Только на live

ответ

3

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

В этом случае, просто войти в систему на сервере, cd голого хранилище, и запустить:

git checkout --work-tree=/path/to/live checkout -f <commit-ID> 

или:

GIT_WORK_TREE=/path/to/live git checkout -f <commit-ID> 

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


Хотя я думаю, что это дословный ответ на ваш вопрос, я хотел бы отметить, что-то другое: если вы git revert плохой фиксации в собственном локальном хранилище, вы получите новый коммит, который отменяет действие плохой фиксации, но плохой фиксатор все еще там. После этого вы можете нажать на результат на сервер, обычным образом:

... - o - X - o - U <-- master, origin/master 

где X является плохой фиксации и U является обязательство, что «не-делает», что делает X. Для иллюстрации я включил неинтересный o фиксацию между ними.

Теперь вы можете просто вернуть ваш Revert, чтобы ваш местный репо заканчивается с «плохим» коммит быть переигран еще раз:

... - o - X - o - U  <-- origin/master 
        \ 
         X' <-- master 

где X' копия плохой фиксации, что «не- делает "уничтожение это U сделал. Теперь вы можете исправить ошибку, сделать еще одну фиксацию сверху или git commit --amend и т. Д., И когда все это сработает, результат снова появится на сервере. Это было бы более типичным способом решения этой проблемы.


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

Например, скажем, дерево на local выглядит так, нарисованный с изломом, чтобы убедиться, что я могу добавить метку:

... - o - R 
      \ 
       X - o - o -...- o <-- HEAD=master, origin/master 

Здесь R это коммит вы хотите, чтобы сервер для сброса к , а X и дополнительные коммиты - это те, которые обновляют плагины Wordpress и так далее. (. Я предполагаю, что вы работаете на ветви master, изменение при необходимости)

Между тем, над на сервере, все выглядит так:

... - o - R 
      \ 
       X - o - o -...- o <-- HEAD=master 

Если вы хотите сохранить все коммиты на сервер, мы должны дать окончательному o передать новое имя филиала, так как нам придется принудительно обновить master. Так что на local, мы могли бы работать так:

$ git push origin master:save 

Это позволит создать новую ветку на сервере, называется save, так что он теперь выглядит следующим образом:

... - o - R 
      \ 
       X - o - o -...- o <-- HEAD=master, save 

update крючок сделать обычный git checkout -f, который проверяет ветвь HEAD (поскольку ветка не указана), которая в этом случае равна master, поэтому сервер обновляется до последнего o commit (бессмысленно, он уже существует).Но дальше, мы делаем это, опять же на local:

$ git branch for-server <commit-ID-for-R> 

Это изменяет установку на local выглядеть следующим образом:

... - o - R      <-- for-server 
      \ 
       X - o - o -...- o <-- HEAD=master, origin/master 

Не очень интересно, но в следующем:

$ git push --force origin for-server:master 

Это (с --force) сообщает серверу принудительно обновить его master, чтобы указать на фиксацию R, после чего он имеет следующее:

... - o - R      <-- HEAD=master 
      \ 
       X - o - o -...- o <-- save 

Это save этикетка сохраняет оставшиеся фиксации в хранилище на сервере. Пробежка post-update бежит и делает git checkout -f, который использует HEAD, что указывает на master, что указывает на фиксацию R. Таким образом, веб-сервер должен теперь выполнить фиксацию R.

Назад на local, вам просто нужно помнить, что for-server соответствует master на пульте дистанционного управления. (Если вы хотите, вы можете переименовать все ваши местные отделения в соответствии с именованием на сервере:.. Изменение master к save и изменить for-server к master, например, что все зависит от этого)

Обратите внимание, что единственное save делает на сервере, фиксирует X и все последующие o s. Это хорошо, если вы хотите напрямую работать на сервере или не хотите отправлять эти сообщения обратно через сеть. Однако, если на сервере (который имеет рабочий каталог, так как он не является голым репо), вы получите git checkout save, вы измените HEAD, чтобы указать на save, а при следующем запуске крюка post-update он развернет версию save , а не версию master.

+0

У меня нет открытого хранилища. На сервере у меня есть каталог git с удаленной настройкой, чтобы выглядеть так: '[email protected]: ~/home/git/project.git' Когда я перехожу к' project.git' и запускаю вашу команду, я получите ошибку: 'fatal: эта операция должна выполняться в дереве работ –

+0

А, это все будет работать с не-обнаженным репо (хотя вы столкнулись со всеми обычными проблемами с обновлением текущей ветви, vs кто-то работает с не-голым репо). Ошибка несколько озадачивает: с '--work-tree =' или 'GIT_WORK_TREE =' вы заставляете git использовать другой путь в качестве дерева работ. Этот путь должен существовать, иначе крюк обновления не будет работать. – torek

+0

Благодарим вас за редактирование исправления плохого коммита. Однако для меня это не так. Я обновил довольно много плагинов Wordpress, подтолкнул их к серверу, а затем понял, что они несовместимы. Я не могу их обновить, и с тех пор я сделал несколько коммитов. Поэтому я пытался вернуться к фиксации до того, как я сделал какие-либо обновления, исправлю проблемы с сервером, а затем вернусь к последней фиксации. –

Смежные вопросы