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
,