Git отслеживать удаленную ветку, но нажать на другую ветку?

Предположим, у меня есть ветвь с именем 'my-local-changes', которая является локальной ветвью, которая была создана из ветки с названием 'some-remote-branch', которая является удаленной веткой.

Давайте также предположим, что существует третья ветвь с именем "разработка", которая является удаленной ветвью, в которую код извлекается из нескольких ветвей (одна из них - "некоторая удаленная ветвь", у меня также есть локальная ветка, которая называется "разработка"). отслеживает ветку удаленной разработки)

Мой вопрос заключается в том, как я могу настроить "мои локальные изменения", чтобы отслеживать ветку "разработки", но нажать на ветку "некоторая удаленная ветка"?

Для тех, кто интересуется, почему я хочу это сделать, я хотел бы иметь возможность запускать git status и видеть, отстаю ли я за "разработкой", при этом мне не нужно переключаться на эту ветку, и легко все еще иметь возможность нажать на " некоторый-удаленный филиал"

Мой текущий процесс выглядит следующим образом (я также хотел бы получить предложения по улучшению этого)

git checkout -b my-local-branch some-remote-branch

(внести некоторые изменения и добавить их)

git fetch origin 
git checkout develop
git status

(сделать это, чтобы увидеть, если какие-либо изменения в разработке, которые мне нужно объединить, если не запустить)

git push origin my-local-branch some-remote-branch

1 ответ

Решение

(Не уверен, почему вопрос опущен, 1, и вы все равно почти сами на него ответили...)

Вы почти у цели: просто настройте push.default в simple или же nothing, так что вы должны указать цель push для этого случая, а затем для вашей последней команды используйте:

git push origin my-local-branch:some-remote-branch

Это работает так, что git push принимает после origin (название пульта), серия refspecs. Refspec не очень сложен: это просто пара имен, как master:master, или же develop:develop, или же develop:foo опционально с лидирующим знаком плюс + и опционально опуская либо имя, либо имя: :foo или же develop,

Refspecs немного усложняется тем, что они работают по-разному в git fetch а также git push, когда вы пропустите одно из двух имен. Если вы используете оба имени каждый раз, они остаются простыми: имя слева - это имя в исходном репозитории, а имя справа - это имя в месте назначения. За fetchисточником является удаленный, а местом назначения является ваш собственный репозиторий. За push Источник - ваш репозиторий, а пункт назначения - удаленный.

Оставляя имя источника работает только с push и в данном случае это означает удаление. следовательно git push origin :foo значит удалить foo на удаленном origin, (Это не то, что вы хотите, поэтому избегайте этого.)

Отсутствие имени пункта назначения работает как с fetch а также push но значит разные вещи для них. Давайте просто проигнорируем fetch Вот. С push, это означает, что использовать одно и то же имя на локальном и удаленном. Так как вы не хотите этого здесь, не используйте это здесь. (Или для тех случаев, когда вы этого хотите, используйте его.)

Ведущий + знак, если присутствует, означает то же, что --force, (По факту --force просто добавляет + на все.)

Если вы бежите git push origin, или же git push (даже без remote аргумент), Git смотрит вверх push.default чтобы увидеть, что подтолкнуть. Установка его в nothing означает просто сбой / ошибка, так что я должен ввести refspec. Установка его в simple означает передачу только одной ветви, текущей ветви, в восходящую ветку текущей ветви, но также требует, чтобы имя восходящей ветки совпадало. поскольку my-local-branch а также some-remote-branch не совпадают, это не удастся для вашего случая местного филиала foo отслеживает удаленное отслеживание ветки origin/develop: имена foo а также develop не совпадают.

В любом случае, Git заставит вас ввести refspec для этого push.

С nothing Git заставит вас вводить refspec для каждого нажатия. (Я использовал это, и это работает, но это не очень удобно.) С simple Конфигурация, Git позволит вам develop к верхнему течению develop легко, и позволит вам подтолкнуть foo вверх по течению develop (или вверх по течению jazzy или любое другое имя, кроме foo) явно, но не будет давить foo в foo так как это не определено выше по течению. (Я использовал это, и это работает лучше.)

Начиная с версии Git 2.0, simple это конфигурация по умолчанию. Так что, если у вас Git версии 2.0 или выше, вы уже готовы к работе. Если нет, посмотрите, можете ли вы обновить версию Git, но push.default настраивается еще в Git версии 1.6. (Я не уверен, какие значения он может принять, тогда. Текущие значения набора 5 возвращаются к 1.7.11, если не раньше, я думаю.)

