Как я могу определить, является ли git commit родителем других коммитов? - PullRequest
1 голос
/ 08 августа 2010

Я пишу скрипт, который вносит некоторые тривиальные изменения, а затем фиксирует их в git. Поскольку это тривиальные изменения, я хочу делать git commit --amend всякий раз, когда могу сойти с рук, в частности, когда поправка не «испортит» историю других ветвей. Если поправка испортит другую ветку, я хочу вместо этого сделать стандартный git commit.

Например, если мои ветви выглядели так (а-ля "Визуализация всей истории веток" в Git GUI):

* [experimental branch] Added feature.
* [master branch] Trivial change from script
* ...

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

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

Если упрощающие предположения помогают, я всегда запускаю этот скрипт на голове мастера и использую только git в качестве локального репозитория - я нигде не извлекаю и не извлекаю изменения.

Этот сценарий написан на Ruby, поэтому я могу либо перейти в командную строку git, либо использовать привязки Ruby для git - в зависимости от того, что облегчит эту задачу.

Ответы [ 2 ]

12 голосов
/ 08 августа 2010

Просто запустите git branch --contains HEAD, чтобы получить список ветвей, которые «содержат» этот коммит.Если список пуст, этот коммит должен быть безопасным для внесения изменений.Вы также можете включить флаг -a для отображения списка локальных и удаленных ветвей.

В качестве альтернативы, вы можете сравнить вывод git rev-parse HEAD с git merge-base HEAD other-branch.Если эти идентификаторы фиксации идентичны, текущий коммит находится в истории коммитов другой ветви.

3 голосов
/ 08 августа 2010

График коммитов является односторонним: при коммите вы знаете всех его предков, но не всех его потомков.Вам придется начинать с конечных точек и возвращаться назад, пока не доберетесь до необходимого вам коммита (ов).

Использовать git rev-list [some commit] --children (по умолчанию HEAD):

$ git rev-list HEAD --children
6edbee61c87fb063700751815f0ad53907d0b7a4
aee452860ecd772b8bdcd27227e6a72e6f4435fd 6edbee61c87fb063700751815f0ad53907d0b7a4
ef8a1487b03256a489d135e76d1f0b01872f2349 aee452860ecd772b8bdcd27227e6a72e6f4435fd
6910dc5833f6cd26133e32bef40ed54cf9337017 ef8a1487b03256a489d135e76d1f0b01872f2349
bbef0da56efe048f70293bd20bad0cb37b5e84f0 6910dc5833f6cd26133e32bef40ed54cf9337017
[...]

Левый столбец - это список коммитов SHA-1 в обратном хронологическом порядке.Все, что имеет право на этот коммит - это дети (--children) этого коммита.Верхний коммит - HEAD и, следовательно, не имеет дочерних элементов.

Таким образом, если вы нашли в своем списке команду SHA-1, и она имеет что-нибудь справа, у нее есть хотя бы один дочерний элемент:

$ git rev-list --children | grep '^6910'
6910dc5833f6cd26133e32bef40ed54cf9337017 ef8a1487b03256a489d135e76d1f0b01872f2349

В приведенном выше примере commit 6910... имеет дочерний элемент, ef8a....

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...