2014-09-03 5 views
5

Просматривая исходный код для brackets-git (расширение git для Brackets), я вижу, что ^! (cart bang) добавляется к хэшу фиксации при вызове git diff. См GitCli.js, line 754:Что делает каретка (^!) После фиксации фиксации при вызове git diff?

function getDiffOfFileFromCommit(hash, file) { 
    return git(["diff", "--no-ext-diff", "--no-color", hash + "^!", "--", file]); 
} 

Это приводит к следующим в командной строке, используя файл в вопрос в качестве примера:

$ git diff --no-ext-diff --no-color 1f9ea6e^! -- src/git/GitCli.js 

Я знаю, что ^ будет относиться к родителю фиксации. Что делает ^!?

+3

Существует хорошее руководство ко всем различным способам ссылки на коммиты в документах для [git rev-parse] (http://git-scm.com/docs/git-rev-parse). Интерес к этому делу я считаю: «r1 ^! Включает commit r1, но исключает всех его родителей». – Charlie

+0

Из тестирования результат кажется идентичным вызову diff с фиксацией и всеми его родителями в качестве параметров. Я не знаю, что делает git при различении нескольких деревьев (из комментариев кода, это должна быть ошибка). Может быть, это волшебство с базой слияния родителей? – knittl

ответ

5

commit^! - спецификатор диапазона, который означает: это фиксация, но ни один из ее родителей. Это эквивалентно определению: commit ^parent1 ^parent2 ^parentN.

Для сравнения это не имеет смысла (вы можете сравнить только два дерева). От тестирования команды, похоже, показаны различия между базой слияния родителей и последним родителем. Я думаю, что git (mis) интерпретирует параметры, похожие на диапазон A...B, который покажет разницу между merge-base A B и B (git diff parent1...parent2 будет производить тот же diff). Не уверен, что произойдет в случае с осьюновым слиянием.

Возможно, я ошибаюсь, это только предположения, которые я извлек из тестирования с помощью репозитория и изучения кода git (builtin/diff.c).

+1

Действительно, это задокументировано здесь: http://git-scm.com/docs/git-rev-parse – maartencls

+0

«Обозначение r1^@ означает, что все родители r1. ** r1 ^! Включают commit r1, но исключает все его родители. ** " – maartencls

+0

@maartencls: да, я знаю - см. первое предложение моего ответа. Диапазоны действительно не имеют смысла с 'git diff', так как он может работать только с конечными точками. В этом диапазоне (commit, но ни один из его родителей), в частности, не гарантируется наличие ровно двух конечных точек, поэтому git запутывается – knittl