Случайно выполненный "Git push origin master" в то время как на ветке от master - PullRequest
0 голосов
/ 01 февраля 2019

Я создал локальную ветку Git от master (давайте назовем ее BranchB).Затем я зафиксировал свои изменения в этой ветви (в BranchB).Но когда пришло время отправить в удаленный репозиторий, ко мне пришло слишком много кофе, и я написал git push origin master вместо git push, чтобы протолкнуть новую ветвь в репозиторий.

Я тогдазашел в GitHub, чтобы увидеть коммиты на мастере.Изменения, которые я недавно случайно подтолкнул к мастеру, не появились здесь?

Так что же конкретно произошло, когда я нажал на мастеринг в то время как на ветви B? Это просто подталкивает коммиты, которые были сделаны намастер, так как я указал мастер.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Краткий ответ: ты в порядке.Git, скорее всего, сказал:

Everything up-to-date

и вообще ничего не делал.Если нет, то вы отправили только коммиты, сделанные вами на master, на ваш GitHub Git's master.

Более длинный ответ по-прежнему в том, что вы в порядке, но вы можете работать с некоторыми ошибочными представлениями оGit ветви.Они не будут кусать тебя ... пока .101

Фиксирует цепочки, обращенные назад

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

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

... <-F <-G <-H

, нам просто нужен хэш-идентификатор последнего такого коммита, например H.Затем Git сможет читать H и вылавливать хэш-идентификатор своего родителя G, читать G и вылавливать идентификатор F и т. Д.

Ветвь name подобно master, поэтому просто идентифицирует один коммит

Способ, которым Git находит хеш-идентификатор last коммита любой ветки, - через имя ветки.Само имя, master или BranchB или что-то еще, просто содержит хеш-идентификатор:

...--F--G--H   <-- master, BranchB

Здесь оба хранилища имен тот же хеш-идентификатор.Таким образом, все коммиты, которые находятся на master, также на BranchB.

Чтобы сделать новый коммит, Git сохранит снимок, сохранит ваше имя и адрес электронной почты и так далее,и сохраните хэш-идентификатор текущего commit H.Это становится новым коммитом I, которому присваивается новый уникальный хэш-идентификатор:

...--F--G--H   <-- master, BranchB
            \
             I

Одно из этих имен должно измениться сейчас!

Ваш HEAD запоминает, какую ветку вы

Чтобы узнать , какое имя обновлять , Git прикрепляет специальное имя HEAD к одной ветви.Если HEAD присоединен к BranchB, это имя, которое Git будет обновлять:

...--F--G--H   <-- master
            \
             I   <-- BranchB (HEAD)

Это действительно так просто.

Перемотка вперед

Хорошо,«это просто» не так просто: имена веток do двигаются так, и Git находит коммиты, начиная с последней и работая в обратном направлении.Вы можете в любое время попросить Git переместить любое имя ветки в любой существующий коммит.Допустим, мы заставляем Git переместиться BranchB назад, чтобы зафиксировать H.Как мы можем найти коммит I?

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

Эточто означает специальный термин Git fast forward .Обновление имени ветви - это операция перемотки вперед, если из new «последнего» коммита мы все еще можем вернуться к старому «последнему» коммиту.

Push (наконец!)

Здесь git push входит. Когда вы запускаете git push, ваш Git вызывает другой Git по некоторому URL.Ваш Git и их Git имеют разговор.Ваш Git будет передавать новые коммиты своему Git по мере необходимости, а затем ваш Git просит свой Git установить одно из их названий веток.

Помните, что их Git является хранилищем Git,как у тебя.Таким образом, их Git имеет свои имена ветвей.У них уже есть master:

...--F--G--H   <-- master

Yнаш Git вызовет их Git и спросит их: Эй, почему бы вам не настроить master на указание совершить H? Они скажут: Это уже происходит. Ваш ответит: О, хорошо, хорошо, пока! и ваш Git напечатает:

Everything up-to-date

Или вы можете отправить новый хеш-код коммита.Ваш Git предложит своему Git ваш новый коммит, столько, сколько нужно, чтобы связать этот новый обратно с H, или где бы он ни находился, ваш Git и их Git делятся каким-то более ранним коммитом.Тогда ваш Git будет таким же, как их Git: Эй, как насчет установки вашего master для этого другого хеш-идентификатора? Они могут сказать окей или они могут сказать: Нет!это не перемотка вперед! И теперь, когда вы знаете, что означает перемотка вперед, вы знаете, что если они отклонят ваш запрос, то это потому, что, если вы передадите их master имен, этого не будетобратная цепь, которую вы получаете, когда смотрите на свой master и работаете в обратном направлении.

То есть, предположим, что вас бьют ударом - кто-то другой, куда-то еще, отправляет ихновый коммит:

...--F--G--H--L   <-- master

Ваш Git сделал несколько новых коммитов (и вы на master):

             J--K   <-- master (HEAD)
            /
...--F--G--H   <-- origin/master
            \
             I   <-- BranchB

, поэтому ваш Git отправляет им J-K цепочка и просит их установить master на K, но это потеряло бы их L - чего у вас даже нет.Вам нужно будет получить их L и выяснить, как сохранить их L.

Пока они не имеют коммитов, которые ваш git push запрос будет отброшен, однако, он примет ваш запрос.Поэтому, если у них нет есть L, и вы запускаете git push origin master, вы отправите свой J-K и попросите их установить для своего мастера значение K, и они будут.

Это верно, даже если вы повторно подключили HEAD к вашему BranchB:

             J--K   <-- master
            /
...--F--G--H   <-- origin/master
            \
             I   <-- BranchB (HEAD)

A git push origin master попросил вашего Git вызвать Git, предложите им свой коммит K, и попросите их переместить их master туда, где находится ваш master.

A git push origin BranchB попросил вашего Git вызвать их Git, предложить им ваш коммит I и попросить ихпереместить (или создать) их BranchB туда.

Обратите внимание, что вы также можете git push origin master BranchB предложить им обе подсказки (K и I на рисунке выше), и сделать оба запроса,Или, как заметил RomainValeri , вы можете установить полный аргумент refspec для каждого слова после слова origin, например, git push BranchB:master или git push master:BranchB.Они заставляют ваш Git отправлять свои коммиты, как и прежде, и затем запрашивают, чтобы они установили имя своей целевой ветки (имя после двоеточия) в соответствии с коммитом tip вашей исходной ветви (от имени до двоеточия).Как правило, смешивать такие имена не очень хорошая идея - это слишком запутанно, если не сказать больше.Но в некоторых особых случаях это полезный ярлык.

0 голосов
/ 01 февраля 2019

Значение <refspec>, которое вы указали здесь в качестве параметра для вашего push-сообщения, равно master, где полная каноническая форма была бы <src>:<dst>, <src> - источник толчка, а <dst> - пункт назначения.Когда вы опускаете один, git предполагает, что это <src> и что <dst> не было дано.В этом случае, и если ветвь имеет конфигурационный набор <repository>.push (так в большинстве случаев), этот ref используется в качестве источника для вашего push.

Так что да, это подтолкнуло мастера (без новых коммитов) к своему удаленному коллеге.Безобидный безоперационный.

(Возможно, проверьте свою собственную конфигурацию с помощью git config -l | grep origin или что-то в этом духе.)

Вы бы выдвинули BranchB на masterс явным:

git push origin BranchB:master

Это то, что я понимаю из документа, а именно параграф <refspec> на странице руководства git-push.Кажется, имеет смысл с вашими результатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...