Обновления были отклонены, потому что кончик вашей текущей ветки позади - но почему? - PullRequest
0 голосов
/ 13 февраля 2020

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

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

   git clone git@github.com:joyofdata/test3.git
   cd test3
   echo "1" > m
   git add .
   git commit -m "m1"
   git push origin master

   git checkout -b feature
   git push -u origin feature
   echo "1" > f
   git add .
   git commit -m "f1"
   git rebase master
   git push origin feature

   git checkout master
   echo "2" >> m
   git add .
   git commit -m "m2"
   git push origin master

   git checkout feature
   echo "2" >> f
   git add .
   git commit -m "f2"
   git rebase master
   git push origin feature (error - see next code box)

Я просто создаю версию файла m в master, а затем файл f в функции , затем я фиксирую изменение в мастере, затем я фиксирую изменение в функции. Теперь, перед тем как отправить изменения в удаленную ветвь функций, я хочу перебазировать их на master.

Это команда и сообщение об ошибке последней команды в приведенном выше списке:

➜  test3 git:(feature) git push origin feature
To github.com:joyofdata/test3.git
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'git@github.com:joyofdata/test3.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.

Now - Я пытаюсь решить проблему, сначала вытягивая из удаленной функции (как предложено в сообщении), затем я разрешаю конфликт, pu sh для функции:

➜  test3 git:(feature) git pull origin feature
From github.com:joyofdata/test3
 * branch            feature    -> FETCH_HEAD
Auto-merging f
CONFLICT (add/add): Merge conflict in f
Automatic merge failed; fix conflicts and then commit the result.

➜  test3 git:(feature) ✗ vim f
➜  test3 git:(feature) ✗ git add .
➜  test3 git:(feature) git commit -m "deconflicted"
[feature 3fb647e] deconflicted

➜  test3 git:(feature) git push origin 
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 565 bytes | 565.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To github.com:joyofdata/test3.git
   0f31f60..3fb647e  feature -> feature

Но - отныне - I ' Я собираюсь снова и снова запускать эту ошибку каждый раз, когда перебрасываю функцию на master - снова конфликт слияния и снова эту ошибку.

➜  test3 git:(feature) git rebase master
First, rewinding head to replay your work on top of it...
Applying: f1
Applying: f1
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
No changes -- Patch already applied.
Applying: f2

➜  test3 git:(feature) git push origin  
To github.com:joyofdata/test3.git
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'git@github.com:joyofdata/test3.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 мастер перебазирования
  • git pu sh исходная функция

I простые термины - перед нажатием коммита на удаленную функцию я хочу перебазировать функцию на мастер. Если я объединю мастер с функцией (git pull origin master или git merge master, если локальный мастер обновлен), я не столкнусь с этой проблемой.

Надеюсь, это не слишком запутанно, но я не не знаю, как это проще сказать, и это меня очень раздражает.

Ответы [ 2 ]

3 голосов
/ 13 февраля 2020

Проблема root в том, что вы перебираете свой feature. Это неаккуратный способ выразить это: важно не имя ветви , а значение commits . Но rebase работает путем копирования некоторых коммитов в новые и (предположительно) улучшенные коммиты. Это требует выбрасывания - или отказа - старые (и теперь паршивые) коммиты.

Команда git push вызывает другой Git и отправляет им ваш новый и улучшенный feature фиксирует, затем просит, чтобы другие Git хранилища выбросили свои старые (и теперь паршивые) коммиты. Там написано: Нет! Если я прошу вас спросить, я потеряю некоторые ценные коммиты! Эта жалоба возвращается в следующей форме:

 ! [rejected]        feature -> feature (non-fast-forward)

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

Конечно, это именно то, что вы хотите сделать. Примечание: если вы должны сделать это, зависит от того, согласились ли все остальные, кто использует этот другой Git репозиторий - тот, что на GitHub - заранее.

