Зачем мне явно выдвигать новую ветку?

180

Я новичок gitи я тренируюсь. Я создал локальную ветку, но увидел, что когда я это сделал, git pushмоя ветка не была загружена в репозиторий. Я должен был на самом деле: git push -u origin --all.
Почему это? Разве ветвь не является новым изменением, которое будет добавлено по умолчанию? Зачем мне запускать вторую команду?

Кратил
источник
15
Обратите внимание, что это настраивается (настройку push.defaultсм. man git-config). Если вы это сделаете git config --add push.default current, то git pushпри необходимости автоматически создадут ветку в удаленном репо. Почему это не по умолчанию объясняется в ответах.
Слёске
@Sleske Я согласен. Для других политик ' current' и ' upstream' см. Мой старый ответ stackoverflow.com/a/13751847/6309 .
VonC
Почему бы не принять ответ?
laike9m

Ответы:

224

Фактическая причина в том, что в новом репо (git init) нет веток (нет master, вообще нет веток, ноль веток)

Поэтому, когда вы впервые подталкиваете к пустому репозиторию (обычно пустое ), у этого вышестоящего репо нет ветки с таким же именем.

И:

В обоих случаях, поскольку обратное пустое хранилище не имеет ветки:

  • пока нет соответствующей именованной ветви
  • нет восходящей ветки вообще (с тем же именем или без него! Отслеживание или нет)

Это означает, что ваш местный первый толчок понятия не имеет:

  • куда толкать
  • что нажать (так как он не может найти какую-либо ветку восходящего потока, либо записанную как удаленную ветвь отслеживания, и / или имеющую то же имя)

Так что вам нужно хотя бы сделать:

git push origin master

Но если вы делаете только это, вы:

  • создаст восходящую masterветвь в вышестоящем (теперь непустом репо): хорошо.
  • не будет записывать, что локальная ветвь ' master' должна быть отправлена ​​в upstream ( origin) ' master' (вышестоящая ветвь): плохо.

Вот почему рекомендуется для первого нажатия:

git push -u origin master

Это будет записывать в origin/masterкачестве удаленного филиала отслеживания , и позволит следующий толчок автоматически нажать masterна origin/master.

git checkout master
git push

И это тоже будет работать с политиками push currentили ' upstream'.
В каждом случае, после начального git push -u origin master, простого нажатия git будет достаточно, чтобы продолжить отправку master в правую ветвь вверх по течению.

VonC
источник
2
После этой точки следующий git pushтакже ожидает, что ветвь уже существует?
Cratylus
2
Да. Он будет отправлять любые обновления в эту ветку в репозиторий upstream.
RyPeck
@Cratylus yes, из-за новой политики push по умолчанию ' simple': push для любой записанной восходящей ветви, если эта восходящая ветвь имеет то же имя, что и локальная. Простого git pushбудет достаточно.
VonC
1
@ButtleButkus Спасибо. Я восстановил ссылку.
VonC
3
Для более общего случая спрашивающего о новой ветке 'new_branch' вы должны использовать git push --set-upstream origin new_branchили git push -u origin new_branchдля краткости. То, -allчто использовал спрашивающий, обошло наименование конкретной новой ветви, включив все ветви. Это покрыто + Klas Mellbourn в его ответе.
Пол Масри-Стоун
106

Вы не видите ниже

Я нахожу эту «особенность» довольно раздражающей, так как я не пытаюсь запускать ракеты на Луну, просто нажмите на мою чертову ветку. Вы, вероятно, тоже, иначе вы не были бы здесь!

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

git config --global push.default current

Так что если вы делаете ветки, как это:

git checkout -b my-new-branch

а затем сделать некоторые коммиты, а затем сделать

git push -u

вывести их в исходное положение (находясь в этой ветви), и он создаст указанную для вас ветку, если она не существует.

Обратите внимание, что бит -u гарантирует, что они связаны, если позже вы извлечете их из указанной ветви. Если вы не планируете тянуть ветку позже (или у вас все в порядке с другим лайнером, если вы это делаете) - u не требуется.

