1
1
const nodegit = require ( 'nodegit' ) ;
2
- const path = require ( 'path' ) ;
2
+ const promisify = require ( 'util' ) . promisify ;
3
+ const exec = promisify ( require ( 'child_process' ) . exec ) ;
3
4
4
5
// https://www.nodegit.org/api/object/#TYPE
5
6
// Object.TYPE.ANY -2
@@ -15,7 +16,7 @@ const path = require('path');
15
16
16
17
/**
17
18
* Nodegit entries 获取目录
18
- * @param {Object } treeWalker
19
+ * @param {Object } treeWalker
19
20
* @param {Boolean } [recursive=false] 以广度优先顺序递归地遍历树。
20
21
*/
21
22
exports . getFiles = ( treeWalker , recursive = false ) => {
@@ -67,7 +68,7 @@ exports.getFiles = (treeWalker, recursive = false) => {
67
68
* 2. 文件夹,排在第二位
68
69
* 3. 隐藏文件,排第三位
69
70
* 4. 文件,排第四位
70
- * @param {Array } tree
71
+ * @param {Array } tree
71
72
*/
72
73
exports . repoFilesSort = ( tree = [ ] ) => {
73
74
const hiddenFolder = tree . filter ( _item => / ^ \. / . test ( _item . name ) && / ^ ( t r e e | c o m m i t ) $ / . test ( _item . type ) ) ;
@@ -100,8 +101,68 @@ exports.getEntrysInfo = (tree = [], repo) => {
100
101
} ) ;
101
102
}
102
103
104
+ /**
105
+ * 获取所有文件,对应在Tree下面最新的提交信息
106
+ *
107
+ * @param {String } repoPath 仓库路径
108
+ * @param {String } branch 仓当前 ref
109
+ * @param {Array } data 目录数组
110
+ */
111
+ exports . getFilesCommitInfo = async ( repoPath , branch , data ) => {
112
+ return Promise . all ( data . map ( async ( item ) => {
113
+ const props = { ...item } ;
114
+ const commit = await this . getFileCommit ( repoPath , item . path , branch ) ;
115
+ props . message = commit . message ;
116
+ props . treehash = commit . hash ;
117
+ props . committer = commit . committer ;
118
+ return props ;
119
+ } ) ) . catch ( ( err ) => {
120
+ throw new Error ( `Can't get commit, ${ err } ` ) ;
121
+ } ) ; ;
122
+ }
123
+
124
+ /**
125
+ * 获取某个路径的提交信息
126
+ * 输出内容:https://git-scm.com/docs/git-log#_pretty_formats
127
+ * 输出commit的总数:git rev-list --all --count
128
+ * 通过hash查看内容:git --no-pager show 5b9cf7 --summary --pretty="%H"
129
+ *
130
+ * @param {String } repoPath 仓地址
131
+ * @param {String } relPath 文件在仓中的路径
132
+ * @param {String } ref ref ?= master
133
+ */
134
+ exports . getFileCommit = async ( repoPath , relPath , ref = "master" ) => {
135
+ try {
136
+ const format = '\n=>[hash]:%H\n=>[parentHashes]:%P\n=>[shortHash]:%h\n=>[treeHash]:%T\n=>[author-name]:%an\n=>[author-email]:%ae\n=>[author-relativedate]:%ar\n=>[author-timestamp]:%at\n=>[committer-name]:%cn\n=>[committer-email]:%ce\n=>[committer-relativedate]:%cr\n=>[committer-timestamp]:%ct\n=>[message]:%s' ;
137
+ const { stdout } = await exec ( `git rev-list --pretty="${ format } " --max-count=1 ${ ref } -- ${ relPath } ` , {
138
+ cwd : repoPath ,
139
+ } ) ;
140
+ const data = { } ;
141
+ stdout . split ( '\n=>' ) . forEach ( ( item ) => {
142
+ if ( / ^ \[ / . test ( item ) ) {
143
+ let key = item . match ( / [ ^ \[ ] ( [ ^ \[ ] * ) (? = \] \: ) / ig) ;
144
+ const value = item . replace ( / ^ \[ .* \] : / , '' ) ;
145
+ if ( key . length > 0 && value ) {
146
+ key = key [ 0 ] ;
147
+ if ( key && key . includes ( '-' ) ) {
148
+ key = key . split ( '-' ) ;
149
+ if ( ! data [ key [ 0 ] ] ) data [ key [ 0 ] ] = { } ;
150
+ data [ key [ 0 ] ] [ key [ 1 ] ] = value ;
151
+ } else {
152
+ data [ key ] = value ;
153
+ }
154
+ }
155
+ }
156
+ } ) ;
157
+ return data ;
158
+ } catch ( error ) {
159
+ throw new Error ( `Can't get commit, ${ error } ` ) ;
160
+ }
161
+ }
162
+
103
163
/**
104
164
* 获取每个问文件的 hash 和 message
165
+ * [弃用]: 在大仓库下性能低下
105
166
* https://github.com/nodegit/nodegit/issues/1174
106
167
* @param {Array } tree 每个文件的JSON对象
107
168
* @param {Object } repo Nodegit 仓对象
@@ -157,39 +218,8 @@ exports.getEntrysCommit = (tree = [], repo, firstCommitOnMasterSha) => {
157
218
props . sha = sha ;
158
219
}
159
220
160
- // if (item.path && (item.type === 'commit' || item.type === 'blob')) {
161
- // // https://github.com/nodegit/nodegit/issues/220
162
- // // 获取单个文件的提交
163
- // const walker = await repo.createRevWalk();
164
- // walker.push(firstCommitOnMasterSha);
165
- // walker.sorting(nodegit.Revwalk.SORT.Time);
166
- // const history = await walker.fileHistoryWalk(item.path, 500);
167
- // history.forEach((entry, index) => {
168
- // const commit = entry.commit;
169
- // if (index === 0) {
170
- // props.author = {};
171
- // props.author.name = commit.author().name();
172
- // props.author.email = commit.author().email();
173
- // props.message = commit.message();
174
- // props.sha = commit.sha();
175
- // props.time = commit.time();
176
- // }
177
- // });
178
- // }
179
-
180
- // if (item.path === 'conf' && item.type === 'tree') {
181
- // const treeEntrys = await repo.getTree(item.id);
182
- // const treeEntry = treeEntrys.entryByIndex(0);
183
- // const refreshIndex = await repo.refreshIndex();
184
- // const indexEntryFolder = refreshIndex.getByPath(treeEntry.path());
185
- // }
186
-
187
- // const blob = await nodegit.Blob.lookup(repo, item.id);
188
- // // const rawsize = await blob.rawsize()
189
- // // const content = await blob.content()
190
- // // const owner = await blob.owner();
191
221
return props ;
192
222
} ) ) . catch ( ( err ) => {
193
223
console . log ( 'err:getEntrysCommit:' , err ) ;
194
224
} ) ;
195
- }
225
+ }
0 commit comments