Git rebase: конфликты продолжают блокировать прогресс

120

У меня есть ветка git (называемая v4), которая была создана мастером только вчера. В master внесено несколько изменений, которые я хочу внести в v4. Итак, в v4 я попытался выполнить перебазирование с master, и один файл продолжает лажать: однострочный текстовый файл, содержащий номер версии. Это файл app/views/common/version.txt, который перед перебазированием содержит такой текст:

v1.4-alpha-02

Вот что я делаю:

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: new version, new branch
error: patch failed: app/views/common/version.txt:1
error: app/views/common/version.txt: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/views/common/version.txt
CONFLICT (content): Merge conflict in app/views/common/version.txt
Failed to merge in the changes.
Patch failed at 0001 new version, new branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

version.txtТеперь выглядит следующим образом :

<<<<<<< HEAD:app/views/common/version.txt
v1.4-alpha-02
=======
v1.4-alpha-01
>>>>>>> new version, new branch:app/views/common/version.txt

Итак, я привел его в порядок, и теперь он выглядит так:

v1.4-alpha-02

а затем я попытался продолжить: сначала я пытаюсь зафиксировать:

> git commit -a -m "merged"
# Not currently on any branch.
nothing to commit (working directory clean)

Не повезло. Итак, я пытался добавить файл:

git add app/views/common/version.txt

Нет ответа. Думаю, отсутствие новостей - это хорошие новости. Итак, я пытаюсь продолжить:

> git rebase --continue
Applying: new version, new branch
No changes - did you forget to use 'git add'?

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Именно в этот момент, после того, как я обдумываю это, я бьюсь головой о стол.

Что тут происходит? Что я делаю не так? Кто-нибудь может меня поправить?

РЕДАКТИРОВАТЬ - для unutbu

Я изменил файл, как вы предлагали, и получил ту же ошибку:

> git rebase master
First, rewinding head to replay your work on top of it...
Applying: new version, new branch
error: patch failed: app/views/common/version.txt:1
error: app/views/common/version.txt: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging app/views/common/version.txt
CONFLICT (content): Merge conflict in app/views/common/version.txt
Failed to merge in the changes.
Patch failed at 0001 new version, new branch

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
Макс Уильямс
источник
10
спасибо за вопрос .. я столкнулся с той же проблемой
Арчан Мишра
6
было бы хорошо, если бы вы подтвердили какой-нибудь ответ
Holms
3
@MaxWilliams, я думаю, что вы (как и я) неверно истолковали совет @unutbu : 1) сначала бегите, git rebase master а потом дайте ему потерпеть неудачу ; 2) затем вы редактируете version.txtи делаете так, как должно выглядеть в этой точке, и сохраняете правку; 3) тогда ты git add .../version.txt; 4) тогда вы делаете git rebase --continueне «совершаете» )! В случае rebase --continueуспеха здесь он уже зафиксирован (здесь нет необходимости git commit!), Поэтому все, что остается сделать, это git push(если вы используете удаленное репо). Надеюсь, это поможет, если я правильно понял :)- ура!
sdaau
@MaxWilliams, вы когда-нибудь получали ответ на это: ruby-forum.com/topic/187288 (я немедленно удалю это после ответа, если кто-то еще не доберется до него первым !!)
atw

Ответы:

102

Я столкнулся с аналогичной проблемой с ребазом. Моя проблема была вызвана тем, что одна из моих фиксаций изменила только файл, и при разрешении я отклонил изменение, внесенное в эту фиксацию. Я смог решить свою проблему, пропустив соответствующий commit ( git rebase --skip).

Вы можете воспроизвести эту проблему в тестовом репозитории. Сначала создайте репозиторий.

$ mkdir failing-merge
$ cd failing-merge
$ git init
Initialized empty Git repository in $HOME/failing-merge/.git/

Затем зафиксируйте исходное содержимое version.txtв master.