Чтобы другой Git, один на GitHub, согласился отклонять коммиты из своего репозитория, вы должны установить «флаг принудительного применения» для этой конкретной операции git push. Однако есть два различных типа флага силы:

  • Общая сила: Я приказываю вам, другой Git репозиторий, чтобы установить имя вашей ветви таким образом! Это просто и эффективно, и отбрасывает не только старые и паршивые коммиты, которые вы заменили новыми и улучшенными коммитами через rebase, но также каждый другой коммит, который кто-либо еще добавил , который вы не также заменить на новую и улучшенную копию. (Это одна из нескольких причин того, что каждый, кто использует этот репозиторий GitHub, должен заранее согласиться с тем, что произойдет перебазировка.)

  • Force-with-lease: Я приказываю вам, в другом хранилище Git, сравнить идентификатор ha sh, хранящийся в названии вашей ветви, со значением, которое я считаю у вас. Если они равны, вам следует заменить это значение новым значением, которое я сейчас предоставляю. Этот вариант force-pu sh безопаснее: если вы отменили некоторые коммиты, но с тех пор кто-то еще добавил new подтверждает, что вы не смогли выполнить перебазирование, ваша операция принудительного лизинга завершится неудачно. Другой Git в GitHub скажет: Идентификатор ha sh, который я сохранил, не совпадает с тем, который, как вы сказали, вы думали, я имел. Поэтому я все-таки не принял вашу команду.

Если вы и все другие пользователи этого репозитория GitHub заранее договорились, что может произойти перебазировка, и вы думаете, что кто-то может Пропустив несколько коммитов, пока вы не искали, вы должны использовать опцию --force-with-lease для git push, чтобы выяснить, так ли это на самом деле.

Если других пользователей репозитория GitHub нет ( или ни один из них не использует ветку feature), ничего из этого не требуется, и вы можете просто использовать git push --force. Единственный человек, с которым вам нужно согласиться, это вы сами: вы даете себе разрешение на форс-пу sh feature филиал? Если это так, вы можете принудительно-pu sh ветвь feature.

Обратите внимание, что если являются другими пользователями, и вы, и они все согласны с этой силой pu sh В процессе перебазирования вы и они должны все позаботиться о том, чтобы следить за принудительными обновлениями и выполнять собственный перебазирование всех коммитов, которые не были скопированы в новые и улучшенные коммиты. Это довольно сложный рабочий процесс; будьте уверены, что вы и все ваши друзья / коллеги готовы к этому.

3 голосов
/ 13 февраля 2020

Быстрый ответ: не перебазируйте ветки вверх по течению, эта ссылка объясняет проблему и решение: https://git-scm.com/docs/git-rebase#_recovering_from_upstream_rebase

Элементарный вариант может быть таким: Начиная с вашего примера, перед строкой ошибки ответвления выглядят так:

$ git log --pretty=oneline --graph --all
* b5b045591ec6584e8f896d85399b7ed5b08d8098 (HEAD -> feature) f2
* 5187c95d6d91b550b9b2cc10ad673a52add620f6 f1
* cea62f3fd0349390115ee5e263730656b7a52d2d (origin/master, master) m2
| * f043b50940593c1ded4631f3681420ad57c0b190 (origin/feature) f1
|/
* 4847339d95d8f02c25538da7e51be14cbb30530d m1

при выполнении

$ git push origin feature

Вы пытаетесь включить изменения от элемента ветвления к источнику / элементу, который невозможен, потому что они имеют разные коммиты .

Таким образом, вы можете удалить источник / функцию удаленной ветви

  1. Unset upstream

    $ git checkout feature
    $ git branch --unset-upstream
    
  2. Удалить удаленную ветку

    $ git push origin --delete feature
    
  3. Pu sh ваши изменения добавляются вверх по течению

    $ git push -u origin feature
    

Ветвь заканчивается следующим образом

$ git log --pretty=oneline --graph --all
* b5b045591ec6584e8f896d85399b7ed5b08d8098 (HEAD -> feature) f2
* 5187c95d6d91b550b9b2cc10ad673a52add620f6 f1
* cea62f3fd0349390115ee5e263730656b7a52d2d (origin/master, master) m2
* 4847339d95d8f02c25538da7e51be14cbb30530d m1

Согласно этому примеру, коммит b5b045 имеет изменения коммита f043b50, поэтому изменения не теряются, вы можете проверить с помощью

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