Конфликты в Git
| Разрешение с помощью rebase | |
| Разрешение конфликтов в GitHub | |
| Другие статьи про Git |
Разрешение конфликтов с помощью rebase
Пример безконфликтного слияния ветки с main вы можете изучить в статье
git merge
В этой статье мы будем рассматривать ситуацию, в которой коммиты непосредственно в main запрещены или нежелательны.
Рассмотрим слияние с main двух веток, редактирующих один и тот же файл и не вступающих в конфликт
git config --global user.email "email@devhops.ru" git config --global user.name "AndreiOlegovich" git clone git@github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git cd jenkins_robot_mkdocs_demo_project/ git status
On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
Изначально документ выглядел следующим образом
vi README.md
# jenkins_robot_mkdocs_demo_project Need to generate ssh keys for jenkins and mkdocs
Создадим нову ветку andrei/add_header и переключимся в неё
git checkout -b andrei/add_header
Switched to a new branch 'andrei/add_header'
Добавим строку ## SSH Keys
vi README.md
# jenkins_robot_mkdocs_demo_project ## SSH Keys Need to generate ssh keys for jenkins and mkdocs
Изучим как видны изменения
git status
On branch andrei/add_header Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
git diff README.md
diff --git a/README.md b/README.md index 635bab3..767d68a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # jenkins_robot_mkdocs_demo_project +## SSH Keys Need to generate ssh keys for jenkins and mkdocs
Закоммитим изменения
git add README.md
git status
On branch andrei/add_header Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: README.md
git commit -m "[MKDOCS-123456] - Adds SSH Keys header"
[andrei/add_header b34e9c1] [MKDOCS-123456] - Adds SSH Keys header 1 file changed, 1 insertion(+)
git status
On branch andrei/add_header nothing to commit, working tree clean
git log --oneline --graph
* 2a095cf (HEAD -> andrei/add_header) [MKDOCS-123456] - Adds SSH Keys header * 0194dcb (origin/main, origin/HEAD, main) Restores README.md for new demo
Видим, что HEAD указывает на наш последний коммит.
Вернёмся в ветку main и убедимся, что файл README.md не изменился.
git checkout main
vi README.md
# jenkins_robot_mkdocs_demo_project Need to generate ssh keys for jenkins and mkdocs …
git status
On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
git log --oneline --graph
* 0194dcb (HEAD -> main, origin/main, origin/HEAD) Restores README.md for new demo
Видим, что HEAD указывает, на последний коммит в main и о нашем предыдущем коммите в andrei/add_header информации здесь нет.
Создадим новую ветку andrei/capitalize_names и перейдём туда.
git checkout -b andrei/capitalize_names
Switched to a new branch 'andrei/capitalize_names'
git status
On branch andrei/capitalize_names nothing to commit, working tree clean
Убедимся, что файл README.md такой же как в main
vi README.md
# jenkins_robot_mkdocs_demo_project Need to generate ssh keys for jenkins and mkdocs …
Внесём изменения в строку Need to generate…
vi README.md
# jenkins_robot_mkdocs_demo_project Need to generate ssh keys for Jenkins and MkDocs
Изучим как видны эти изменения.
git status
On branch andrei/capitalize_names Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
git diff README.md
diff --git a/README.md b/README.md index 635bab3..a61df87 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # jenkins_robot_mkdocs_demo_project -Need to generate ssh keys for jenkins and mkdocs +Need to generate ssh keys for Jenkins and MkDocs Keys should be stored in ./keys/jenkins and ./keys/mkdocs directories
Закоммитим изменения.
git add README.md
git status
On branch andrei/capitalize_names Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: README.md
git commit -m "[MKDOCS-12346] - Capitalizes some names"
[andrei/capitalize_names 53330e6] [MKDOCS-12346] - Capitalizes some names 1 file changed, 1 insertion(+), 1 deletion(-)
git status
On branch andrei/capitalize_names nothing to commit, working tree clean
git log --oneline --graph
* e5e0d1a (HEAD -> andrei/capitalize_names) [MKDOCS-12346] - Capitalizes some names * 0194dcb (origin/main, origin/HEAD, main) Restores README.md for new demo
Видим, что здесь HEAD указывает на последний коммит в этой ветке
Визуально это можно представить как два независимых ответвления от последнего коммита в main
Визуализация коммитов
Запушим коммит на GitHub.
git push origin andrei/capitalize_names
Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 24 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 349 bytes | 349.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 2 local objects. remote: remote: Create a pull request for 'andrei/capitalize_names' on GitHub by visiting: remote: https://github.com/AndreiOlegovich/jenkins_robot_mkdocs_demo_project/pull/new/andrei/capitalize_names remote: To github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git * [new branch] andrei/capitalize_names -> andrei/capitalize_names
Теперь нужно перейти по ссылке, скорее всего зажав CTRL и сделав клик мышью.
URL составляется по следующему принципу:
https://github.com/username/project/pull/new/branch_name
Нажмите Create Pull Request
https://devhops.ru
Нажмите Merge Pull Request
https://devhops.ru
Нажмите Confirm Merge
https://devhops.ru
Ветка сольётся с main
https://devhops.ru
Вернувшись в main локальном репозитории мы можем убедиться, что пока что об измениях на GitHub ничего не известно.
Чтобы подтянуть эти данные можно сделать git fetch, но мы пока оставим всё как есть.
git checkout main
git status
On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
Перейдём в ветку andrei/add_header. Так как мы уже закоммитили измнения в этой ветке никаких новых изменений там не должно быть видно.
git checkout andrei/add_header
Switched to branch 'andrei/add_header'
git status
On branch andrei/add_header nothing to commit, working tree clean
Запушим коммит на GitHub
git push origin andrei/add_header
Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 24 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 342 bytes | 342.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 2 local objects. remote: remote: Create a pull request for 'andrei/add_header' on GitHub by visiting: remote: https://github.com/AndreiOlegovich/jenkins_robot_mkdocs_demo_project/pull/new/andrei/add_heade remote: To github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git * [new branch] andrei/add_header -> andrei/add_header
Если PR не видно сразу, можно нажать на Pull requests либо перейти на URL https://github.com/name/project/pulls
В данном случае это
https://github.com/AndreiOlegovich/jenkins_robot_mkdocs_demo_project/pulls
Нажмите Compare & pull request
https://devhops.ru
Нажмите Create Pull Request
https://devhops.ru
Нажмите Resolve conflicts чтобы изучить конфликт
https://devhops.ru
Видно, что в main на GitHub уже есть заглавные J, M и D, о которых andrei/add_header ничего не знает.
И просто так добавить ## SSH Keys уже не получается.
https://devhops.ru
Вернёмся в главную ветку
git checkout main
Switched to branch 'main' Your branch is up to date with 'origin/main'.
Пока изменения не подтянуты с Гитхаба файл выглядит по-старому
vi README.md
# jenkins_robot_mkdocs_demo_project Need to generate ssh keys for jenkins and mkdocs
В нём нет изменений ни из одной ветки.
Подтянем изменения
git pull
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts. remote: Enumerating objects: 1, done. remote: Counting objects: 100% (1/1), done. remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Unpacking objects: 100% (1/1), 929 bytes | 929.00 KiB/s, done. From github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project 3339d7a..f20b986 main -> origin/main Updating 3339d7a..f20b986 Fast-forward README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Изменения из ветки andrei/capitalize_names теперь в main.
vi README.md
# jenkins_robot_mkdocs_demo_project Need to generate ssh keys for Jenkins and MkDocs
Теперь в нашем репозитории ветка andrei/capitalize_names уже слилась с main а ветка andrei/add_header ещё нет.
Визуализация коммитов
Перейдём в ветку andrei/add_header и сделаем rebase.
git checkout andrei/add_header
Switched to branch 'andrei/add_header'
git rebase main
Auto-merging README.md CONFLICT (content): Merge conflict in README.md error: could not apply 458c923... [MKDOCS-123456] - Adds SSH Keys header hint: Resolve all conflicts manually, mark them as resolved with hint: "git add/rm <conflicted_files>", then run "git rebase --continue". hint: You can instead skip this commit: run "git rebase --skip". hint: To abort and get back to the state before "git rebase", run "git rebase --abort". Could not apply 458c923... [MKDOCS-123456] - Adds SSH Keys header
После того как мы выполнили команду git rebase main, git отредактировал файл README.md таким образом, чтобы подсветить нам места конфликтов. В нашем случае конфликт один.
vi README.md
# jenkins_robot_mkdocs_demo_project <<<<<<< HEAD Need to generate ssh keys for Jenkins and MkDocs ======= ## SSH Keys Need to generate ssh keys for jenkins and mkdocs >>>>>>> 458c923 ([MKDOCS-123456] - Adds SSH Keys header)
Отредактируем файл таким образом, чтобы остались нужные нам изменения.
Оставим заглавные буквы из main и новый заголовок из andrei/add_header.
# jenkins_robot_mkdocs_demo_project ## SSH Keys Need to generate ssh keys for Jenkins and MkDocs
Если сейчас сделать git rebase --continue получим сообщение о том, что необходимо сделать merge.
git rebase --continue
README.md: needs merge You must edit all merge conflicts and then mark them as resolved using git add
git add README.md
git rebase --continue
В нашем случае можно оставить предлагаемый текст для коммит-сообщения. В общем случае можно подумать
о редактировании во избежание одинаковых текстов сообщений в коммитах.
Нажимаем CTRL + O, затем ENTER
nano
Нажимаем CTRL + X
nano
hint: Waiting for your editor to close the file... [detached HEAD 620f900] [MKDOCS-123456] - Adds SSH Keys header 1 file changed, 2 insertions(+) Successfully rebased and updated refs/heads/andrei/add_header.
Если теперь сделать обычный push, то он не пройдёт так как наша локальная ветка
сейчас слилась с main а ветка на GitHub впереди main.
Понятно, что на самом деле наша локальная ветка уже содержит больше полезного кода чем
удалённая, но Git об этом не знает.
git push origin andrei/add_header
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts. To github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git ! [rejected] andrei/add_header -> andrei/add_header (non-fast-forward) error: failed to push some refs to 'github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.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.
Решить эту проблему можно, например, с помощью опции -f
git push -f origin andrei/add_header
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts. Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 24 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 347 bytes | 347.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 2 local objects. To github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git + 458c923...620f900 andrei/add_header -> andrei/add_header (forced update)
Найдите наш PR в списке открытых
https://devhops.ru
Нажмите Merge Pull Request
https://devhops.ru
Нажмите Confirm Merge
https://devhops.ru
Убедитесь в успехе
https://devhops.ru
Обратите внимание, что теперь ветка andrei/add_header видна так, как-будто она появилась только после слияния main и andrei/capitalize_names
https://devhops.ru
Далее осталось только убедиться, что файл README.md имеет тот вид, который планировался и локально и на GitHub.
Разрешение конфликтов в GitHub
В этом примере мы будет разрешать конфликт прямо в онлайн редакторе GitHub
Продолжим редактировать файл
README.md
vi README.md
# jenkins_robot_mkdocs_demo_project ## SSH Keys Need to generate ssh keys for Jenkins and MkDocs
Изначально мы в ветке main
git status
On branch main Your branch is up to date with 'origin/main'. nothing to commit, working tree clean
Создадим новую ветку andrei/update_header и перейдём в неё.
git checkout -b andrei/update_header
Switched to a new branch 'andrei/update_header'.
Внесём изменения в файл README.md
vi README.md
# jenkins_robot_mkdocs_demo_project ## Precondition - SSH Keys Need to generate ssh keys for Jenkins and MkDocs Keys should be stored in ./keys/jenkins and ./keys/mkdocs directories
git status
On branch andrei/update_header Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: README.md no changes added to commit (use "git add" and/or "git commit -a")
Закоммитим изменения
git add README.md
git commit -m "[MKDOCS-123458] - Updates header"
[andrei/update_header 854e2d6] [MKDOCS-123458] - Updates header 1 file changed, 1 insertion(+), 1 deletion(-)
Вернёмся в ветку main
git checkout main
Switched to branch 'main' Your branch is up to date with 'origin/main'.
Файл README.md не изменился.
vi README.md
# jenkins_robot_mkdocs_demo_project ## SSH Keys Need to generate ssh keys for Jenkins and MkDocs Keys should be stored in ./keys/jenkins and ./keys/mkdocs directories
Создадим новую ветку andrei/capitalize_header_and_ssh и перейдём в неё.
git checkout -b andrei/capitalize_header_and_ssh
Switched to a new branch 'andrei/capitalize_header_and_ssh'
Изменим ту же самую строку, что и в прошлой ветке. Но теперь просто сделаем из Keys KEYS
vi README.md
# jenkins_robot_mkdocs_demo_project ## SSH KEYS Need to generate SSH keys for Jenkins and MkDocs
Закоммитим изменения
git add README.md
git commit -m "[MKDOCS-123459] - Capitalize"
[andrei/capitalize_header_and_ssh dfed6fa] [MKDOCS-123459] - Capitalize 1 file changed, 2 insertions(+), 2 deletions(-)
Запушим коммит на GitHub
git push origin andrei/capitalize_header_and_ssh
Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 24 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 349 bytes | 349.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 2 local objects. remote: remote: Create a pull request for 'andrei/capitalize_header_and_ssh' on GitHub by visiting: remote: https://github.com/AndreiOlegovich/jenkins_robot_mkdocs_demo_project/pull/new/andrei/capitalize_header_and_ssh remote: To github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git * [new branch] andrei/capitalize_header_and_ssh -> andrei/capitalize_header_and_ssh
Нажмите Compare & pull request
https://devhops.ru
Нажмите Create Pull Request
https://devhops.ru
Нажмите Merge Pull Request
https://devhops.ru
Нажмите Confirm Merge
https://devhops.ru
Ветка сольётся с main
https://devhops.ru
Теперь на Гитхабе у нас в main добавлен коммит который сделал SSH KEYS
Вернёмся в main.
git checkout main
Switched to branch 'main' Your branch is up to date with 'origin/main'.
Можно подтянуть изменения из GitHub и убедиться, что теперь в main строка ## SSH KEYS
Но это необязательно.
git pull
remote: Enumerating objects: 1, done. remote: Counting objects: 100% (1/1), done. remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0) Unpacking objects: 100% (1/1), 927 bytes | 927.00 KiB/s, done. From github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project 7b69e42..a274ca5 main -> origin/main Updating 7b69e42..a274ca5 Fast-forward README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Перейдём в ветку andrei/update_header
git checkout andrei/update_header
Switched to branch 'andrei/update_header'
Запушим коммит на GitHub
git push origin andrei/update_header
Enumerating objects: 5, done. Counting objects: 100% (5/5), done. Delta compression using up to 24 threads Compressing objects: 100% (3/3), done. Writing objects: 100% (3/3), 340 bytes | 340.00 KiB/s, done. Total 3 (delta 2), reused 0 (delta 0), pack-reused 0 remote: Resolving deltas: 100% (2/2), completed with 2 local objects. remote: remote: Create a pull request for 'andrei/update_header' on GitHub by visiting: remote: https://github.com/AndreiOlegovich/jenkins_robot_mkdocs_demo_project/pull/new/andrei/update_header remote: To github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project.git * [new branch] andrei/update_header -> andrei/update_header
Нажмите Compare & pull request
https://devhops.ru
Нажмите Create Pull Request
https://devhops.ru
Нажмите Resolve conflicts
https://devhops.ru
На экране будет подсвечен код, который конфликтует
https://devhops.ru
В редакторе оставьте нужный код.
В этом примере оставлен код из ветки andrei/update_header
https://devhops.ru
Нажмите Commit merge
https://devhops.ru
Нажмите Merge Pull Request
https://devhops.ru
Нажмите Confirm Merge
https://devhops.ru
Ветка сольётся с main
https://devhops.ru
Если изучить коммиты то видно слияние main в andrei/update_header
https://devhops.ru
Перейдём в main и подтянем последние изменения
git checkout main
Switched to branch 'main' Your branch is up to date with 'origin/main'.
git pull
remote: Enumerating objects: 8, done. remote: Counting objects: 100% (8/8), done. remote: Compressing objects: 100% (4/4), done. Unpacking objects: 100% (4/4), 1.89 KiB | 1.89 MiB/s, done. remote: Total 4 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0) From github.com:AndreiOlegovich/jenkins_robot_mkdocs_demo_project a274ca5..960ad95 main -> origin/main 854e2d6..182b4ba andrei/update_header -> origin/andrei/update_header Updating a274ca5..960ad95 Fast-forward README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
vi README.md
# jenkins_robot_mkdocs_demo_project ## Precondition - SSH Keys Need to generate SSH keys for Jenkins and MkDocs
Автор статьи: Андрей Олегович
| Git | |
| branch: Ветки | |
| merge: Слияние | |
| Конфликты |