Pull-only repo 'git status "говорит, что ветвь опережает начало/мастер. Зачем?

Итак, ситуация:

$git статус
# На сервере ветки
# Ваша ветка опережает "происхождение/мастер" с помощью [x]. #

Есть несколько вопросов об этом на SO уже, но ни один из них, похоже, специально не описывает тип сценария, который у меня есть. Этот ответ по одному из вопросов подходит ближе, но не вдаваться в подробности.

Я просто процитирую это дословно:

Если вы получите это сообщение после выполнения "git pull remote branch", попробуйте выполнить его с помощью "git fetch".

Кажется, что Fetch обновляет локальное представление удаленной ветки, что не обязательно происходит, когда вы выполняете "git pull remote branch".

Этот совет действительно работает. Но "не обязательно"? Почему нет? Мне нужно это понять. Что тянет не делать?

Я не хочу брать на себя этот вопрос, поэтому здесь мой сценарий подробно:

Три компьютера. Mac, на котором я разрабатываю, мой домашний сервер, на котором существует репозиторий git (т.е. Источник/ведущий), и учетную запись Webfaction, которая извлекается с этого сервера.

Я выполняю транзакции и git push origin master только на Mac. Единственной командой, которая когда-либо запускается в Webfaction как часть обычного рабочего процесса, является git pull origin master (как часть развертывания Fabric script). Я не изменяю код там. Я - одинокий разработчик, поэтому никто не делает другого.

Время от времени я вхожу в Webfaction и проверяю вещи, включая git status. Неизбежно, я всегда получаю сообщение "Ваша ветка впереди...". Запуск git fetch заставляет сообщение уходить.

Я собираюсь добавить git fetch в Fabric script для этой проблемы, но я хочу знать, почему это нужно сделать, особенно для клонирования origin-master. Я не очень разбираюсь в git, хотя ежедневно использую базовые функции, поэтому приветствую новички.

Обновить по запросу, соответствующие биты из config:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/*
    url = [email protected][server_address]:[path/to/repo.git]
[branch "master"]
    remote = origin
    merge = refs/heads/master

Ответ 1

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

В простейших терминах "git pull" делает "git fetch", за которым следует "git merge"

Что я думаю об этом. Поэтому вам не нужно вызывать git fetch после прямой git pull, но я могу почти гарантировать вам, это отлично работает на что угодно. ЗА ИСКЛЮЧЕНИЕМ ветки master.

В одном из связанных сообщений он сказал удалить следующую строку:

[remote "origin"]
    fetch = +refs/heads/*:refs/remotes/origin/* <--- Remove this

И он должен исправить эту проблему, однако я не могу объяснить, почему это работает. Мне очень сложно исследовать, но я думаю, что когда вы вызываете fetch, ваш конфигуратор git фактически указывает, что именно взять. Когда вы используете pull, я не уверен, что он считает, что синхронизация master.

Я могу гарантировать, что если вы сделали это из другого не-ведущего ветки, вы не увидите эту проблему. Надеюсь, один из гуру git может подробно объяснить строку fetch в конфигурации.

Кроме того, я бы рекомендовал вместо этого использовать следующую команду, которая устанавливает HEAD для удаленного репозитория, чтобы убедиться, что он синхронизирован с вашим локальным: git push -u origin master


Вот еще один интересный вопрос:

Имея трудное понимание git -fetch


Хорошо, поэтому я проверил это на одном из моих рабочих процессов и нашел следующее.

Когда вы выполняете git pull origin master на удаленном сервере, есть файл в каталоге .git/, который ссылается туда, где находится ваша ГОЛОВКА. Два файла, чтобы принять к сведению:

ORIG_HEAD

FETCH_HEAD

Вы заметите, что ваш FETCH_HEAD верен, но ORIG_HEAD показывает старую фиксацию, поэтому причина, по которой вы получаете Ahead by x. Когда вы запустите git fetch, вы действительно исправите ссылку в ORIG_HEAD, и все вернется в нормальное состояние. Я изучаю, как изменить строку fetch в конфиге, чтобы исправить это поведение.

Ответ 2

Если вы запустите git pull origin вместо git pull origin master, с сообщением Your branch is ahead of 'origin/master' by ... commits. не будет проблем.

Ответ 3

Смотрите этот вопрос: В чем разница между 'git pull' и 'git fetch'?

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

Я всегда делаю git fetch до git pull. Действительно, я делаю git fetch в любое время, когда я собираюсь что-то делать с удаленными ветвями.

Также связанный с этим вопрос - это очень хорошее описание git fetch, pull и merge. http://longair.net/blog/2009/04/16/git-fetch-and-merge/

Ответ 4

В моем случае - у меня было два ветки в Origin, и каждый раз, когда я тянул git, он показывал, что я опережал начало/мастер на x. Даже после жесткого переучета его в начало/мастер, как показано в Reset ветке локального репозитория, точно так же, как в удаленном хранилище HEAD.

Решение возникло, когда я просто запустил git fetch, и он привел мою ветку разработки на мой производственный сервер.