node.js 获取 Node 中最近 git 提交的哈希值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34518389/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 19:42:33  来源:igfitidea点击:

Get hash of most recent git commit in Node

node.jsgit

提问by Noah

I'd like to get the id/hash of the most recent commit on the current branch in NodeJS.

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

In NodeJS, I'd like to get the most recent id/hash, with respect to git and commits thereof.

在 NodeJS 中,我想获得关于 git 及其提交的最新 id/hash。

回答by antoine129

Short solution, no external module needed (synchronous alternative to Edin's answer):

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

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

and if you want to manually specify the root directory of the git project, use the second argument of execSyncto pass the cwdoption, like execSync('git rev-parse HEAD', {cwd: __dirname})

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

回答by edin-m

Solution #1 (git required, with callback):

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

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

Optionally, you can use execSync()to avoid the callback.

或者,您可以使用execSync()来避免回调。

Solution #2 (no git required):

解决方案#2(不需要git):

  • get contents of the file .git/HEAD
  • if the git repo is in the detached head state, the content will be the hash
  • if the git repo is on some branch, the content will be something like: "refs: refs/heads/current-branch-name"
  • get contents of .git/refs/heads/current-branch-name
  • handle all possible errors in this process
  • to get the latest hash from the master branch directly, you can get the contents of the file: .git/refs/heads/master
  • 获取文件内容 .git/HEAD
  • 如果 git repo 处于分离的头部状态,则内容将是哈希
  • 如果 git repo 在某个分支上,则内容将类似于:“refs: refs/heads/current-branch-name”
  • 获取内容 .git/refs/heads/current-branch-name
  • 处理此过程中所有可能的错误
  • 直接从master分支获取最新的hash,可以获取文件的内容: .git/refs/heads/master

This can be coded with something like:

这可以用以下代码进行编码:

const rev = fs.readFileSync('.git/HEAD').toString();
if (rev.indexOf(':') === -1) {
    return rev;
} else {
    return fs.readFileSync('.git/' + rev.substring(5)).toString();
}

回答by Paul

Using nodegit, with path_to_repodefined as a string containing the path to the repo you want to get the commit sha for. If you want to use the directory your process is running from, then replace path_to_repowith process.cwd():

使用nodegitpath_to_repo定义为一个字符串,其中包含要获取提交 sha 的存储库的路径。如果要使用运行进程的目录,请替换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
} );

回答by Bruno Bronosky

I was inspired by edin-m's "Solution #2 (no git required)", but I didn't like the substring(5)part which felt like a dangerous assumption. I feel my RegEx is much more tolerant to the variations allowed in git's loose requirements for that file.

我的灵感来自edin-m 的“解决方案 #2(不需要 git)”,但我不喜欢substring(5)感觉像是一个危险假设的部分。我觉得我的 RegEx 更能容忍 git 对该文件的松散要求中允许的变化。

The following demo shows that it works for both a checked out branch and a "detached HEAD".

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

回答by erg

Here's a version I worked up that uses fs.promisesand async/await.

这是我开发的一个版本,它使用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();

回答by hakatashi

If you are always on specific branch, you can read .git/refs/heads/<branch_name>to easily get commit hash.

如果你总是在特定的分支上,你可以阅读.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());
});

回答by Noah

You can also use git-fs(it's name on npm is git-fs, on Github it's node-git.)

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

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

The same module can read directories and files from the repo.

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