Здесь нет необходимости git stash
. git stash
уже сохраняет полные снимки, но также и все коммиты. Без коммитов это diff. Git превращает коммит в diff, сравнивая его с другим полным снимком: что бы ни отличалось в двух снимках, это diff. Многие команды, включая git stash
, делают это много, сравнивая коммит с его родителем (-ями). Например, git cherry-pick
сравнивает выбранный коммит с его родителем, чтобы увидеть, что изменилось, и затем применяет эти изменения, где бы вы ни находились (также выполняя второй diff и используя механизм слияния).
A git commit
делает свой снимок из содержимого index , а не из того, что находится в рабочем дереве. Итак, если вы хотите новый коммит в какой-либо существующей ветви, который точно соответствует любому существующему коммиту, все, что вам нужно сделать, это удалить все в индексе и заменить все на все из какого-либо другого коммита. (Рабочее дерево подходит для поездки, чтобы вы могли видеть, что происходит.) Существует очевидный простой способ сделать это:
$ git checkout br1
$ git rm -r . # from the top level: remove everything
$ git checkout br2 -- . # extract everything from commit at tip of br2
$ git commit
Это делает новый коммит, который добавляет к кончику br1
, содержимое которого от br2
. (Необнаруженные неотслеживаемые файлы не появятся, поскольку неотслеживаемые файлы по определению отсутствуют в индексе, но следует соблюдать осторожность в отношении файлов, отслеживаемых в извлеченном коммите, которые не были отслежены в старой подсказке br1
, и наоборот.)
Существует более короткая версия того же:
$ git read-tree -m -u br2
$ git commit
, что вызывает меньший отток в рабочем дереве (иногда это важно, например, для make
): read-tree считывает фиксацию в индексе, а -u
заставляет Git обновлять работу Дерево, чтобы соответствовать. Поскольку здесь есть только один аргумент для git read-tree
, он выбрасывает текущее содержимое индекса, удаляя любой файл, который находится в нем (и в рабочем дереве), который не находится в коммите br2
. Как и в случае с более длинным вариантом, это не влияет на неотслеживаемые файлы.