Подтвердить что ты не робот

Почему мне нужно "git push -set-upstream origin <branch>"?

Я создал локальную ветку для тестирования Solaris и Sun Studio. Затем я подтолкнул ветку вверх по течению. После внесения изменений и попыток нажать изменения:

$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
 1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin solaris

Зачем мне делать что-то особенное для этого?

Есть ли разумный случай использования, когда кто-то создавал бы <branch>, нажимал <branch> на удаленный, а затем утверждал, что фиксация на <branch> не должна быть для <branch>?


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


Здесь вид на другой машине. Филиал явно существует, поэтому он был создан и нажат:

$ git branch -a
  alignas
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/alignas
  remotes/origin/arm-neon
  remotes/origin/det-sig
  remotes/origin/master
  remotes/origin/solaris
4b9b3361

Ответ 1

TL; DR: git branch --set-upstream-to origin/solaris


Ответ на заданный вами вопрос, который я перефразирую как "должен ли я установить восходящий поток" - это: нет, вам не нужно устанавливать восходящий поток вообще.

Если у вас нет восходящего потока для текущей ветки, однако, Git изменяет свое поведение на git push, а также на другие команды.

Полная толковая история здесь длинная и скучная и возвращается в историю до версии Git версии 1.5. Чтобы сократить его, git push был реализован плохо. 1 Начиная с версии Git версии 2.0, Git теперь имеет ручку конфигурации push.default, которая по умолчанию имеет значение simple. Для нескольких версий Git до и после 2.0 каждый раз, когда вы запускаете git push, Git будет вызывать много шума, пытаясь убедить вас установить push.default только для того, чтобы закрыть git push.

Вы не указываете, какую версию Git вы используете, и не настроили ли вы push.default, поэтому мы должны угадать. Я предполагаю, что вы используете Git версию 2-point-something, и что вы установили push.default в simple, чтобы заставить ее заткнуться. Какая версия Git у вас есть, и что, если что-то, что у вас есть, push.default установлено, имеет значение, из-за этой длинной и скучной истории, но в конце концов тот факт, что вы получаете еще одну жалобу от Git указывает, что ваш Git настроен так, чтобы избежать одной из ошибок из прошлого.

Что такое восходящий поток?

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

Каждая ветвь имеет возможность иметь один (1) восходящий набор. То есть каждая ветвь имеет восходящий поток или не имеет восходящего потока. Ни одна ветка не может иметь более одного восходящего потока.

Верхний поток должен, но не обязательно, действительной ветвью (будь то дистанционное отслеживание, например origin/B или локальное, например master). То есть, если текущая ветвь B имеет верхний U, git rev-parse U должен работать. Если он не работает - если он жалуется, что U не существует, то большинство из Git действует так, как будто восходящий поток вообще не установлен. Несколько команд, например git branch -vv, покажут восходящую настройку, но отмечают ее как "ушли".

Какая польза от восходящего потока?

Если ваш push.default установлен на simple или upstream, то восходящий параметр сделает git push, который используется без дополнительных аргументов, просто работает.

Это то, что все это делает для git push. Но это довольно значимо, так как git push является одним из мест, где простая опечатка вызывает серьезные головные боли.

Если ваш push.default установлен на nothing, matching или current, установка восходящего потока вообще ничего не делает для git push.

(Все это предполагает, что ваша версия Git не менее 2.0.)

Верхний поток влияет на git fetch

Если вы запустите git fetch без дополнительных аргументов, Git выяснит, какой удаленный выбор из него вызывается, консультируясь с текущей ветвью вверх. Если восходящий поток является ветвью удаленного отслеживания, Git выбирается с этого пульта. (Если восходящий поток не установлен или является локальной ветвью, Git пытается извлечь origin.)

Верхний поток влияет на git merge и git rebase тоже

Если вы запустите git merge или git rebase без дополнительных аргументов, Git использует текущий ветвь вверх. Таким образом, это сокращает использование этих двух команд.

Верхний поток влияет на git pull

В любом случае вы никогда не должны 2 использовать git pull, но если вы это сделаете, git pull использует настройку восходящего потока, чтобы определить, какой удаленный выбор извлекается, а затем какая ветка объединяется или пересоединяется с, То есть git pull делает то же самое, что и git fetch, потому что на самом деле он запускает git fetch, а затем делает то же самое, что и git merge или git rebase, потому что на самом деле он запускает git merge или git rebase.

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

Верхний поток влияет на git status

Это может быть самым важным. После того, как у вас есть восходящий набор, git status может сообщить разницу между вашей текущей веткой и ее восходящим потоком в терминах коммитов.

Если, как и в обычном случае, вы находитесь в ветке B с установленным вверх адресом до origin/B, и вы запустите git status, вы сразу увидите, можете ли вы совершить то, что вы можете нажать, и/или совершить вы можете объединить или переустановить.

