Git push в удаленный репозиторий или как залить локальную ветку в origin

0
310
views

Перевод статьи «Git Push to Remote Branch – How to Push a Local Branch to Origin».

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

Как запушить локальную ветку git в origin

Если вы запустите просто команду git push, не дополнив ее ничем, Git по умолчанию выберет для вас еще два параметра: удаленный репозиторий, в который направятся изменения, и ветку, которую вы отправите.

Вообще синтаксис команды следующий:

$ git push <удаленный-репозиторий> <ветка>

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

Если ваша текущая ветка — main, а вы запустите на выполнение просто git push, на самом деле будет выполняться git push origin main.

В примере, приведенном ниже, удаленный origin — это GitHub-репозиторий, а текущая ветка — main:

(main)$ git remote -v 
origin  git@github.com:johnmosesman/burner-repo.git (fetch)
origin  git@github.com:johnmosesman/burner-repo.git (push)

(main)$ git push
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 16 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 274 bytes | 274.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:johnmosesman/burner-repo.git
   b7f661f..ab77dd6  main -> main

В выводе вы можете увидеть, что локальная ветка main была запушена в удаленную ветку main:

To github.com:johnmosesman/burner-repo.git
   b7f661f..ab77dd6  main -> main

Как принудительно запушить ветку

Обычно вы заливаете что-то в ветку и пополняете ее историю коммитов.

Но бывает, что вам нужно принудительно перезаписать историю ветки. Такая необходимость может возникнуть по двум причинам.

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

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

Git осуществляет rebase путем создания новых коммитов и применения их к указанной основе (base). Очень важно понимать, что хотя ветка выглядит так же, как выглядела, она составлена из совершенно новых коммитов.

rebase создает совершенно новые коммиты.

Это означает, что если вы попытаетесь запушить ветку, которая локально была «перебазирована», а удаленно — нет, удаленный репозиторий распознает, что история коммитов изменилась, и не даст вам запушить ваши изменения, пока вы не устраните различия:

(my-feature)$ git push
To github.com:johnmosesman/burner-repo.git
 ! [rejected]        my-feature -> my-feature (non-fast-forward)
error: failed to push some refs to 'git@github.com:johnmosesman/burner-repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Чтобы смержить различия, можно выполнить git pull, но если вы очень хотите перезаписать удаленный репозиторий, вы можете добавить к вашему push флаг --force:

(my-feature)$ git push --force origin my-feature
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 184 bytes | 184.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To github.com:johnmosesman/burner-repo.git
 + edb64e2...52f54da my-feature -> my-feature (forced update)

Примечание: вместо --force можно использовать короткую форму -f.

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

Принудительный push с оговоркой

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

Если кто-то поработал с вашей веткой и запушил свои изменения в удаленный репозиторий, а вы после этого принудительно запушите свои, — вы перезапишете изменения, внесенные вашим коллегой.

Чтобы предотвратить такой ход событий, можно использовать опцию --force-with-lease (документация).

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

Если вы работаете над одной веткой совместно с другими людьми, лучше или вообще избегать использования --force, или хотя бы пользоваться --force-with-lease, чтобы не стереть изменения, внесенные вашими товарищами.

Как запушить изменения в ветку с другими именем

Обычно вы отправляете вашу локальную ветку в удаленную ветку с тем же именем (т. е. локальную my-feature — в удаленную my-feature), но так бывает не всегда.

Чтобы запушить локальную ветку в удаленную ветку с другим именем, вам нужно указать имена обеих веток, разделив их двоеточием.

Например, если вы хотите запушить ветку some-branch в my-feature, то команда будет выглядеть так:

(some-branch)$ git push origin some-branch:my-feature
Total 0 (delta 0), reused 0 (delta 0)
To github.com:johnmosesman/burner-repo.git
 + 728f0df...8bf04ea some-branch -> my-feature

Как запушить все локальные ветки в удаленный репозиторий

Вам не так уж часто понадобится пушить сразу все ветки из локального репозитория, но в принципе это возможно. Для этого нужно воспользоваться флагом --all:

(main)$ git branch
* main
  my-feature

(main)$ git push --all
...
To github.com:johnmosesman/burner-repo.git
   b7f661f..6e36148  main -> main
 * [new branch]      my-feature -> my-feature

Заключение

Команда git push — одна из тех, что используются наиболее часто. Она имеет много вариантов использования и соответствующих опций. Найти их можно в документации.