git reset
- это перемещение HEAD
, и, как правило, ветвь ref .
Вопрос: а как насчет рабочего дерева и индекса?
При использовании с --soft
, перемещается HEAD
, чаще всего обновляется ссылка на ветку, и только HEAD
.
Это отличается от commit --amend
как:
- это не создает новый коммит.
- он может фактически перемещать HEAD к любому коммиту (поскольку
commit --amend
- это всего лишь , а не перемещение HEAD, при этом позволяя повторить текущий коммит)
Только что нашел этот пример объединения:
- классическое слияние
- объединение поддеревьев
все в один (осьминог, так как объединено более двух веток) совершить слияние.
Томас "wereHamster" Карнекки объясняет в своей статье "Слияние поддеревьев осьминога" :
- Стратегия слияния поддеревьев может использоваться, если вы хотите слить один проект в подкаталог другого проекта и впоследствии поддерживать подпроект в актуальном состоянии. Это альтернатива подмодулям git.
- Стратегия слияния осьминога может использоваться для слияния трех или более веток. Обычная стратегия может объединять только две ветви, и если вы попытаетесь объединить больше, git автоматически вернется к стратегии осьминога.
Проблема в том, что вы можете выбрать только одну стратегию. Но я хотел объединить их, чтобы получить чистую историю, в которой весь репозиторий атомарно обновляется до новой версии.
У меня есть суперпроект, назовем его projectA
, и подпроект projectB
, который я слил в подкаталог projectA
.
(это часть слияния поддерева)
Я также поддерживаю несколько локальных коммитов.
ProjectA
регулярно обновляется, projectB
имеет новую версию каждые пару дней или недель и обычно зависит от конкретной версии projectA
.
Когда я решаю обновить оба проекта, я не просто извлекаю из projectA
и projectB
, так как это создаст два коммита для атомарного обновления всего проекта .
Вместо этого я создаю один коммит слияния, который объединяет projectA
, projectB
и мои локальные коммиты .
Сложность в том, что это слияние осьминога (три головы), , но projectB
необходимо объединить со стратегией поддеревьев . Вот что я делаю:
# Merge projectA with the default strategy:
git merge projectA/master
# Merge projectB with the subtree strategy:
git merge -s subtree projectB/master
Здесь автор использовал reset --hard
, а затем read-tree
, чтобы восстановить то, что первые два слияния сделали с рабочим деревом и индексом, но здесь reset --soft
может помочь:
Как мне повторить те два слияния , которые сработали, то есть мое рабочее дерево и индекс в порядке, но без необходимости записывать эти два коммита?
# Move the HEAD, and just the HEAD, two commits back!
git reset --soft HEAD@{2}
Теперь мы можем возобновить решение Томаса:
# Pretend that we just did an octopus merge with three heads:
echo $(git rev-parse projectA/master) > .git/MERGE_HEAD
echo $(git rev-parse projectB/master) >> .git/MERGE_HEAD
# And finally do the commit:
git commit
Итак, каждый раз:
- вы довольны тем, что вы в итоге (с точки зрения рабочего дерева и индекса)
- Вы не удовлетворены всеми коммитами, которые потребовали вас, чтобы попасть туда:
git reset --soft
- это ответ.