Быстрый ответ: Самый простой способ исправить это - Сделать существующую ветку Git отслеживающей удаленную ветвь?
Что на самом деле здесь происходит
Я всегда находил, что описания "отслеживающих веток" git меня смущают. Они звучат, по крайней мере для меня, как будто они делают намного больше, чем на самом деле.
Я думаю, что хитрость заключается в том, чтобы понять, что git вообще никогда не "отслеживает" удаленный репозиторий. (Он извлекает из удаленного репо.) Вместо этого "отслеживающая ветвь" отслеживает ветку в вашем собственном репо . Чтобы «отслеживать удаленную ветку», вы создаете ветку, имя которой говорит, что она была первоначально скопирована из какого-либо другого репо. (Под обложками это означает любую ветвь, хранящуюся в refs/remotes/
, более или менее.) Наиболее распространенным «другим репо» является тот, который называется origin
, который является тем, который для вас устанавливает начальная git clone
. Как сказано в справочной странице git-clone:
Эта конфигурация по умолчанию достигается созданием ссылок на удаленные головки веток в refs/remotes/origin
и инициализацией переменных конфигурации remote.origin.url
и remote.origin.fetch
.
Когда вы используете git branch --track
для создания ветви, новая ветка «отслеживает» «начальную точку», которую вы ей даете. (И «отслеживать» в основном означает «связываться с различными действиями push / pull / fetch» и сообщать мне больше, когда я запускаю git status
.) Итак, предполагая, что репо, из которого вы клонировали, уже имеет ветку stats_page
, вы, вероятно, означало сделать это:
git branch --track stats_page origin/stats_page
, который говорит git «создать новую ветку с именем stats_page
, которая отслеживает то, что у меня есть в refs/remotes/origin/stats_page
» (обычно вы пропускаете части refs/heads
и refs/remotes
, а git вычисляет их). Вам даже не нужно --track
здесь, так как origin/
часть справа включает это для вас.
Как только вы сделаете все это, в терминологии git у вас появится «локальная» ветвь (refs/heads/stats_page
), которая отслеживает «удаленную» ветвь (refs/remotes/origin/stats_page
). Для фактического обновления «удаленной» ветки вы используете git fetch
, или, более точно, git fetch origin
, который идет по URL-адресу, связанному с origin
, собирает все новые вещи и затем добавляет их в репозиторий. Следовательно, несмотря на то, что он называется «удаленным», он все же удивительно локальный: он прямо на вашем локальном диске.
(Я стал называть git "Borg SCMs": "Мы - git-Borg. Мы добавим вашу уникальность в коммит". Большая часть того, что вы делаете, просто добавляет новые вещи в ваш собственный репозиторий). Borg-коллектива.)
Как только вы используете git fetch
для обновления вашей локальной копии «удаленной» ветви (origin/stats_page
), вы можете сделать git merge
, чтобы объединить ее (до stats_page
, имя без origin/
часть). И git pull
просто запускает эти два в один простой шаг - что скрывает тот факт, что это fetch
, который на самом деле получает новые вещи с "удаленного"
Теперь проблема в том, что когда вы бежали:
git branch --track stats_page
вы были в своей ветке master
, поэтому вы создали новую "локальную" ветку с именем stats_page
, которая отслеживает ваш master
вместо отслеживания origin/stats_page
. Следовательно, git pull
и git push
просто потяните и нажмите на локальную ветвь с именем master
. (Примечание: если вы на самом деле запускаете git fetch
, он все равно извлекается в remotes/origin/*
, поэтому он все равно обновляет origin/stats_page
, даже если одна «локальная» ветвь ошибочно отслеживает другую «локальную» ветвь.)
Последнее замечание: обычно, когда вы создаете «локальную» ветвь, которая отслеживает удаленную ветвь с тем же именем, вы также хотите немедленно сделать git checkout
. Вы можете просто git checkout -b stats_page origin/stats_page
сделать все три шага одновременно. (Если ваша версия git старая, она может не отслеживать автоматически, когда вы называете origin/stats_page
справа; но если это так, вам, вероятно, следует просто обновить свою версию git.)
Footnote: Некоторые люди вообще не рекомендуют использовать
git pull
, и я с ними согласен.
git pull
действительно смешивает две совершенно разные операции.В частности,
git pull remote_A remote_B
, кажется, удивляет людей, когда происходит слияние осьминога.Использование
git fetch
никогда не удивляет людей;и как только они привыкли к явному
git merge
и познакомились с ним, логика ускоренного слияния становится намного понятнее.Тем не менее,
git pull
без аргументов так удобно ....