Git: ветки расходятся; как действовать?
Мое локальное дерево отклонилось от мастера:
$ git status
# On branch master
# Your branch and 'origin/master' have diverged,
# and have 7 and 3 different commit(s) each, respectively.
#
nothing to commit (working directory clean)
Я попробовал git pull --rebase и не удалось:
$ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: * ...
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging ChangeLog
CONFLICT (content): Merge conflict in ChangeLog
Failed to merge in the changes.
Patch failed at 0001 * ...
Итак, я вернулся с git rebase --abort, и теперь я на квадрате 1.
Я хочу:
- "Экспортировать" мои 7 патчей в файлы для чтения, доступные для чтения (a la hg export).
- Сделайте свое дерево копией источника/мастера (a la hg strip).
- повторно примените мои 7 патчей один за другим вручную (a la hg import).
Я понимаю, что git rebase -continue делает это.
Я сделал это, и это сработало (после нескольких ручных слияний и git добавить).
Тем не менее, я хочу, чтобы иметь возможность сделать это вручную,
поэтому мне интересно, какие команды git соответствуют командам hg выше.
Спасибо.
PS. Пожалуйста, не говорите мне, что использование файла ChangeLog с git глупо.
Даже если это так, это не зависит от меня.
Ответы
Ответ 1
Есть, конечно, несколько способов сделать это вручную. У вас все еще будут те же конфликты, потому что git в основном делает это для вас под капотом. Но если вы хотите сделать это вручную, вот несколько способов.
Во-первых, экспортируйте свои фиксации в виде серии патчей. Самый простой способ сделать это - использовать git format-patch
:
git format-patch -M @{upstream}
создаст 7 патч файлов - по одному для каждого из ваших коммитов. (Обратите внимание, что "@{upstream}" является литералом - это не очень хорошо известная функция git.) Это лучше, чем захват вывода git diff
, потому что вся информация о фиксации (автор, дата, и т.д.) сохраняются.
Тогда вы могли бы reset ваш репозиторий соответствовать восходящему потоку:
git reset --hard @{upstream}
Затем вы можете повторно применить свои исправления с помощью git am
- по одному за раз или сразу.
git am 0001-blah-blah.patch
git am 0002-blah-blah.patch
...
Второй вариант - создать резервную ветку с вашей работой над ней:
git branch scrap
Затем reset ваша ветка вверх по течению:
git reset --hard @{upstream}
Затем вишневый захват совершает над:
git cherry-pick scrap~6
git cherry-pick scrap~5
git cherry-pick scrap~4
...
Затем уничтожьте ветку лома:
git branch -D scrap
Ответ 2
Вы пробовали git merge origin/master
?
Ваши удаленные изменения сохраняются в ветке origin/master
. (Или это произойдет, если вы выполните git fetch
.) Просто объедините две ветки - master
и origin/master
- как и любые две ветки и разрешите конфликты (если они есть).
Это может помочь вам, если вам нужно знать, как разрешать конфликты git.
Как разрешить конфликты слияния в Git?
Ответ 3
Git говорит, что он пытался сделать именно то, что вы хотите (повторно примените свои исправления поверх новейших изменений от origin/master), но не удалось с конфликтом. Сразу после git pull --rebase
конфликты открывают редактор с конфликтующими файлами (git status
будет перечислять их в разделе "оба изменены" ) и разрешать конфликты, отмеченные в стандарте diff lingua. Когда вы закончите разрешать конфликт, введите git rebase --continue
(или git rebase --skip
, если ваше разрешение не вносит никаких изменений).
Прочитайте о нем в Документация Stackexchange для "Разрешение конфликтов слияния после Git rebase" .
Ответ 4
Вот несколько хороших ответов на ту же проблему (только без разрешения конфликта):
ветвь master и 'origin/master' расходятся, как "разделить ветки" ?
Во-первых, вы можете просмотреть, что было изменено на удаленном сервере по сравнению с вашей локальной версией:
git log HEAD..origin/master
Чтобы исправить вашу фактическую проблему, она сводится к той же строке, которую предложили:
git pull --rebase
Как вы сказали, у вас появятся конфликты.
Разрешение конфликтов - это повторяющаяся проблема. Если вы еще этого не сделали, вы можете взглянуть на git mergetool
(подробнее см. git help mergetool
). Чтобы получить графическую поддержку, я бы рекомендовал перезаписать конфигурацию merge.tool
. Например, если вы хотите использовать meld
для трехсторонних слияний, вы можете использовать:
git config --global merge.tool meld
Итак, после того, как вы разрешили конфликт, что сделал git pull --rebase
? Он объединил все изменения от источника/мастера в локальный мастер и повторил ваши изменения поверх него. Поздравляем, вы вернулись к нормальной жизни.