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
Get hash of most recent git commit in Node
提问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():
使用nodegit,path_to_repo定义为一个字符串,其中包含要获取提交 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
} );
回答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.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();
回答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 中读取目录和文件。

