Last active
April 6, 2022 12:13
-
-
Save monochromer/d2f4e79d706d14cc67ce50e57c4a520e to your computer and use it in GitHub Desktop.
git get last date commit of files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # https://stackoverflow.com/questions/32893773/how-to-git-log-with-date-time-and-file-names-in-one-line | |
| git log --pretty=%x0a%ci --name-only \ | |
| | awk ' | |
| /^$/ { dateline=!dateline; next } | |
| dateline { date=$0; next } | |
| !seen[$0]++ { print date,$0 } | |
| ' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const path = require('path') | |
| const os = require('os') | |
| const fs = require('fs') | |
| const { promisify } = require('util') | |
| const { exec } = require('child_process') | |
| const divider = '|' | |
| const pathSeparator = path.sep | |
| // Выводим список дат и файлов в формате `<файл> | <дата>` | |
| const gitCommand = ` | |
| git ls-tree -r --name-only HEAD | while read filename; do | |
| echo "$filename ${divider} $(git log -1 --format="%ad" -- $filename)" | |
| done | |
| ` | |
| async function main() { | |
| const { stdout } = await promisify(exec)(gitCommand) | |
| // создаём стуктуру вида [[<путь до файла>, <дата обновления>]] (массив массивов) | |
| const filesDataList = stdout | |
| .split(os.EOL) | |
| .map(textLine => textLine | |
| .split(divider) | |
| .map(item => item.trim()) | |
| ) | |
| .filter(fileData => { | |
| const [filePath] = fileData | |
| const pathSegments = filePath.split(pathSeparator).filter(Boolean) | |
| const tag = pathSegments[0] | |
| return [ | |
| // учитываем только файлы, находящиеся в папках статей | |
| ['html', 'css', 'js', 'tools'].includes(tag), | |
| // не учитывем файлы индексов статей, например, 'css/index.md' | |
| pathSegments.length >= 3, | |
| // исключаем файлы index.11tydata.json | |
| !filePath.includes('index.11tydata.json') | |
| ].every(Boolean) | |
| }) | |
| // возвращаем путь до папки самой статьи | |
| // например, из пути `css/active/index.md` оставляем только `css/active` | |
| .map(fileData => { | |
| const [filePath, fileDate] = fileData | |
| const [tag, articleName] = filePath.split(pathSeparator).filter(Boolean) | |
| const newFilePath = [tag, articleName].join(pathSeparator) | |
| return [newFilePath, fileDate] | |
| }) | |
| // создаём map-структуру вида { [<путь до папки статьи>]: <дата последних обновлений в статье>} | |
| const filesDataMap = filesDataList.reduce((hashMap, fileData) => { | |
| const [filePath, fileDate] = fileData | |
| hashMap[filePath] = hashMap[filePath] || [] | |
| hashMap[filePath].push(fileDate) | |
| return hashMap | |
| }, {}) | |
| Object.keys(filesDataMap).forEach(filePath => { | |
| const dates = filesDataMap[filePath].map(d => new Date(d)) | |
| filesDataMap[filePath] = new Date(Math.max(...dates)) | |
| }) | |
| Object.entries(filesDataMap).forEach((fileData) => { | |
| const [filePath, fileDate] = fileData | |
| if (!fs.existsSync(filePath)) { | |
| return | |
| } | |
| const dataFilePath = path.join(process.cwd(), filePath, 'index.11tydata.json') | |
| const indexData = (() => { | |
| try { | |
| return require(dataFilePath) | |
| } catch { | |
| return {} | |
| } | |
| })() | |
| const createDateToSave = indexData['createdAt'] ?? fileDate | |
| const savedUpdatedDate = indexData['updatedAt'] | |
| ? new Date(indexData['updatedAt']) | |
| : createDateToSave | |
| const timeDiff = 1000 * 60 * 60 | |
| const updateDateToSave = Math.abs(savedUpdatedDate - fileDate) < timeDiff | |
| ? savedUpdatedDate | |
| : fileDate | |
| const dataToSave = { | |
| updatedAt: updateDateToSave, | |
| createdAt: createDateToSave, | |
| } | |
| fs.writeFileSync(dataFilePath, JSON.stringify(dataToSave, null, 2) + '\n') | |
| }) | |
| } | |
| main() | |
| .catch(console.error) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment