Включить сообщения о фиксации подмодуля с помощью "git log"
Предположим, у меня есть две версии в моем репозитории... каждый из них был помечен следующим образом:
Теперь предположим, что фиксация обновила ссылку на подмодуль, чтобы указать на новый компилятор субмодуля между Tag1 и Tag2. Я запускаю следующую команду и получаю следующее:
# show commits between these two tags
git log Tag1..Tag2
commit be3d0357b93322f472e8f03285cb3e1e0592eabd
Author: James Johnston <snip>
Date: Wed Jan 25 19:42:56 2012 +0000
Updated submodule references.
В этом случае единственным изменением было обновление подмодуля. Как я могу получить компромисс субмодуля с чередованием с родительским репозиторием?
В частности, в этом примере предположим, что родительский репозиторий указывает на тег SubTag5 в подмодуле. Две коммиты позже в подмодуле являются тегами SubTag6. Показанная фиксация обновила указатель подмодуля, чтобы указать SubTag6 вместо SubTag5. То, что я хотел бы сделать, это иметь git log
, в дополнение к уже зафиксированному фиксажу напечатать оба коммодов субмодуля, которые привели субмодуль из SubTag5 в SubTag6.
Ответы
Ответ 1
Здесь простая команда bash, которая создает граф фиксации ASCII (аналогичный gitk), который чередует соответствующий подмодуль, фиксируется, когда подмодуль изменяется в суперпроекте. Он печатает полный патч для каждого фиксации, а затем использует grep для фильтрации содержимого патча, оставляя только сводные строки и изменения подмодулей.
git log --graph --oneline -U0 --submodule Tag1..Tag2 | grep -E '^[*| /\\]+([0-9a-f]{7} |Submodule |> |$)'
Он производит вывод, подобный этому:
* 854407e Update submodule
| Submodule SUB 8ebf7c8..521fc49:
| > Commit C
* 99df57c Commit B
* 79e4075 Commit A
Ответ 2
Вы можете отображать изменения подмодуля, но только при использовании git log -p
. Следующая команда показывает полный diff каждого изменения фиксации и подмодуля.
git log -p --submodule=log
Сообщения фиксации субмодуля будут перечислены следующим образом:
Submodule <submodule-name> <starting-commit>..<ending-commit>:
> Commit message 1
> Commit message 2
...
> Commit message n
Ответ 3
Если вы работаете в Windows, вы можете использовать этот PowerShell script:
function Parse-SubmoduleDiff($rawDiffLines) {
$prefix = "Subproject commit "
$oldCommitLine = $($rawDiffLines | where { $_.StartsWith("-" + $prefix) } | select -First 1)
$newCommitLine = $($rawDiffLines | where { $_.StartsWith("+" + $prefix) } | select -First 1)
if ($newCommitLine -eq $null) {
return $null
}
$oldCommit = $null
if ($oldCommitLine -ne $null) {
$oldCommit = $oldCommitLine.Substring($prefix.Length + 1)
}
$newCommit = $newCommitLine.Substring($prefix.Length + 1)
return @{ OldCommit = $oldCommit; NewCommit = $newCommit }
}
# Get the paths of all submodules
$submodulePaths = $(git submodule foreach --quiet 'echo $path')
if ($submodulePaths -eq $null) {
$submodulePaths = @()
}
# Get the log of the parent repository (only SHA1)
$log = $(git log --format="%H %P" $args)
foreach ($line in $log) {
$parts = $line.Split()
$commit = $parts[0]
$parents = $parts[1..$parts.Length]
# Print the summary for this commit
git show --format=medium --no-patch $commit
echo ""
# Can be more than one parent if it a merge
foreach ($parent in $parents) {
# List the paths that changed in this commit
$changes = $(git diff --name-only $parent $commit)
if ([System.String]::IsNullOrWhiteSpace($parent)) {
continue;
}
foreach ($path in $changes) {
if ($submodulePaths.Contains($path)) {
# if it a submodule, the diff should look like this:
# -Subproject commit 1486adc5c0c37ad3fa2f2e373e125f4000e4235f
# +Subproject commit a208e767afd0a51c961654d3693893bbb4605902
# from that we can extract the old and new submodule reference
$subDiff = $(git diff $parent $commit -- $path)
$parsed = Parse-SubmoduleDiff($subDiff)
if ($parsed -eq $null) {
continue;
}
# Now get the log between the old and new submodule commit
$oldCommit = $parsed.OldCommit
$newCommit = $parsed.NewCommit
echo "Submodule '$path'"
if ($oldCommit -ne $null) {
$range = $($oldCommit + ".." + $newCommit)
} else {
$range = $newCommit
}
git --git-dir $path/.git log $range | foreach { " | " + $_ }
echo ""
}
}
}
}
Очевидно, его можно перевести на bash для использования в Linux. Общий принцип таков:
for each commit in the parent repo
print the commit summary
for each submodule that has changed in this commit
get the old and new commit hashes of the submodule
print the log of the submodule between those commits
end for
end for