В этой статье я расскажу о полезном, но малоизвестном приеме работы с git — о том, как можно легко создать коммит, используя дерево из другого коммита.
Проще говоря, как получить нужное состояние проекта на любой ветке, если это состояние раньше уже было где-то в репозитории.
Будет несколько примеров того, как это позволяет элегантно решать некоторые практические задачи.
И, в частности, я расскажу об найденном мной методе, который значительно упрощает исправление множественных конфликтов во время перебазирования.
Кроме того, эта статья — отличный способ на практике понять, что такое коммит в git.
Содержание
Теоретическая часть.О коммитах и деревьях
git дерево коммитов Практическая часть 1. Синхронизация с другой веткой 2. Сравнение двух ветвей 3. Вернуть ветку 4. Частичный реверс 5. Искусственное слияние 6а.Метод перебазирования через слияние — описание
6б.Метод перебазирования через слияние — скрипт
7. Псевдоним Заключение Теоретическая часть.
О коммитах и деревьях
Коммит — это, наверное, самое базовое понятие в git, давайте посмотрим, из чего он состоит. Каждый коммит имеет свой уникальный идентификатор в виде хеша, например 5e45ecb .
И с помощью следующей команды, зная хеш, мы сможем просмотреть его содержимое.
git cat-file -p 5e45ecb
tree 8640790949c12690fc71f9abadd7b57ec0539376
parent 930741d1f5fd2a78258aa1999bb4be897ba3d015
author Mark Tareshawty <[email protected]> 1542718283 -0500
committer Mark Tareshawty <[email protected]> 1542718283 -0500
gpgsig -----BEGIN PGP SIGNATURE-----
.
-----END PGP SIGNATURE-----
Fix scoping so that we don't break the naming convention
Эти несколько строк содержат все содержимое коммита:
- дерево — ссылка на конкретное состояние проекта
- родительский — ссылка на родительский коммит
- автор — автор исходного коммита + дата
- коммиттер — создатель этого коммита + дата
- gpgsig — цифровая подпись (если имеется)
- сообщение — текст фиксации
Здесь наоборот: каждый коммит описывает конкретное состояние проекта в целом, и то, что мы видим как вносимые им изменения, на самом деле является динамически вычисляемой разницей по сравнению с предыдущим состоянием.
Также стоит отметить, что все коммиты являются неизменяемыми (неизменяемыми), то есть, например, при rebase/cherry-pick/amend создаются совершенно новые коммиты.
Tree (дерево) — это, по сути, просто папка с определенным неизменяемым содержимым.
Объект типа «дерево» содержит именованный список файлов с определенным содержимым (блобы) и подпапками (деревья).
А дерево, на которое указывает каждый коммит, — это корневая папка проекта, а точнее его конкретное состояние.
просмотреть содержимое дерева Точно так же это можно сделать и для любого другого объекта (commit/tree/blob), и достаточно взять несколько первых уникальных символов хеша: 8640790949c12690fc71f9abadd7b57ec0539376 -> 8640790. git cat-file -p 8640790
100644 blob 7ab08294a46f158c51460be3e7df6a190e15023b .
env.example 100644 blob 0a1a4d1ad9ff3f35b67678ca893811e91b423af5 .
gemset 040000 tree 033aa38ce0eab11fe229067c14ccce95e2b8b601 .
github 100644 blob ca49bb7ffa6273b0be4ce7ba1accba456032fb11 .
gitignore 100644 blob c99d2e7396e14ac072c63ec8419d9b8fede28d86 .
rspec 100644 blob 65e77a2f59f635a8f24eb4714e8e43745c5c0eb9 .
rubocop.yml 100644 blob 8e8299dcc068356889b365e23c948b92c6dfcd78 .
ruby-version 100644 blob 19028f9885948aca2ba61f9d062e9dc21c21ad03 .
stylelintrc.json 100644 blob 2f7a032fbc3f4f7195bfd91cb33889a684b572b9 .
travis.yml
100644 blob 121615722a6c206a9fe24b9a1c9b647662a460d2 ARCHITECTURE.md
100644 blob 898195daeea0bbf8c5930deeaf1020ba8abab34a Gemfile
100644 blob de7ca707f9fe9172db941b65cdacaba7e024fc06 Gemfile.lock
100644 blob e6ff62fefd071b1a8ca279bae94ddbc4dd17b7a3 Gruntfile.js
100644 blob 0cac5b30fb32d36cce2aeb7d936be7b6207d68c7 MIT-LICENSE.txt
100644 blob c2c566e8cc3d440d3ee8041b79cded416db28136 Procfile
100644 blob d1fb2f575380e1e093a4d82e3f19e51f0b99a0a1 Procfile.dev
100644 blob 3a88e138f10fa65bd2cfe1a1d3292348205508b5 README.md
100644 blob 5366e6e073cc426518894cc379d3a07cf3c9cfb3 Rakefile
100644 blob e6d3d2d3e9d5122c5f75bbeee8ed0917ad38c131 app.json
040000 tree 94f83cf03bd6f1cf14672034877b14604744b7a2 app
040000 tree d4d859e82564250b4c4f2047de21e089e7555475 bin
100644 blob 1f71007621f17334fd6f2dd71c87b7a16867119c config.ru
040000 tree 9e8e4bf5ec44541aefff544672b94ca8a9d07bbf config
040000 tree 31b8d0e1fa2bb789dbd6319e04fc9f115952cf2a db
040000 tree 38e7a13e0e772c2a13e46d2007e239f679045bee doc
040000 tree a6e35ded8b35837660cf786e637912377f845515 lib
040000 tree d564d0bc3dd917926892c55e3706cc116d5b165e log
100644 blob 843523565ddee5e00f580d9c4e37fc2478fdaecc package-lock.json
100644 blob 791ee833ad316d75b1d2c83a64a3053fc952d254 package.json
040000 tree 4645317c52675d9889f89b26f4dd4d2ae1d8cbad public
040000 tree 31d3f8ae4a4ffe62787134642743ed32a35dbae2 resources
040000 tree 807ffa29868ef9c25ddb4b4126a4bb7f1b041bf0 script
040000 tree 4c3bf9a7f3679ba059b0f1c214a500d197546462 spec
040000 tree 136c8174412345531a9542cafef25ce558d2664f test
040000 tree e6524eafe066819e4181bc56c503320548d8009b vendor
На самом деле это важнейшая особенность работы git: идентификатор фиксации на самом деле представляет собой хэш его содержимого.
Точно так же, как хэши вложенных в него объектов (деревьев, блобов).
Теперь давайте посмотрим, что произойдет, когда мы это сделаем.
git commit -m "Fixed bug"
Эта команда создает новый коммит, который содержит следующее:
- промежуточное состояние проекта (сохраняется как новый объект дерева и берется его хэш)
- ссылка на текущий (родительский) коммит
- автор + коммиттер + две даты
- зафиксировать текст
И команда автоматически поднимает на него указатель текущей ветки.
немного о терминологии Как мы уже знаем, дерево — это объект, который содержит состояние всего проекта в какой-то конкретный момент в прошлом — когда был создан коммит с этим деревом.
Рабочая папка называется рабочим деревом/рабочей копией/рабочим каталогом, что вполне логично.
Еще у нас есть — staging area/index — область подготовленных изменений.
Но логически это тоже дерево Точнее, состояние, которое сохраняется при коммите в виде дерева.
Поэтому мне кажется, что логичнее было бы назвать это поэтапным деревом.
git дерево коммитов
И наконец мы можем перейти к описанию нужной нам команды git дерево коммитов .Формально это одна из низкоуровневых команд, поэтому она редко упоминается и используется.
Мы не будем рассматривать другие связанные с ним низкоуровневые команды (такие как git write-tree, git-update-index, они также известны как сантехнические команды).
Нас интересует только одно конкретное последствие: с помощью этой команды мы можем легко скопировать (повторно использовать) дерево состояний проекта из любого другого коммита.
Давайте посмотрим ее вызов git commit-tree 4c835c2 -m "Fixed bug" -p a8fc5e3
d9aded78bf57ca906322e26883644f5f36cfdca5
Команда git commit-tree также создает фиксацию, но низкоуровневым способом.
Здесь необходимо явно указать уже существующее дерево (дерево) 4c835c2 и ссылку на родительский коммит a8fc5e3. И возвращает хеш нового коммита d9aded7, но не меняет положение ветки (поэтому этот коммит как будто висит в воздухе).
Практическая часть
Примеры этой команды продемонстрированы в следующем простом репозитории.
Он содержит три ветви: мастер - основная ветка
альфа — ветка, над которой мы работаем и находимся
бета - ветка, которая уже была слита с мастером Все действия можно легко повторить локально; для этого достаточно клонировать репозиторий, присоединиться к альфа-ветке и затем выполнить команды из примеров.
Это исходное состояние является общим для всех примеров.
git clone https://github.com/capslocky/git-commit-tree-example.git
cd .
/git-commit-tree-example/
git checkout alpha
под окнами Все команды, включая скрипт, работают и под Windows. Вам просто нужно открыть bash-терминал в папке проекта, например, вот так "C:\Program Files\Git\git-bash.exe" --cd="D:\path\project"
1. Синхронизация с другой веткой
Задача: Синхронизировать состояние проекта в ветке альфа с филиалом бета .То есть нужно создать на ветке альфа такой новый коммит, чтобы состояние проекта стало точно таким же, как на ветке бета .
Эта конкретная проблема вряд ли когда-либо возникнет, но это наиболее подходящий случай для демонстрации подхода.
Самое простое решение — взять существующее дерево, на которое указывает бета-ветвь, и просто указать на него из нового коммита для альфа-ветки.
Поскольку это первый пример, вся его логика рассматривается достаточно подробно.
Сначала найдем хеш коммита, на который указывает бета-ветка: git rev-parse origin/beta
280c30ff81a574f8dd41721726cf60b22fb2eced
280c30f - просто возьмите первые несколько символов Теперь найдем хеш его дерева, отобразив содержимое коммита через git cat-файл: git cat-file -p 280c30f
tree 3c1afe75f54518dbd82ea7a4e3c4ff50389a573a <---
parent 560b449675513bc8f8f4d6cda56a922d4e36917a
author Baur <[email protected]> 1540619512 +0600
committer Baur <[email protected]> 1540619512 +0600
Added info about windows
3c1afe7 - это то дерево, которое нам нужно А теперь давайте создадим коммит, указывающий на это дерево, и используем родительский коммит для указания текущего коммита: git commit-tree 3c1afe7 -m "Synced with branch 'beta'" -p HEAD
eb804d403d4ec0dbeee36aa09da706052a7cc687
Всё, коммит создан, команда вывела его хеш.
При этом это значение всегда будет уникальным, поскольку рассчитывается не только от дерева, но и от автора и времени.
Сам коммит висит в воздухе, так как он еще не включен ни в одну из веток.
Нам просто нужно взять первые несколько символов: eb804d4 , я обозначим это значение, уникальное для каждого случая, как ххххххх .
Давайте посмотрим на его содержимое: git cat-file -p xxxxxxx
tree 3c1afe75f54518dbd82ea7a4e3c4ff50389a573a <---
parent 64fafc79e8f6d22f5226490daa5023062299fd6c
author Peter <[email protected]> 1545230299 +0600
committer Peter <[email protected]> 1545230299 +0600
Synced with branch 'beta'
Отлично, у него то же дерево, что и у коммита в ветке origin/beta. А поскольку этот коммит является прямым потомком текущей ветки, чтобы включить его в ветку, вам просто нужно выполнить ускоренное слияние.
git merge --ff xxxxxxx
Updating 64fafc7.xxxxxxx
Fast-forward
Azure.txt | 3 ---
Bill.txt | 6 +-----
Linus.txt | 15 +++++++++++++++
3 files changed, 16 insertions(+), 8 deletions(-)
Готовый.
Теперь состояние проекта на альфа-ветке точно такое же, как и на бета-ветке.
[обновлять] И если мы посмотрим, что на самом деле изменил этот коммит, мы увидим: он отменил все свои собственные коммиты (изменения) альфа-ветки и добавил все уникальные коммиты (изменения) бета-ветки относительно их общего предка.
2. Сравнение двух ветвей
Задача: Сравнить ветку альфа с филиалом бета .Из первого примера вы можете видеть, что зафиксированный коммит показывает все те изменения, которые являются фактической разницей между двумя ветвями.
Это свойство позволяет легко сравнивать одну ветвь с другой.
Достаточно создать третью временную ветку и сделать в ней аналогичный коммит. Итак, сначала вернем альфа-ветвь в исходное состояние git reset --hard origin/alpha
Давайте создадим временную ветку текущего коммита и присоединимся к ней.
git checkout -b temp
И все, что нам нужно сделать, это сделать то же самое, что и в предыдущем примере.
Но на этот раз мы будем придерживаться одной линии.
Для этого мы будем использовать специальный синтаксис для доступа к дереву коммитов.
происхождение/бета^{дерево} или что то же самое 280c30f^{дерево} .
git merge --ff $(git commit-tree origin/beta^{tree} -m "Diff with branch 'beta'" -p HEAD)
Готово, по сути мы материализовали разницу между двумя ветвями в виде коммита.
git show
git diff alpha origin/beta
Конечно, мы можем создать такой «сравнительный» коммит для любых двух коммитов (состояний) в репозитории.
3. Вернуть ветку
Задача: Откатить последние несколько коммитов.Вернемся к альфа-ветке и удалим временную ветку.
git checkout alpha
git branch -D temp
Допустим, нам нужно откатить два последних коммита в альфа-ветке.
Есть два классических способа сделать это:
- Запустите git revert дважды — для каждого коммита.
- git reset, то есть сброс положения ветки
git merge --ff $(git commit-tree 7a714bf^{tree} -m "Reverted to commit 7a714bf" -p HEAD)
Это добавит один новый коммит, который откатит изменения из двух предыдущих коммитов.
В отличие от первого метода, создается только один коммит, даже если последние десять коммитов необходимо откатить.
Отличие метода сброса git в том, что мы не выбрасываем эти коммиты из самой ветки.
Далее, если вам позже понадобится вернуть исходное состояние ветки, то это можно сделать аналогичным образом.
git merge --ff $(git commit-tree 64fafc7^{tree} -m "Reverted back to commit 64fafc7" -p HEAD)
При этом эти два коммита останутся в истории ветки, которая будет показывать, что ее откатили и вернули обратно.
4. Частичный реверс
Задача: Откатить изменения в некоторых файлах из последних нескольких коммитов.
Вернем альфа-ветвь еще раз в исходное состояние git reset --hard origin/alpha
Ветка альфа содержит 3 коммита, каждый из которых вносит изменения в файл Bill.txt, последний коммит также добавляет файл Azure.txt. Допустим, нам нужно откатить изменения в файле Bill.txt для двух последних коммитов, не трогая при этом другие файлы.
Во-первых, давайте откатим все файлы, которые фиксирует 2. git merge --ff $(git commit-tree 7a714bf^{tree} -m "any text" -p HEAD)
Далее вернем ветку к предыдущему коммиту, но не трогая состояние проекта на диске git reset HEAD~1
И теперь достаточно проиндексировать нужные файлы и сделать коммит, а остальные изменения можно отбросить.
git add Bill.txt
git commit -m "Reverted file Bill.txt to 7a714bf"
git reset --hard HEAD
5. Искусственное слияние
Задача: Меркайте одну ветку с другой, получая заранее заданный результат. Давайте представим себе эту ситуацию.В продакшене обнаружена критическая ошибка и ее как всегда нужно срочно исправлять.
Однако неясно, сколько времени потребуется на его изучение и изготовление правильного исправления, поэтому быстро было сделано временное исправление, изолирующее взаимодействие с проблемным модулем.
Итак, в ветке master появляется коммит с этим временным патчем, а через какое-то время вместо него в master нужно мержить полноценный хотфикс.
Таким образом, нам необходимо слить альфа-ветку с мастером, но это не должен быть традиционный мерж, когда все уникальные изменения из альфа-ветки добавляются в мастер сверху и возникает конфликт, а мы должны полностью перезаписать мастер с альфа-веткой.
ветвь.
Для начала давайте в общих чертах вспомним, что такое мердж-коммит — по сути, это тот же обычный коммит, только у него есть два родительских коммита, это хорошо видно, если посмотреть на его содержимое (как формируется его дерево — это отдельный вопрос).
А кто в кого сливается, определяется просто — основным считается первый родительский коммит. git cat-file -p 7229df8
tree 3c1afe75f54518dbd82ea7a4e3c4ff50389a573a
parent fd54ab7dde87593b9892b6d1ffbf1afd39ba6f9e
parent 280c30ff81a574f8dd41721726cf60b22fb2eced
author Baur <[email protected]> 1540619579 +0600
committer Baur <[email protected]> 1540619592 +0600
Merge branch 'beta' into 'master'
Сбросьте текущую альфа-ветвь в исходное состояние и переключитесь на главную.
git reset --hard origin/alpha
git checkout master
И теперь та же команда, но с два родитель совершает git merge --ff $(git commit-tree alpha^{tree} -m "Merge 'alpha' into 'master', but take 'alpha' tree" -p HEAD -p alpha)
Готово, мы объединили альфа-ветку с основной, и нам не пришлось удалять временный код или разрешать конфликты, так как в этом случае нам нужно было просто перезаписать последние изменения.
На самом деле, не так уж и странно создать слияние с деревом, скопированным из другого коммита.
Такие ситуации могут возникнуть, поскольку git — очень гибкий инструмент, позволяющий реализовать самые разные подходы к работе с ветками и репозиториями.
Но всё же самый банальный пример был в нашем репозитории с самого начала — попробуйте разобрать его самостоятельно или откройте спойлер, чтобы прочитать объяснение.
спойлер Обратим внимание на то, как бета-ветка была объединена обратно в мастер-версию.
За то время, пока в нем появлялись два коммита, в самой мастер-ветке новых коммитов не было.
Это означает, что при объединении бета-версии с основной версией исключаются любые конфликты из-за одновременных изменений.
Если бы мы сделали бета-версию git merge, то произошло бы ускоренное слияние (поведение согласно по умолчанию ), то есть основная ветка просто появится в том же коммите, где находится бета-ветвь, и коммита слияния не будет. Это было бы так:
Но здесь слияние без перемотки вперед было выполнено с помощью команды git merge beta --no-ff. То есть мы принудительно создали коммит слияния, хотя это и не требовалось.
А поскольку желаемое конечное состояние проекта для будущего мержа было известно — это дерево ветвей бета-версии, git просто скопировал ссылку на это дерево в новый коммит: git cat-file -p origin/beta
tree 3c1afe75f54518dbd82ea7a4e3c4ff50389a573a <---
parent 560b449675513bc8f8f4d6cda56a922d4e36917a
author Baur <[email protected]> 1540619512 +0600
committer Baur <[email protected]> 1540619512 +0600
Added info about windows
git cat-file -p 7229df8
tree 3c1afe75f54518dbd82ea7a4e3c4ff50389a573a <---
parent fd54ab7dde87593b9892b6d1ffbf1afd39ba6f9e
parent 280c30ff81a574f8dd41721726cf60b22fb2eced
author Baur <[email protected]> 1540619579 +0600
committer Baur <[email protected]> 1540619592 +0600
Merge branch 'beta' into 'master'
6а.
Метод перебазирования через слияние — описание
Задача:
Нам нужно сделать «тяжелую» перезагрузку ветки (много конфликтов на разных коммитах).
В git есть такая классическая холиварная тема — rebase vs merge. Но я не буду его охлаждать.
Наоборот, я расскажу о том, как их можно подружить в контексте этой задачи.
В общем, git был специально разработан для того, чтобы мы могли эффективно мержить.
И когда я пришел к проекту, где рабочий процесс был основан на rebase, поначалу мне было неудобно и непривычно, пока я не разработал приемы, упрощающие мою повседневную работу с git. Один из них — мой оригинальный метод выполнения тяжелой перебазировки.
Итак, нам нужно перебазировать альфа-ветвь для разработки, чтобы мы могли затем объединить ее так же красиво, как была объединена бета-ветвь.
Если мы начнем выполнять перебазирование как обычно, первый и последний коммит создадут два разных конфликта в двух разных местах.
Но если бы вместо rebase мы просто сделали слияние, то в одном слиянии коммита был бы только один конфликт в одном месте.
Если вы хотите в этом убедиться, предлагаю под спойлером готовые команды.
Скрытый текст Возвращение веток в исходное состояние git checkout master
git reset --hard origin/master
git checkout alpha
git reset --hard origin/alpha
Давайте создадим и присоединимся к ветке альфа-rebase-conflicts и перебазуем ее в master. git checkout -b alpha-rebase-conflicts
git rebase master
На разных коммитах будут конфликты, в том числе «фантомный» конфликт. Теперь давайте попробуем слияние, вернемся к альфа-ветке и удалим ветку перебазирования.
git checkout alpha
git branch -D alpha-rebase-conflicts
Давайте переключимся на мастер и выполним слияние git checkout master
git merge alpha
Будет всего один простой конфликт, исправьте его и сделайте это.
git add Bill.txt
git commit -m "Merge branch 'alpha' into 'master'"
Слияние завершено успешно.
Конфликты Git — естественная часть нашей жизни, и этот простой пример показывает, что в этом отношении слияние определенно удобнее, чем перебазирование.
В реальном проекте эта разница измеряется гораздо большим количеством затраченного времени и нервов.
Поэтому, например, существует неоднозначная рекомендация перед слиянием сжимать все коммиты функциональной ветки в один.
Идея этого метода — сделать временное скрытое слияние, при котором мы разрешаем все конфликты сразу.
Запомните результат (дерево).
Далее запускаем обычный ребаз, но с опцией «автоматически разрешать конфликты путем выбора наших изменений».
И в конце добавьте в ветку еще один коммит, который восстановит правильное дерево.
Давайте начнем.
Давайте снова вернем обе ветки в исходное состояние.
git checkout master
git reset --hard origin/master
git checkout alpha
git reset --hard origin/alpha
Давайте создадим временную ветку temp, в которую будем сливаться.
git checkout -b temp
git merge origin/master
Конфликт. Разрешите один простой конфликт в файле Bill.txt обычным способом (в любом редакторе).
Обратите внимание, что конфликт здесь только один, а не два, как при rebase. git add Bill.txt
git commit -m "Merge branch 'origin/master' into 'temp'"
Возвращаемся в альфа-ветку, делаем ребаз с автоматическим разрешением всех конфликтов в нашу пользу и приводим в состояние временной ветки, а саму временную ветку удаляем.
git checkout alpha
git rebase origin/master -X theirs
git merge --ff $(git commit-tree temp^{tree} -m "Fix after rebase" -p HEAD)
git branch -D temp
И, наконец, красиво объедините альфу с мастером.
git checkout master
git merge alpha --no-ff --no-edit
Обратите внимание, что master, Alpha и удаленная временная ветка указывают на одно и то же дерево, хотя это три разных коммита.
Недостатки этого метода:
- Ручное исправление каждого конфликтующего коммита не требуется — конфликты разрешаются автоматически.
Такой промежуточный коммит может не скомпилироваться.
- Дополнительный коммит добавляется (но не всегда) при каждой перезагрузке.
- Мы исправляем только реальные конфликты (никаких фантомных конфликтов)
- Исправление всех конфликтов происходит только один раз
- Первые два пункта экономят время
- Сохраняется полная история коммитов и всех изменений (можно, например, сделать выборку)
- Метод реализован в виде скрипта и всегда может быть использован при необходимости сделать ребазирование (никаких знаний о деревьях и т.п.
не требуется)
6б.
Метод перебазирования через слияние — скрипт
Скрипт опубликован здесь: https://github.com/capslocky/git-rebase-via-merge Давайте проверим, как это работает, на нашем примере.
Вернем обе ветки еще раз в исходное состояние git checkout master
git reset --hard origin/master
git checkout alpha
git reset --hard origin/alpha
Загрузите скрипт и сделайте его исполняемым.
curl -L https://git.io/rebase-via-merge -o ~/git-rebase-via-merge.sh
chmod +x ~/git-rebase-via-merge.sh
окна Файл появится здесь: C:\Users\имя-пользователя\git-rebase-via-merge.sh. Меняем ветку по умолчанию, в которую нам нужно выполнить ребазирование, в нашем случае нам нужен origin/master nano ~/git-rebase-via-merge.sh
default_base_branch='origin/master'
Давайте также создадим и присоединимся к временной ветке, чтобы не трогать саму альфа-ветку.
git checkout -b alpha-rebase-test
И теперь вы можете запустить скрипт (вместо традиционного git rebase origin/master) ~/git-rebase-via-merge.sh
результат скрипта $ ~/git-rebase-via-merge.sh
This script will perform rebase via merge.
Current branch:
alpha-rebase-test (64fafc7)
Base branch:
origin/master (9c6b60a)
Continue (c) / Abort (a)
c
Auto-merging Bill.txt
CONFLICT (content): Merge conflict in Bill.txt
Automatic merge failed; fix conflicts and then commit the result.
You have at least one merge conflict.
Fix all conflicts in the following files, stage them up and type 'c':
Bill.txt
Continue (c) / Abort (a)
c
[detached HEAD 785d49e] Hidden temp commit to save result of merging 'origin/master' into 'alpha-rebase-test' as detached head.
Merge succeeded on hidden commit:
785d49e
Starting rebase automatically resolving any conflicts in favor of current branch.
First, rewinding head to replay your work on top of it.
Auto-merging Bill.txt
[detached HEAD a680316] Added history of windows
Author: Baur <[email protected]>
Date: Sat Oct 27 11:45:50 2018 +0600
1 file changed, 6 insertions(+), 3 deletions(-)
Committed: 0001 Added history of windows
Auto-merging Bill.txt
[detached HEAD dcd34a8] Replaced history of windows
Author: Baur <[email protected]>
Date: Sat Oct 27 11:55:42 2018 +0600
1 file changed, 4 insertions(+), 5 deletions(-)
Committed: 0002 Replaced history of windows
Auto-merging Bill.txt
[detached HEAD 8d6d82c] Added file about Azure and info about Windows 10
Author: Baur <[email protected]>
Date: Sat Oct 27 12:06:27 2018 +0600
2 files changed, 5 insertions(+), 3 deletions(-)
create mode 100644 Azure.txt
Committed: 0003 Added file about Azure and info about Windows 10
All done.
Restoring project state from hidden merge w
Теги: #git #Системы контроля версий #merge #commit #rebase #TREE #conflict
-
«Тело На Чипе»: Перспективы Технологии
19 Oct, 24 -
Фаерфокс 6.0
19 Oct, 24 -
Аэтутс - Учимся Делать Эффекты
19 Oct, 24 -
Half-Life: Поднимаем Планку
19 Oct, 24 -
Очередная Попытка Об Управлении :)
19 Oct, 24 -
Как Защитить Ваши Данные
19 Oct, 24