У меня есть нечеткое представление о том, что индекс git
содержит как git-add
s и git-commit
s, но у меня нет подсказки о том, что происходит с этим содержимым, когда вы делаете git-merge
. Мне особенно интересно узнать, что делает индекс, когда слияние происходит неудачно (например, из-за конфликта).Как содержимое индекса git развивается во время слияния (и что находится в индексе после неудачного слияния)?
ответ
Для любого заданного пути в индексе есть до четырех «номеров версий», пронумерованных 0 (ноль) до 3. Я назову их «слотами», как если бы они были на самом деле для каждой записи, а затем легко индексируется (это облегчает их обсуждение), хотя на самом деле дополнительные версии вводятся динамически только тогда, когда это необходимо. Эти «виртуальные слоты» могут быть «пустыми», то есть файл не существует.
(На самом деле, как только запись создается в индексе, она помечается бит-бит, CE_REMOVED
, если это необходимо. Это становится волосатым, потому что весь каталог, полный файлов, можно пометить «удаленным», а затем файл может быть созданный с именем предыдущего каталога и помеченным как «добавленный». Давайте просто притворимся, что у нас есть фиксированные слоты, там-но-пусто, вместо. :-))
Слот № 0 является «нормальным», не конфликтующим , все-хорошо. Он содержит кучу данных кэша, имя пути и идентификатор blob-ID (SHA-1) для файла, хранящегося в репозитории.
Когда слияние завершается успешно, все это «обычное дело», поэтому единственным частным случаем является конфликтное слияние. Слияние «конфликтует», когда слоты 1, 2 и/или 3 не являются пустыми. Пройдя большую часть механики, это происходит. Слияние использует «новейший» имя для всех слотов, а также:
- слот ноль остается пустым (вы не можете «совершить», пока не разрешить конфликт, к тому времени этот слот не будет пустым если вы действительно не хотите, чтобы файл был удален).
- Слот 1 («основание») заполнен общей версией предка. Если файл является новым (в обеих версиях), этот слот пуст.
- Слот 2 («наш») заполнен мишенью (
HEAD
, если только вы не вручную ссылаетесь на некоторые из основных механизмов слияния). Если файл был удален вHEAD
/target-of-merge, вместо этого этот слот пуст. - Слот 3 («их») заполнен версией, объединенной в бытие. Если файл был удален в ревизии, связанной с объединением, этот слот пуст.
После того, как вы разрешите конфликт и «добавьте git», слот # 0 будет заполнен всем, что вы «добавите», уничтожив записи с # 1 по # 3 или, если вы «git rm», конфликтный файл, остальные записи в стадии записи все еще удаляются, но теперь слот # 0 остается пустым, что также устраняет конфликт.
Более конкретно, то, что у вас есть общий предок, который имеет (среди прочих) эти два файла:
gronk
flibby
Вы находитесь на ветке cleanup
и вы переименовали gronk
в breem
и редактировать как это и flibby
. Вы принимаете решение git merge work
, где они модифицировали gronk
, но не переименовали его и удалили flibby
. Некоторые другие файлы (файлы) сливаются чисто.
Индекс будет содержать три версии bleem
и две версии flibby
:
$ git checkout cleanup
Switched to branch 'cleanup'
$ git merge work
CONFLICT (modify/delete): flibby deleted in work and modified
in HEAD. Version HEAD of flibby left in tree.
Auto-merging bleem
CONFLICT (content): Merge conflict in bleem
Automatic merge failed; fix conflicts and then commit the result.
$ git ls-files --stage
100644 4362aba7f3b7abf2da0d0ed558cbf5bc0d12e4b0 1 bleem
100644 49db92a61392e9fd691c4af6e1221f408452a128 2 bleem
100644 04b399c8fe321902ce97a1538248878756678ca2 3 bleem
100644 366b52546711401122b791457793a38c033838dd 1 flibby
100644 6fecb1480f45faaabc31b18c91262d03d3767cde 2 flibby
100644 7129c6edb96d08bb44ca1025eb5ae41d41be8903 0 x.txt
Вы можете увидеть оригинал (базовый) вариант bleem
git show :1:bleem
с. Это было названо gronk
в базовой версии (и в work
, а в данном случае), но теперь это называется bleem
, потому что git считает, что вы переименовали gronk
в bleem
в cleanup
. (Git находит переименовывает между слиянием базы и HEAD
, а затем применяет ту же переименовывать к work
при необходимости, так как в этом случае.)
Кроме того, вы можете увидеть версию work
с git show :3:bleem
или git show work:gronk
, а версия HEAD
с любым из: git show HEAD:bleem
, git show cleanup:bleem
, или git show :2:bleem
(слот 2 содержит HEAD
aka cleanup
, и назван в соответствии с наименованием в HEAD
).
Для flibby
, так как он был удален в work
, нет версии «их» (слот 3).
Для устранения конфликтов вам необходимо сообщить только git add
или git rm
, чтобы обновить запись с нулевым номером и удалить записи с 1 по 3. Конечно, с git add
, то, что идет в слот 0, теперь находится в рабочем каталоге, поэтому вам обычно приходится сначала редактировать файлы.
Кстати, я обозначил слоты 2 и 3 «наши» и «их» выше. Так как git checkout
обрабатывает их (git checkout --ours
и git checkout --theirs
, вы можете написать версию 2 или 3 в слот 0, такая проверка, как и большинство проверок, также «стирает» другие слоты, тем самым разрешая конфликт). Тем не менее, в rebase ветвь HEAD
на самом деле является ветвью, переустановленной на, а «их» версия - это ваше подразделение-перераспределение. Таким образом, наша/терминология на самом деле не такая уж большая, на мой взгляд: слишком легко вернуть ее во время перебазы.
Следует также отметить, что git checkout -m
будет «воссоздавать» конфликт слияния, если вы находитесь в середине конфликтного слияния, стирая слот 0 и «воскрешая» версии в слотах 1-3 по мере необходимости (и записывать конфликтуемый файл слияния в рабочий каталог, выполняя любые изменения в настройке merge.conflictstyle
).
Это очень хороший ответ. –
- 1. Git - вернуться к ветвям после неудачного слияния?
- 2. Поврежденная ревизия после неудачного слияния
- 3. Git слияния после слияния и возвращается
- 4. Git rebase развивается до слияния для разработки?
- 5. Как отменить "git add." во время слияния?
- 6. git удалить файлы при отмене неудачного слияния
- 7. git: избегать дублирования методов во время слияния
- 8. Git: Confuse после слияния
- 9. Git; код исчез после слияния
- 10. Git - Игнорировать файлы во время слияния
- 11. `git stash` во время конфликта слияния
- 12. Обновление данных mergeinfo после неудачного слияния
- 13. Раскадровка повреждена во время слияния
- 14. Git: Как сбрасывать после слияния?
- 15. Требуется фиксация после разрешения конфликта слияния во время перезагрузки Git?
- 16. Как развить две ветви git вокруг неудачного слияния
- 17. Исправление конфликта без слияния во время переустановки?
- 18. Как увидеть изменения во время «конфликта слияния» в git rebase
- 19. Как мне удалить конфликты слияния git после слияния неправильно?
- 20. Может ли Git конвертировать слияния в squash во время rebase?
- 21. Git: Отменить локальные изменения с момента неудачного слияния
- 22. Git commit исчез после слияния
- 23. восстановление ветвей git после слияния
- 24. проверить изменения после слияния git
- 25. Сохранение изменений во время неполного слияния
- 26. OutOfMemoryError во время слияния PDF
- 27. Squashing Git фиксируется после слияния
- 28. Как Git прослушивает изменения из редактора во время конфликта слияния?
- 29. Git hook для конфликтов слияния
- 30. Что такое стратегии слияния git?
merge и rebase похожи в некоторых точках. Возможно, вы можете видеть, что происходит, выполняя 'git rebase -i' и заменяя все' pick' на 'edit', а затем наблюдая модификацию .git – Asenar
@Asenar: сходство возникает, потому что' rebase' представляет собой серию 'cherry-pick' операции внутри и для каждой собранной вишни, git использует механизм слияния для применения изменений, подразумеваемых этим фиксатором. – torek
благодарю вас за эту точность :) – Asenar