Есть ли обратное слиянию осьминога в Git? - PullRequest
4 голосов
/ 14 января 2009

У Git есть очень разрекламированная (?) Возможность слияния осьминогов, которая может объединить множество голов в одну.

Но есть ли что-то, что могло бы сделать наоборот, сделать несколько одновременных ветвей из одного узла?

Давайте предположим, что у меня есть куча кода для проекта, и я только начал использовать Git. Некоторые функции в этом проекте завершены, другие еще находятся в стадии разработки. Я хотел бы, чтобы эти незавершенные объекты были перемещены в их собственную соответствующую и отдельную ветвь и иметь мастер как можно более полным, без незавершенного кода.

Теперь я, конечно, мог бы сделать все это за один шаг: создать ветку «Незаконченная функция # 1» и удалить файлы из мастера, относящиеся к этой функции. Затем я бы перегруппировал мастер в «незавершенную функцию № 2» и снова удалил файлы, специфичные для функции № 2, из мастера, но также и из первой ветви. И, таким образом, рабочая нагрузка увеличивается с каждым делением, которое я делаю.

Есть ли что-то, что могло бы помочь мне в таком сценарии?

Ответы [ 2 ]

11 голосов
/ 14 января 2009

Примечание: сценарий слияния осьминога и точка ветвления осьминога сильно различаются. Пожалуйста, помните, что указатели в DAG (направленный ациклический граф) коммитов указывают от ребенка (более новый коммит) к родителю или родителям. Так что в случае с осьминогом merge у вас есть commit (commit object), у которого более двух родителей; в случае «точки ветвления осьминога» у вас просто есть несколько коммитов, указывающих на тот же коммит, что и его родитель.

слияние осьминога:

1 <---- M
2 <----/ |
3 <------|

точка осьминога:

P <----- 1
^-------- 2
^-------- 3

Так что я думаю, что называть этот вопрос просто неправильно


Ответ

Теперь, если вы хотите разделить изменения в рабочей области между различными ветками, чтобы поместить каждую функцию в отдельную ветку темы, вы можете использовать явную область подготовки (он же индекс) в Гите.

Предположим, что вы изменили два файла, «a» и «b», и вы хотите, чтобы изменение файла «a» перешло в ветвь «A», а изменение в файле «b» - в ветвь «B» , Давайте предположим, что ветвь, в которой вы находитесь в данный момент, точка ветвления, которую вы хотите использовать в качестве основы для множества ветвей, которые вы хотите создать, называется «master».

Сначала давайте создадим ветку 'A'

$ git checkout -b A master

Git отвечает:

M       a
M       b
Switched to a new branch "A"

«M» означает, что файлы «a» и «b» модифицируются относительно точки, на которой вы основали ветвь «A» (ветка «master»). (Ниже я просто помещу git response ниже вызова командной строки вместо того, чтобы отдельно отмечать, что это за ответ.)

Давайте добавим содержимое файла 'a' в область подготовки (индекс).

$ git add a

Обратите внимание, что если вы хотите добавить только некоторое подмножество изменений в файле 'a' в ветку 'A', вы можете использовать «git add --interactive» (сокращенно «-i») или «git gui» для внесение изменений в область подготовки и другие подобные манипуляции за каждый кусок.

Теперь мы фиксируем изменения в ветке 'A'

$ git commit
Created commit 35d0061: Commit description...
 1 files changed, 1 insertions(+), 0 deletions(-)

Обратите внимание , что мы не использовали опцию -a для git-commit!

Кстати, если вы хотите протестировать изменения перед отправкой из промежуточной области, вы можете использовать "git stash save --keep-index", чтобы перевести рабочую область в состояние, которое вы хотите зафиксировать, используя "git commit", test изменения, затем вернитесь в предыдущее состояние, используя "git stash pop --index" (или "git stash pop"; я не помню, какой из них вам нужен здесь).

Теперь мы создаем другую ветвь, ветвь «B», на основе ветки «master»

$ git checkout -b B master
M       b
Switched to a new branch "B"

Вы можете легко увидеть, что изменения, которые вы оставили для ветви «B» (изменения, которые вы не зафиксировали для ветви «A»), переходят во вновь созданную ветку «B». Не нужно удалять файлы или удалять изменения. Не нужно знать, что есть в других ветках. Все автоматически.
Еще раз добавьте содержимое файла 'b' в промежуточную область (индекс) и зафиксируйте ветку "B":

$ git add B
$ git commit

Вы можете повторять это так часто, как это необходимо, и это не усложняется с новой ветвью.

НТН

1 голос
/ 14 января 2009

Поскольку вы только начали использовать Git, было бы проще начать заново и передать только ваш «полный» код в ветку Master. Затем извлеките новую ветку от мастера для функции и зафиксируйте этот «незаконченный» код функции в своей собственной ветви. Повторите для каждой ветви функций.

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

...