$ echo v1.4-alpha-02 > version.txt
$ git add version.txt
$ git commit -m initial
[master (root-commit) 2eef0a5] initial
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 version.txt

Создайте v4ветку и измените содержимое version.txt.

$ git checkout -b v4
Switched to a new branch 'v4'
$ echo v1.4-alpha-03 > version.txt
$ git add version.txt
$ git commit -m v4
[v4 1ef8c9b] v4
 1 files changed, 1 insertions(+), 1 deletions(-)

Вернитесь masterи измените содержимое version.txtтак, чтобы во время перебазирования было конфликт.

$ git checkout master
Switched to branch 'master'
$ echo v1.4-alpha-04 > version.txt
$ git add version.txt
$ git commit -m master
[master 7313eb3] master
 1 files changed, 1 insertions(+), 1 deletions(-)

Вернитесь в v4ветку и попробуйте перебазировать. Как version.txtи планировалось, это не удается .

$ git checkout v4
Switched to branch 'v4'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: v4
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging version.txt
CONFLICT (content): Merge conflict in version.txt
Recorded preimage for 'version.txt'
Failed to merge in the changes.
Patch failed at 0001 v4

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".
$ cat version.txt
<<<<<<< HEAD
v1.4-alpha-04
=======
v1.4-alpha-03
>>>>>>> v4

Мы разрешаем конфликт, выбирая masterсодержание version.txt. Добавляем файл и пытаемся продолжить ребаз.

$ echo v1.4-alpha-04 > version.txt
$ git add version.txt
$ git rebase --continue 
Applying: v4
No changes - did you forget to use 'git add'?
If there is nothing left to stage, chances are that something else
already introduced the same changes; you might want to skip this patch.

When you have resolved this problem run "git rebase --continue".
If you would prefer to skip this patch, instead run "git rebase --skip".
To restore the original branch and stop rebasing run "git rebase --abort".

Это не удается! Посмотрим, какие изменения gitесть в нашем репозитории.

$ git status
# Not currently on any branch.
nothing to commit (working directory clean)

Ах ах, нет никаких изменений. Если вы подробно прочитали предыдущее сообщение об ошибке, gitсообщили нам об этом и рекомендовали к использованию git rebase --skip. Он сказал нам: «Если ничего не осталось для обработки, скорее всего, что-то другое уже внесло такие же изменения; вы можете пропустить этот патч». Таким образом, мы просто пропускаем фиксацию, и перебазирование завершается успешно.

$ git rebase --skip
HEAD is now at 7313eb3 master

Предупреждение : обратите внимание, что git rebase --skipэто полностью отбросит фиксацию, которая gitпыталась перебазировать. В нашем случае это должно быть нормально, поскольку gitон жалуется, что это пустой коммит. Если вы считаете, что потеряли изменения после завершения перебазирования, вы можете использовать его git reflogдля получения идентификатора фиксации вашего репозитория перед перебазированием и использовать его, git reset --hardчтобы вернуть свое хранилище в это состояние (это еще одна деструктивная операция).

Сильвен Дефресн
источник
4
Спасибо, что нашли время написать это длинное объяснение, Сильвен! Это проясняет ситуацию. Думаю, я всегда просто нервничал из-за пропуска патча, потому что мне казалось, что работа может быть потеряна: то есть патч включал все файлы, затронутые перебазированием, а не только файл с конфликтом. Значит, патч - это просто слияние одного файла?
Макс Уильямс
3
Нет, патч содержит всю разницу для всех файлов, измененных за один коммит. Но при использовании git rebase --skipвы пропускаете только одну фиксацию. Я обычно выдаю git statusперед тем, как пропустить фиксацию, чтобы узнать, нахожусь ли я в этой ситуации.
Сильвен Дефресн 01
1
Я просто хотел повторить, как Макс поблагодарил за то, что нашел время написать отличное объяснение - я наконец понимаю, почему это происходит. Я тоже больше не боюсь rebase --skip:).
Бен Долман
1
Предупреждение - если у вас есть несколько изменений в одном коммите, вы можете потерять работу, выполнив git rebase --skip. Я только что сделал
Крисси Х
@ChrissyH Если вы не сделали git reflog purgeили git reflog deleteвы все еще можете вернуть свои изменения, используя git reflog. Попробуйте проверить различные коммиты, на которые есть ссылки, один из них должен быть состоянием вашего дерева до того, как вы начали все git rebase.
Сильвен Дефресн 07
23

