Как определить, какие файлы были изменены между коммитами git

Как мы можем использовать go-git для создания списка всех файлов, которые изменились между двумя коммитами, аналогично git diff --name-only commit1 commit2?

Для контекста у нас есть git monorepo, который содержит единственный корень go.modфайл, но несколько приложений Go. Когда разработчики отправляют коммиты в ветку, мы хотели бы получить список всех файлов, которые изменились между двумя коммитами git (git diff --name-only), и отфильтруйте его до списка каталогов приложений, исключив некоторые каталоги. Наша конечная цель состоит в том, чтобы мы могли создавать, развертывать и тестировать только те приложения, которые были изменены в нашем монорепозитории. У нас есть сценарий bash, похожий на этот из shippable, который делает это, но мы хотели бы использовать чистый go and go-git.

1 ответ

Решение

Похоже, что change.Files() дает только имена файлов с to.Name, без путей внутри репозитория, однако change.toString() дает полный путь.

Итак, если вы хотите использовать Tree.Diff, вам нужно получить такие пути:

func getChangeName(change *object.Change) string {
        var empty = object.ChangeEntry{}
        if change.From != empty {
            return change.From.Name
        }

        return change.To.Name
}

Итак, похоже, вы можете выбрать Tree.Diff или Patch.Stats в зависимости от ваших потребностей:

    currentTree, err := commit.Tree()
    CheckIfError(err)

    prevTree, err := prevCommit.Tree()
    CheckIfError(err)

    patch, err := currentTree.Patch(prevTree)
    CheckIfError(err)
    fmt.Println("----- Patch Stats ------")

    var changedFiles []string
    for _, fileStat := range patch.Stats() {
        fmt.Println(fileStat.Name)
        changedFiles = append(changedFiles,fileStat.Name)
    }

    changes, err := currentTree.Diff(prevTree)
    CheckIfError(err)
    fmt.Println("----- Changes -----")
    for _, change := range changes {
        // Ignore deleted files
        action, err := change.Action()
        CheckIfError(err)
        if action == merkletrie.Delete {
            //fmt.Println("Skipping delete")
            continue
        }
        // Get list of involved files
        name := getChangeName(change)
        fmt.Println(name)
    }

Patch.Stats будет пропускать двоичные файлы, а Tree.Diff позволяет игнорировать удаления.

Другие вопросы по тегам