2016-06-10 3 views
0

У меня просто был интересный опыт игры. Я работал единственным разработчиком в своем филиале my-branch, который я недавно разветвил из филиала моего товарища по команде: her-branch. Я уже успешно нажал несколько коммитов в свой филиал. Но когда я пошел, чтобы толкать мою последнюю ветку, то произошло следующее:Git Time Travel

$ git push 
To [email protected]/repo.git 
! [rejected]  her-branch -> her-branch (non-fast-forward) 
error: failed to push some refs to '[email protected]/repo.git' 
hint: Updates were rejecetd because a pushed branch tip is behind its remote 
hint: counterpart. Check out this branch and integrate the remote changes. 
hint: (e.g. 'git pull ...') before pushing again. 
hint: See the 'Note about fast-forwards' in 'git push --help' for details. 

Я думал, что это было очень странно, что даже если я толкал на my-branch сообщения сказали, что это не удалось из-за her-branch. Я не знал, что был неправ, но я вытащил, как предложил сообщение:

$ git pull 
Already up-to-date. 

Я хотел бы подтвердить, я был на моей ветке ...

$ git checkout my-branch 
Already on 'my-branch' 
Your branch is up-to-date with 'origin/my-branch'. 

Так наконец, я заставил толчок.

$ git push -f 
Total 0 (delta 0), reused 0 (delta 0) 
To [email protected]/repo.git 
+ 9b3232c..d35fe86 her-branch -> her-branch (forced update) 

my-branch Это подтолкнуло успешно и обновила пульт. Но он отправил her-branch вовремя, со всеми моими товарищами по команде, так как я удалился от нее. Ее история полностью исчезла с дистанции.

К счастью, она не тянула и смогла надавить на свою ветку, чтобы восстановить последнюю версию своего кода, но я довольно смущен.

Не могли бы вы объяснить, что здесь произошло?

+0

tldr: 'git push' не толкает вашу ветку, она толкает ** все ** ваших ветвей. Вы не должны этого делать, вы перезаписали новую версию своей ветви своей устаревшей местной версией. Убедитесь, что 'push.default' установлен правильно. – meagar

ответ

5

Похоже, что ваш git config push.default установлен в matching. Это обычно было поведением по умолчанию, но, как вы столкнулись, вероятно, не то, что вы хотите для большинства рабочих процессов git. Вы можете проверить текущие настройки, запустив git config --get push.default

См https://git-scm.com/docs/git-config

push.default

Определяет действие мерзавец толчок должен предпринять, если не refspec не явно задан. Различные значения хорошо подходят для конкретных рабочих процессов ; например, в чисто центральном рабочем процессе (то есть источник выборки равен целевому назначению), вверх по потоку, вероятно, то, что вы хотите . Возможные значения:

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

текущий - нажмите текущую ветку, чтобы обновить ветку с тем же именем на принимающей стороне. Работает как в центральных, так и в нецентральных рабочих процессах .

перед - нажать текущую ветку обратно к ветви которого изменяется , как правило, интегрированы в текущей ветви (который называется @ {вверх}). Этот режим имеет смысл только в том случае, если вы нажимаете на тот же репозиторий, который вы обычно извлекаете (т. Е. Центральный рабочий процесс).

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

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

Этот режим стал по умолчанию в Git 2.0.

Соответствие - нажмите все ветви с тем же именем на обоих концах. Этот делает хранилище, на которое вы нажимаете, чтобы помнить набор ветвей , который будет вытолкнут (например, если вы всегда нажимаете maint и master там и никакие другие ветви, в хранилище, на которое вы нажимаете, будут этих двух ветвей, а ваши местный maint и master будут нажаты там).

Чтобы эффективно использовать этот режим, вы должны убедиться, что все ветви вы бы выталкивают готовы быть вытеснены перед запуском GIT толчок, как весь смысл этого режима позволит вам нажать все ветвей за один раз. Если вы обычно завершаете работу только с одной веткой и выталкиваете результат, а остальные ветви не завершены, этот режим не для вас. Также этот режим не подходит для перехода в общий центральный репозиторий , так как другие люди могут добавлять туда новые ветки, или обновлять кончик существующих ветвей вне вашего контроля.

Это было по умолчанию, но не с Git 2.0 (просто новый по умолчанию).

+0

Спасибо за информацию.Это полезно, но знаете ли вы, что случилось, чтобы вызвать путешествие во времени на отделение моего коллеги? –

+0

@NateGardner Когда вы запускаете 'git push -f', вы заставляете вашу« мою ветвь »и вашу копию« своей ветви »переписывать удаленную версию« своей ветви »с вашей локальной копией. Ваша локальная копия 'her-branch' не обновлялась, так как вы разветвляли« мою ветвь », а« git pull »только извлекали и объединяли текущую ветку (' my-branch'). – Jonah

0

git pull - всего лишь предложение, которое не может решить проблему в вашем случае, потому что her_branch не находится вверх по течению от my_branch. Он просто обновляет my_branch своим собственным потоком вверх. Вместо этого вы должны запустить git pull --rebase <remote> her_branch. <remote> может быть origin или надлежащим удаленным, что относится к URL-адресу удаленного репо, к которому принадлежит its_branch.

Кроме того, опция -f в git push - это то, что вы всегда должны избегать при нажатии на опубликованную ветку в удаленном репо.

Еще одно предложение всегда использовать полную команду, как git push origin HEAD:her_branch вместо git push, git pull origin her_branch вместо git pull, если вы не знаете точно, что произойдет после того, как git push или git pull.