Это связано с тем, что git status работает:

  • git rev-list --count @{u}..HEAD: сколько коммитов у вас есть на B, которые не находятся на origin/B?
  • git rev-list --count [email protected]{u}: сколько коммитов у вас есть на origin/B, которые не находятся на B?

Настройка восходящего потока дает вам все эти вещи.

Почему master уже имеет восходящий набор?

Когда вы сначала клонируете какой-то пульт, используя:

$ git clone git://some.host/path/to/repo.git

или аналогичный, последний шаг Git действительно, по существу, git checkout master. Это проверяет вашу локальную ветвь master - только у вас нет локальной ветки master.

С другой стороны, у вас есть ветвь удаленного отслеживания с именем origin/master, потому что вы просто клонировали ее.

Git догадывается, что вы, должно быть, имели в виду: "Сделайте мне новый локальный master, который указывает на ту же фиксацию, что и дистанционное отслеживание origin/master, и, пока вы на нем, установите восходящий поток для master до origin/master."

Это происходит для каждой ветки, которую вы git checkout, которой у вас еще нет. Git создает ветку и делает ее "дорожкой" (имеет в качестве восходящего потока) соответствующую ветвь удаленного отслеживания.

Но это не работает для новых ветвей, т.е. ветвей без ветвей удаленного отслеживания.

Если вы создаете новую ветку:

$ git checkout -b solaris

пока еще нет origin/solaris. Ваш локальный solaris не может отслеживать ветвь удаленного отслеживания origin/solaris, потому что ее не существует.

Когда вы сначала нажимаете новую ветку:

$ git push origin solaris

который создает solaris на origin, и, следовательно, также создает origin/solaris в вашем собственном репозитории Git. Но это слишком поздно: у вас уже есть локальный solaris, у которого нет восходящего потока. 3

Не следует ли Git установить это, теперь, как восходящий поток автоматически?

Возможно. См. "Выполнено плохо" и примечание 1. Теперь трудно изменить: существуют миллионы скриптов, которые используют Git, и некоторые из них могут сильно зависеть от его текущего поведения. Для изменения поведения требуется новый основной выпуск, nag-ware, чтобы заставить вас установить какое-либо поле конфигурации и т.д. Короче говоря, Git является жертвой своего собственного успеха: любые ошибки, которые он имеет в нем, сегодня могут быть исправлены только в том случае, если изменение является либо в основном невидимым, ясно-намного лучше, либо медленно с течением времени.

Дело в том, что это не сегодня, если вы не используете --set-upstream или -u во время git push. Это то, что сообщение говорит вам.

Вам не обязательно это делать. Ну, как мы уже отмечали выше, вам не нужно это делать вообще, но позвольте сказать, что вы хотите вверх по течению. Вы уже создали ветвь solaris на origin через более ранний push, и, как показывает ваш вывод git branch, у вас уже есть origin/solaris в вашем локальном репозитории.

Вы просто не устанавливаете его как восходящий поток для solaris.

Чтобы установить его сейчас, а не во время первого нажатия, используйте git branch --set-upstream-to. Подкоманда --set-upstream-to принимает имя любой существующей ветки, например origin/solaris, и устанавливает текущую ветвь вверх по течению к этой другой ветке.

Это то, что все, что он делает, но имеет все эти последствия, отмеченные выше. Это означает, что вы можете просто запустить git fetch, затем осмотритесь, а затем запустите git merge или git rebase, а затем создайте новые коммиты и запустите git push, не куча дополнительных проблем.


1 Чтобы быть справедливым, тогда было неясно, что первоначальная реализация была подвержена ошибкам. Это стало ясно, когда каждый новый пользователь делал одни и те же ошибки каждый раз. Теперь он "менее беден", что не означает "большой".

2 "Никогда" немного силен, но я нахожу, что Git новички понимают вещи намного лучше, когда я отделяю шаги, особенно когда я могу показать им, что git fetch на самом деле а затем они могут увидеть, что будет делать git merge или git rebase.

3 Если вы запустите свой первый git push как git push -u origin solaris -ie, если вы добавите флаг -u - Git, установите origin/solaris в качестве восходящего потока для вашей текущей ветки если (и только если) нажатие преуспевает. Поэтому вы должны поставить -u при первом нажатии. Фактически, вы можете поставить его на любой последующий толчок, и он установит или изменит восходящий поток в этой точке. Но я думаю, что git branch --set-upstream-to проще, если вы забыли.

4 Измеряется методом Austin Powers/Dr Evil, просто говоря "один MILLLL-YUN", во всяком случае.

Ответ 2

В основном полная команда похожа на git push <remote> <local_ref>:<remote_ref>. Если вы запускаете только git push, git не знает, что делать точно, если вы не сделали какой-либо конфиг, который помогает git принять решение. В репозитории git мы можем настроить несколько пультов. Также мы можем перенаправить локальный номер на любой удаленный номер ref. Полная команда - самый простой способ сделать нажатие. Если вы хотите ввести меньшее количество слов, сначала нужно настроить конфигурацию, например, --set-upstream.