git-ftp Ошибка Unknown SHA1 object, make sure you are deploying the right branch and it is up-to-date

При использовании git-ftp возможно появление ошибки типа:

Unknown SHA1 object, make sure you are deploying the right branch and it is up-to-date.
Do you want to ignore and upload all files again? [y/N]: n

в ответ на вашу попытку залить очередные изменения с помощью команды вроде:

git ftp -s <name> push

Причина

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

git ftp -s <name> push

при этом на сервер были отправлены правки, о которых ваша копия git-репозитория ничего "не знает".

Когда возникает

Эта ошибка всегда вызвана тем, что git-ftp почему-то в не знает какие файлы нужно загружать, или опасается затереть чьи-то переменные, о которых вы не знаете.

Рассмотрим возможные причины подробнее (как минимум 2 ситуации):

  1. Кто-то из вашей команды забыл залить изменения (какие-то коммиты) в центральный репозиторий, но при этом вытолкнул их на FTP сервер:

    Просто кто-то закоммитил изменения у себя на машине, а потом вытолкнул их на FTP, при этом не делая git push, то есть выполнил что-то вроде:

     git add . && git commit -m "update index"  && git ftp -s test push

    Не выполним git push, зато выполнив git ftp push -- то есть центральное хранилище не получило изменений (а значит git pull вам тут сам по себе не поможет), а вот ftp сервер их получил и теперь предупреждает вас, что вы правили свою копию, не зная о каких-то, может быть, важных изменениях.

  2. Файл .git-ftp.log пуст:

    Файл .git-ftp.log хранит id последнего залитого на FTP сервер кем-то из команды (или вами) коммита. Именно этот id сравнивается и с тем, что вы хотите залить, и если этот комит вашему локальному репозиторию не извествен, то появляется ошибка, в ситуации описанной выше.

    В случае же если данный файл вообще пуст, то git-ftp предупреждает вас о том, что хотя файл вроде и есть, но номер коммита вообще не известен.

Оперативное решение

В таком порядке (если кто-то из команды что-то не отправил в центральный репозиторий):

  1. Сделать
    git pull

    и потом сразу попробовать снова отправить изменения

    git ftp -s test push
  2. Если предыдущее не помогло -- значит кто-то из ваших коллег или вы сами в друго репозитории не отправили изменения на рабочий сервер. Попросите их сделать
    git push

    у себя (в других репозиториях), и после того, как они сделают переходите к предыдущему пункту 1.

В случае если файл .git-ftp.log пуст:
Вам придётся заново залить весь проект на FTP сервер, делаем следующее:

  1. просим всех участников сделать
    git push

    своих локальных копий в центральный репозиторий (и больше пусть ничего не делают, пока вы не восстановите работу git-ftp)

  2. сами делаем (вы у себя):
    git pull 

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

  3. Далее выполняем всё ту же команду:
     git ftp -s test push

    но в конце с соглашаемся с форсированными изменениями (в ответ на вопрос набрав английскую букву $y$ и нажав Enter):

    $ git ftp -s test push
    Unknown SHA1 object, make sure you are deploying the right branch and it is up-to-date.
    Do you want to ignore and upload all files again? [y/N]: y
    
  4. Загрузка может идти долго -- так как заливаются вообще все файлы репозитория (это эквивалентно git ftp -s test init в начале работы с сервером)
  5. Если загрузка завершилась, то: Готово! на FTP сервере в корне проекта в файле .git-ftp.log должен был появиться id вашего последнего коммита, например (или другое значение):
    97fc0dcabe66dace055c0f41159bb9710d02c589

    -- это значение меняется каждый раз как кто-то выполняет команду

    git ftp -s test push

Что делать, чтобы проблема не возникала

Чтобы проблема не возникала:

  1. При использовании графических (если используете) средств типа TurtoiseGit не забывайте сначала делать push, потом уже давать команду git-ftp для обновления сервера.
  2. Если же вы работает в режиме командной строки, используйте команду типа:
    git add . && git commit -m "your comment here" && git push && git ftp -s test push

    Такая команда не избавит вас от необходимости иногда делать git pull, но зато вы не вызовите рассматриваемую здесь ошибку у других участников команды.

  3. Следите, чтобы никто не удалял содержимое файла .git-ftp.log

Источник:

  • github.com/git-ftp/git-ftp/issues/244

Другие возможные причины

О других возможных причинах см. ниже в комментариях

vedro-compota's picture

Проблема может на наблюдаться в работе функции list_changed_files() (см. исходный код git-ftp),
а конкретно её строк-команд:

	git diff --name-only --no-renames --diff-filter=AM -z "$DEPLOYED_SHA1" -- "$SYNCROOT" 2>/dev/null > "$TMP_GITFTP_UPLOAD"
	git diff --name-only --no-renames --diff-filter=D  -z "$DEPLOYED_SHA1" -- "$SYNCROOT" 2>/dev/null > "$TMP_GITFTP_DELETE"

(наблюдалось в Windows)
Решение:
Добавить в секцию [git-ftp] для сервера, с которым вы работаете строку:

syncroot = .

Дополнительно (если предыдущее не помогает):
Кусок изменного кода начала функции (отладка исходного кода срипта git-ftp):

list_changed_files() {
	git diff --name-only --no-renames --diff-filter=AM -z "$DEPLOYED_SHA1" -- "$SYNCROOT" 2>/dev/null > "$TMP_GITFTP_UPLOAD"
	git diff --name-only --no-renames --diff-filter=D  -z "$DEPLOYED_SHA1" -- "$SYNCROOT" 2>/dev/null > "$TMP_GITFTP_DELETE"
	
	echo -e "git diff --name-only --no-renames --diff-filter=D  -z "$DEPLOYED_SHA1" -- "$SYNCROOT" " # распечатаем команду
	local git_diff_status=$?
	
	echo -e "TMP_GITFTP_UPLOAD = ${TMP_GITFTP_UPLOAD}"
	echo -e "TMP_GITFTP_DELETE = ${git_diff_status}"
	
	echo -e "status = ${git_diff_status}"
	if [ "$git_diff_status" -ne 0 ]; then

_____________
матфак вгу и остальная классика =)