Я бы хотел получить только коммиты branchA
, отсутствующие в его базе branchB
.
Например, рассмотрим эту историю:
B1 - B2 - B3 - B4 - B5
\
A1 - A2 - A3
Я бы хотел получить только A1
, A2
и A3
.
Важно отметить, что я заранее не знаю, какой коммит A1
и сколько коммитов мне нужно получить.
Мой вклад - это просто главы двух ветвей,
в этом примере branchA=A3
и branchB=B5
.
Основываясь на таком вводе, мне нужно идентифицировать A1
и извлечь все между A1
и branchA
, и в идеале ничего больше.
В качестве альтернативы, может быть интересен выбор минимального набора коммитов, который включает A1
, A2
и A3
и достаточно информации для идентификации A1
, также может быть интересным.
Почему? В случае использования, когда мне нужны только эти коммиты («что изменилось в branchA
относительно branchB
), выборка большего количества необходимых коммитов замедляет мой процесс. Возьмите, например, большой репозиторий с тысячами коммитов и ветвями функций только с несколькими коммитами. Извлечение всей истории branchA
и branchB
извлекает много коммитов, которые мне не нужны, и занимает много времени и пропускную способность сети.
Я придумал уродливый хак, который избегает извлечения полной истории, начиная с мелких клонов и постепенно подбирая все больше и больше, пока не будет найден общий коммит:
git clone --depth 1 "$repo" --branch "$branchA" shallow
cd shallow
for ((depth = 8; depth <= 1024; depth *= 2)); do
echo "trying depth $depth ..."
git fetch --depth $depth
git fetch --depth $depth origin "$branchB:$branchB"
lastrev=$(git rev-list --reverse "$branchB" | head -n1)
if git merge-base --is-ancestor "$lastrev" HEAD; then
echo "found with depth=$depth"
break
fi
done
Это работает для моего варианта использования: он выбирает достаточно большое подмножество коммитов для идентификации A1
и включает в себя коммиты до заголовка branchA
, и это быстрее, чем извлечение полной истории двух ветвей.
Есть ли лучший способ, чем этот? Я ищу чистое решение Git, но если в GitHub API есть что-то, чтобы сделать это быстрее и проще, это тоже может быть интересно.