Джон Кульвинер
источник
3
Когда я делаю это, если я делаю git pull, сразу после - две ветви не связаны. :(
Алиссо
это единственный ответ, который решил мою проблему.
Рэймонд Шенон
2
Чтобы связать их, используйтеgit push -u
Бен
Спасибо! Этот ответ должен быть принят как быстрое и «грязное» решение. Я уверен, что это ближе всего к тому, что задумал ОП.
youngrrrr
3
> Я не пытаюсь запустить ракеты на Луну. -- ДА.
VCavallo
39

Вывод при git pushнажатии на новую ветку

> git checkout -b new_branch
Switched to a new branch 'new_branch'
> git push
fatal: The current branch new_branch has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin new_branch

Простое git pushпредполагает, что уже существует удаленная ветвь, которую отслеживает текущая локальная ветвь. Если такой удаленной ветви не существует, и вы хотите ее создать, вы должны указать это с помощью флага -u(краткая форма --set-upstream).

Почему это так? Я предполагаю, что разработчики чувствовали, что создание ветки на удаленном компьютере является настолько важным действием, что это должно быть трудно сделать по ошибке. git pushэто то, что вы делаете все время.

"Разве ветвь не является новым изменением, которое будет добавлено по умолчанию?" Я бы сказал, что «изменение» в Git - это коммит. Ветвь - это указатель на коммит. Для меня имеет больше смысла думать о push как о чем-то, что подталкивает коммиты в другие репозитории. То, какие коммиты отправляются, определяется тем, в какой ветке вы находитесь, и отношениями отслеживания этой ветви к удаленным веткам.

Подробнее о отслеживании веток вы можете прочитать в главе «Удаленные ветки» книги Pro Git .

Клас Меллборн
источник
Я не получил, fatalно я уже сделал коммит в ветке. Это имеет значение?
Cratylus
@Cratylus нет, это не имеет значения. Коммит безопасен в вашем репозитории, и git push -u originскопировал его в удаленный репозиторий.
Клас Меллборн
Нет, я имею в виду тот факт, что я не получил fatalсообщение, подобное тому, которое вы упомянули в ответе. Зависит ли это различие от того, что я передал что-то в ветку?
Cratylus
@Cratylus Я не знаю, почему вы не получили fatalсообщение. Я предполагаю, что разница зависит от того, какую именно реализацию git вы используете. Мой вывод из 1.8.1.msysgit.1 работает на Windows 8.
Klas Mellbourn
У меня та же версия, но на Vista
Cratylus
4

Первоначальные разработчики не смогли быстро найти обоснование, но я могу дать вам обоснованное предположение, основанное на нескольких годах опыта работы с Git.

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

Кроме того, куда следует git pushотправлять все филиалы? Git может работать с несколькими пультами, и вы можете захотеть иметь разные наборы веток на каждом. Например, центральный проект GitHub repo может иметь ветки релизов; ветка GitHub может иметь ветки тем для просмотра; и локальный сервер Git может иметь ветви, содержащие локальную конфигурацию. Если git pushбы отодвинуть все ветви к удаленному, что отслеживает текущая ветка, такую ​​схему было бы легко испортить.

Фред Фу
источник
1). It might represent a private experimentХорошо, но в чем дело? «Основная» ветка, в которой все работают, т.е. masterне затронута. Если вы не хотите скрыть исходный код 2) git push, without a remote, pushes to the current branch's remoteЯ потерял вас здесь :(
Cratylus
@Cratylus: 1) в проекте с десятками разработчиков, которые все разветвляют ad lib, вы получите очень грязные репозитории. Я работаю над такими проектами, и я бы не хотел git fetchкаждый раз создавать сотни наполовину работающих ветвей. 2) Я имею в виду git pushповедение по умолчанию. Это выдвигает к удаленному, что текущая ветвь отслеживает, если таковые имеются.
Фред Фу
3

HEAD - это сокращение от текущей ветви, поэтому git push -u origin HEAD работает. Теперь, чтобы избежать этой типизации каждый раз, когда я использую псевдоним:

git config --global alias.pp 'push -u origin HEAD'

После этого, каждый раз, когда я хочу отправить ветку, созданную через ветку git -b, я могу нажать ее, используя:

мерзавец пп

Надеюсь, это сэкономит время для кого-то!

Ауримас Рекштис
источник
2

При первой проверке

Шаг 1: git remote -v
// если найден git initialize, то удалить или пропустить шаг 2

Шаг 2: git remote rm origin
// Затем настройте ваш адрес электронной почты глобально Git

Шаг 3: git config --global user.email "youremail@example.com"

Шаг 4: git initial

Шаг 5: git commit -m "Initial Project"
// Если вы уже добавили репозиторий проекта, пропустите шаг 6

Шаг 6: git remote add origin %repo link from bitbucket.org%

Шаг 7: git push -u origin master

Md.Milton
источник
1

Я только что испытал дальнейшую перестановку этой проблемы.

У меня была названа ветка, feat/XYZ-1234-some-descriptionпотому что я работал над проблемой Jira 1234. Во время работы я создал новую проблему Jira, чтобы отследить небольшую часть работы, и когда я пришел, я решил нажать на название ветви с этим новым номером проблемы. в:

git push -u origin feat/XYZ-5678-a-different-description # failed

Это дало мне ошибку, обсуждаемую в этой теме. Но поскольку я пытался перейти к другому имени ветви, отличному от текущего, моя проблема отличалась от описанной здесь. Я закончил тем, что переименовал свою местную ветку прежде, чем я мог нажать ее:

git branch -m feat/XYZ-1234-some-description feat/XYZ-5678-a-different-description
git push -u origin feat/XYZ-5678-a-different-description # now works

После того, как немного больше чтения вокруг , я понял , что я мог бы поставил srcна git push, либо к текущему имени ветви, или только в HEADслучае необходимости:

git push -u origin feat/XYZ-1234-some-description:feat/XYZ-5678-a-different-description # also works
Марк Бирбек
источник
-1

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

*git push -f
fatal: The current branch Coding_Preparation has no upstream branch.

Чтобы протолкнуть текущую ветку и установить пульт в качестве восходящего, используйте

git push -u origin new_branch_name


** Successful Result:** 
 git push -u origin Coding_Preparation
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 599 bytes | 599.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'Coding_Preparation' on GitHub by visiting: ...
 * [new branch]      Coding_Preparation -> Coding_Preparation
Branch 'Coding_Preparation' set up to track remote branch 'Coding_Preparation' from 'origin'.
Мукеш Кумар
источник