Цитата отсюда: http://wholemeal.co.nz/node/9

А?!? Нет, я не забыл использовать git add, я сделал это ... вроде ... 2 секунды назад!

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

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

$ git rebase --skip
Бижу Трувай
источник
После того, как я использовал git mergetool и исправил изменения, затем добавил их и зафиксировал, я просто ввел <code> git rebase --skip </code>, а «Сейчас нет ни в одной ветке». И все было исправлено. Спасибо!
geerlingguy
На самом деле, я думаю, что это была комбинация непрерывного запуска git mergetool, затем git rebase --continue, затем git mergetool и т.д., что окончательно исправило мою ситуацию.
geerlingguy
6

Это сообщение об ошибке является результатом вашего git commit -a -m "merged". Если вы просто исправить файл, а затем запустить git add <file>, и git rebase --continueон должен работать нормально. git rebase --continueпытается выполнить фиксацию, но обнаруживает, что нет ожидающих изменений для фиксации (потому что вы их уже зафиксировали).

twalberg
источник
1
Это кажется более разумным, чем пропуск, по крайней мере, в общем случае. Я удивлен, что он не указан как лучший ответ.
EmeraldD.
1
@EmeraldD., Не работает. Исправление файла и запуск git add <file>не решат проблему. git rebase --continue все еще сообщаетNo changes - did you forget to use 'git add'?
Pacerier
6

Измените app / views / common / version.txt на

v1.4-alpha-01

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

Итак, при ребейзинге из

      A---B---C topic
     /
D---E---F---G master

в

              A*--B*--C* topic
             /
D---E---F---G master

конфликт, который вы разрешаете, заключается в том, как создать A * в ветке темы.

Итак, после этого git rebase --abortкоманды должны быть

git checkout topic
git rebase master
< make edits to resolve conflicts >
git add .
git rebase --continue
unutbu
источник
3
Спасибо, unutbu, я попробовал, но не повезло: см. OP для нового редактирования. ура
Макс Уильямс
4

Поведение, которое вы видите, - это не то, что я ожидал бы от типичного перебазирования только с этим конфликтом. Рассмотрите возможность использования отдельной ветки для выполнения этой перестановки (особенно, если вы уже отправили коммиты удаленно, чтобы выполнить быструю пересылку). Кроме того, это git mergetoolможет быть полезно для разрешения конфликтов и не забывать о выпуске файла git add.

В этом минимальном примере перебазирование работает должным образом. Можете ли вы привести пример, демонстрирующий наблюдаемое вами поведение?

#!/bin/bash

cd /tmp
mkdir rebasetest
cd rebasetest
git init
echo 'v1.0' > version.txt
git add version.txt
git commit -m 'initial commit'
git checkout -b v4
echo 'v1.4-alpha-01' > version.txt
git add version.txt
git commit -m 'created v4'
git checkout master
git merge v4
echo 'v1.4-alpha-01-rc1' > version.txt
git add version.txt
git commit -m 'upped version on master to v1.4-alpha-01-rc1'
git checkout v4
echo 'v1.4-alpha-02' > version.txt
git add version.txt
git commit -m 'starting work on alpha-02'

git rebase master
echo 'v1.4-alpha-02' > version.txt
git add version.txt
git rebase --continue
Бен Тайтельбаум
источник
4

Вот несколько идей:

Адам Монсен
источник