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

Noa*_*oah 40 git node.js

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

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

ant*_*129 99

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

revision = require('child_process')
  .execSync('git rev-parse HEAD')
  .toString().trim()
Run Code Online (Sandbox Code Playgroud)

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

  • @DanielSteigerwald或`git rev-parse --short HEAD` (28认同)
  • 使用`.slice(0,7);`得到短沙. (7认同)

edi*_*n-m 47

解决方案#1(需要git,带回调):

require('child_process').exec('git rev-parse HEAD', function(err, stdout) {
    console.log('Last commit hash on this branch is:', stdout);
});
Run Code Online (Sandbox Code Playgroud)

(可选)您可以使用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();
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*aul 21

使用nodegit,path_to_repo定义为包含要获取提交sha的repo路径的字符串.如果要使用运行该进程的目录,请替换path_to_repoprocess.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
} );
Run Code Online (Sandbox Code Playgroud)

  • 当时间在 10 毫秒以下的范围内时,需要多长时间真的很重要吗?特别是如果您在主程序开始时执行此操作并将其存储以供以后使用(而不是每次需要时都执行此操作)。添加另一个依赖项似乎有点矫枉过正(如果您仅用于此目的),该依赖项会引入 [*477* 更多依赖项](https://github.com/nodegit/nodegit/network/dependency#package-锁.json)。但我猜一个空的 Next.js 项目使用的数量大约相同...... (7认同)

Bru*_*sky 8

我的灵感来自edin-m 的“解决方案 #2(不需要 git)”,但我不喜欢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 '/sf/answers/3988288531/'
[master (root-commit) 164b559] /sf/answers/3988288531/
 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
Run Code Online (Sandbox Code Playgroud)


小智 6

这是我制作的一个使用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();
Run Code Online (Sandbox Code Playgroud)


hak*_*shi 5

如果您始终位于特定分支,则可以阅读.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());
});
Run Code Online (Sandbox Code Playgroud)