获取Node中最新git提交的哈希值

时间:2015-12-29 20:17:11

标签: node.js git

我想在NodeJS中获取当前分支上最近提交的id / hash。

在NodeJS中,我想获得最新的id / hash,关于git和commits。

7 个答案:

答案 0 :(得分:88)

简短的解决方案,无需外部模块(爱丁的答案的同步替代方案):

revision = require('child_process')
  .execSync('git rev-parse HEAD')
  .toString().trim()

如果你想手动指定git项目的根目录,请使用execSync的第二个参数来传递cwd option,如execSync('git rev-parse HEAD', {cwd: __dirname})

答案 1 :(得分:37)

解决方案#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 repo处于分离头状态,则内容将是哈希
  • 如果git repo在某个分支上,则内容将类似于:“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 :(得分:13)

使用nodegit,将path_to_repo定义为包含要获取提交sha的repo路径的字符串。如果您要使用运行该流程的目录,请将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
} );

答案 3 :(得分:3)

这是我使用fs.promisesasync/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();

答案 4 :(得分:2)

如果您总是在特定分支上,则可以阅读.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 :(得分:1)

我受到edin-m's "Solution #2 (no git required)"的启发,但我不喜欢substring(5)部分,那感觉像是一个危险的假设。我觉得我的RegEx对git对该文件的宽松要求所允许的变化更加宽容。

以下演示显示了它既适用于已签出分支又适用于“分离的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

答案 6 :(得分:0)

你也可以使用git-fs(它在npm上的名字是git-fs,在Github上它是node-git。)

Git('path/to/repo')
Git.getHead((err, sha) => {
    console.log('The hash is: ' + sha)
})

同一模块可以从仓库中读取目录和文件。