Подтвердить что ты не робот

Включить сообщения о фиксации подмодуля с помощью "git log"

Предположим, у меня есть две версии в моем репозитории... каждый из них был помечен следующим образом:

  • Tag1
  • Tag2

Теперь предположим, что фиксация обновила ссылку на подмодуль, чтобы указать на новый компилятор субмодуля между 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.

4b9b3361

Ответ 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