Для полноты, три других возможных значения: current, upstream, а также matching, current Значение означает использовать имя текущей ветви: git push origin $branch:$branch где $branch текущая ветка. upstream Значение означает использовать восходящее имя текущей ветви: git push origin $branch:$merge, где $merge из git config --get branch.$branch.merge,

matching Значение сложнее всего описать, и оно было по умолчанию до Git версии 2.0: это значит, получить список всех веток на удаленном компьютере, сопоставить их имена и имена наших локальных ветвей, а затем выполнить массовую передачу всех наши локальные филиалы к одноименной ветви на удаленном компьютере, где совпадают два имени. Это не очень безопасная настройка, хотя до тех пор, пока вы не используете --force на самом деле он работает довольно хорошо, поэтому его можно было использовать в течение многих лет.

Дополнительные примечания: терминология

Терминология Git - это беспорядок.

  • Локальная ветвь (или просто "ветвь" или "название ветки"), например master это имя в refs/heads/ имя-пространства. Он указывает на идентификатор фиксации. Когда вы делаете новый коммит, находясь в этой ветви, Git считывает ID коммита, делает новый коммит с этим ID в качестве родителя нового коммита, а затем записывает ID нового коммита в имя ветви, так что ветка теперь указывает на новый коммит (который, в свою очередь, указывает на предыдущий ответвление и т. д.).

    Вы можете git checkout местный филиал, который ставит вас на "на ветке", так что git status говорится On branch master например. Это настраивает так, чтобы новые коммиты продвигали ветку, как я только что отметил выше.

  • Ветка удаленного слежения, как origin/master это имя в refs/remotes/ имя-пространства. После refs/remotes/ мы находим название самого пульта, origin затем еще одна косая черта, и, наконец, название ветви, как видно на том удаленном refs/heads/ конечно). Эти имена хранятся локально, в вашем собственном хранилище: на самом деле они вообще не удалены. Они просто автоматически обновляются, когда ваш Git связывается с пультом, через git fetch и (в более ограниченной степени) через git push,

    Вы можете git checkout ветка удаленного слежения, но если вы это сделаете, git checkout переводит вас в режим "отсоединенная ГОЛОВА", так что git status а также git branch утверждают, что вы не в какой-либо ветке (или не в "ветке" или подобной, иногда используя фразу "detached HEAD"). Когда это происходит, вы фактически находитесь в (единственном, специальном) анонимном филиале. Когда вы вернетесь в обычную ветку, любая работа, которую вы выполняли в анонимной ветке, со временем исчезнет. (Так что если вы хотите сохранить работу, установите имя, чтобы оно больше не было анонимным, или используйте git checkout чтобы вернуться к обычной ветке, прежде чем делать эту работу.)

  • Локальный филиал может отслеживать другой филиал (локальный или удаленный). Когда локальная ветвь B отслеживает другую ветвь U, Git называет это "восходящим потоком" локальной ветки. Этот upstream состоит из двух частей: название удаленного, как origin и название ветки, как видно на пульте, вроде master, Чтобы отслеживать локальную ветвь как ваш восходящий поток для ветки B, Git просто устанавливает для пульта . вместо.

    Следовательно, локальная ветвь B отслеживает U в восходящем направлении, если для нее настроены эти два элемента. Обычно U - это ветвь удаленного отслеживания, которая является локальной сущностью (одна из refs/remotes/ имена пространств имен). Вы должны git fetch или же git push обновить ветку (и) удаленного отслеживания, после чего git status а также git branch -vv будет сообщать о локальных филиалах, которые отслеживают удаленные отслеживающие ветви, как находящиеся впереди и / или позади своих коллег.

    Вместо этого локальная ветвь B может отслеживать другую локальную ветвь в качестве восходящей. В этом случае, поскольку все локально обновляется, git status а также git branch -vv будет актуальным без каких-либо git fetch необходимо.

    Конечно, местное отделение B не должно ничего отслеживать. Команды git branch --set-upstream-to upstream а также git branch --unset-upstream установит или отменит восходящий поток текущей ветви. Вы также можете установить, изменить и проверить две отдельные части вышестоящего branch.$branch.remote и branch.$branch.merge части) с помощью git config хотя использую git branch обычно приятнее и удобнее.


1 Возможно, отрицательный голос из-за Git 2.0 по умолчанию push.default,

Другие вопросы по тегам