Получить хэш из последнего git-фиксации в узле
Я хотел бы получить id/hash из последней фиксации текущей ветки в NodeJS.
В NodeJS я хотел бы получить самый последний id/хэш в отношении git и совершить его.
Ответы
Ответ 1
Решение № 1 (требуется git, с обратным вызовом):
require('child_process').exec('git rev-parse HEAD', function(err, stdout) {
console.log('Last commit hash on this branch is:', stdout);
});
При желании вы можете использовать execSync()
чтобы избежать обратного вызова.
Решение № 2 (Git не требуется):
- получить содержимое файла
.git/HEAD
- если репозиторий git находится в состоянии отсоединенной головы, содержимое будет хешем
- если репозиторий git находится в какой-либо ветке, содержимое будет выглядеть примерно так: "refs: refs/heads/current-branch-name"
- получить содержимое
.git/refs/heads/current-branch-name
- обработать все возможные ошибки в этом процессе
- Чтобы получить последний хеш из основной ветки напрямую, вы можете получить содержимое файла:
.git/refs/heads/master
Это может быть закодировано с чем-то вроде:
const rev = fs.readFileSync('.git/HEAD').toString();
if (rev.indexOf(':') === -1) {
return rev;
} else {
return fs.readFileSync('.git/' + rev.substring(5)).toString();
}
Ответ 2
Короткое решение, не требуется внешний модуль (синхронная альтернатива Edin):
revision = require('child_process')
.execSync('git rev-parse HEAD')
.toString().trim()
и если вы хотите вручную указать корневую директорию проекта git, используйте второй аргумент execSync
для передачи опции cwd
, например execSync('git rev-parse HEAD', {cwd: __dirname})
Ответ 3
Используя nodegit, с path_to_repo
определяемым как строка, содержащая путь к репо, вы хотите получить команду commit sha. Если вы хотите использовать каталог, из которого выполняется ваш процесс, а затем замените path_to_repo
на process.cwd()
:
var Git = require( 'nodegit' );
Git.Repository.open( path_to_repo ).then( function( repository ) {
return repository.getHeadCommit( );
} ).then( function ( commit ) {
return commit.sha();
} ).then( function ( hash ) {
// use 'hash' here
} );
Ответ 4
Если вы всегда находитесь в определенной ветки, вы можете прочитать .git/refs/heads/<branch_name>
чтобы легко получить хеш фиксации.
const fs = require('fs');
const util = require('util');
util.promisify(fs.readFile)('.git/refs/heads/master').then((hash) => {
console.log(hash.toString().trim());
});
Ответ 5
Вот версия, которую я разработал, которая использует fs.promises
и async/await
.
import {default as fsWithCallbacks} from 'fs';
const fs = fsWithCallbacks.promises;
const getGitId = async () => {
const gitId = await fs.readFile('.git/HEAD', 'utf8');
if (gitId.indexOf(':') === -1) {
return gitId;
}
const refPath = '.git/' + gitId.substring(5).trim();
return await fs.readFile(refPath, 'utf8');
};
const gitId = await getGitId();
Ответ 6
Я был вдохновлен edin-m "Solution # 2 (git не требуется)", но мне не понравилась часть substring(5)
которая выглядела как опасное предположение. Я чувствую, что мой RegEx гораздо более терпим к изменениям, разрешенным в требованиях Git Loose для этого файла.
Следующая демонстрация показывает, что она работает как для извлеченной ветки, так и для "отсоединенного HEAD".
$ cd /tmp
$ git init githash
Initialized empty Git repository in /private/tmp/githash/.git/
$ cd githash
$ cat > githash.js <<'EOF'
const fs = require('fs');
const git_hash = () => {
const rev = fs.readFileSync('.git/HEAD').toString().trim().split(/.*[: ]/).slice(-1)[0];
if (rev.indexOf('/') === -1) {
return rev;
} else {
return fs.readFileSync('.git/' + rev).toString().trim();
}
}
console.log(git_hash());
EOF
$ git add githash.js
$ git commit -m 'https://stackoverflow.com/a/56975550/117471'
[master (root-commit) 164b559] https://stackoverflow.com/a/56975550/117471
1 file changed, 14 insertions(+)
create mode 100644 githash.js
$ node githash.js
164b559e3b93eb4c42ff21b1e9cd9774d031bb38
$ cat .git/HEAD
ref: refs/heads/master
$ git checkout 164b559e3b93eb4c42ff21b1e9cd9774d031bb38
Note: checking out '164b559e3b93eb4c42ff21b1e9cd9774d031bb38'.
You are in 'detached HEAD' state.
$ cat .git/HEAD
164b559e3b93eb4c42ff21b1e9cd9774d031bb38
$ node githash.js
164b559e3b93eb4c42ff21b1e9cd9774d031bb38
Ответ 7
Вы также можете использовать git-fs (это имя на npm является git-fs, на Github it node-git.)
Git('path/to/repo')
Git.getHead((err, sha) => {
console.log('The hash is: ' + sha)
})
Тот же модуль может читать каталоги и файлы из репо.