Skip to content

Commit e2994f9

Browse files
skyjurbugthesystem
authored andcommitted
Fix: locating file in a git submodule opens it in master git repository (#62)
Git submodules, are git repositories inside a git repository. For exampole: ``` /project .git/ config modules/ parts/ sub-project/ config parts/ sub-project/ .git <<< gitdir: ../.git/modules/parts/sub-project >>> ``` In a git-submodule the '.git' would be a file instead of directory. It works like a symbolic link and points to location of .git folder. Checkout https://git-scm.com/book/en/v2/Git-Tools-Submodules for more details about git submodules. Conflicts: src/extension.js
1 parent e5c52da commit e2994f9

File tree

1 file changed

+40
-14
lines changed

1 file changed

+40
-14
lines changed

src/extension.js

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,26 @@ var Position = VsCode.Position;
99

1010
var path = require('path');
1111
var fs = require('fs');
12-
var git = require('parse-git-config');
1312
var open = require('open');
1413
var copy = require('copy-paste').copy;
1514
var gitRev = require('git-rev-2');
1615
var findParentDir = require('find-parent-dir');
16+
var ini = require('ini');
1717

1818
const gitProvider = require('./gitProvider');
1919
const requireSelectionForLines = workspace.getConfiguration('openInGitHub').get('requireSelectionForLines');
2020

2121
function getGitProviderLink(cb, fileFsPath, lines, pr) {
22-
var cwd = workspace.rootPath;
23-
var repoDir = findParentDir.sync(workspace.rootPath, '.git') || cwd;
22+
var repoDir = findParentDir.sync(fileFsPath, '.git');
23+
if(!repoDir) {
24+
throw 'Cant locate .git repository for this file';
25+
}
2426

25-
git({
26-
cwd: repoDir
27-
}, function (err, config) {
27+
locateGitConfig(repoDir)
28+
.then(readConfigFile)
29+
.then(config => {
2830

29-
gitRev.branch(cwd, function(branchErr, branch) {
31+
gitRev.branch(repoDir, function(branchErr, branch) {
3032
var rawUri,
3133
configuredBranch,
3234
provider = null,
@@ -61,13 +63,7 @@ function getGitProviderLink(cb, fileFsPath, lines, pr) {
6163
return;
6264
}
6365

64-
let subdir = fileFsPath ? fileFsPath.substring(workspace.rootPath.length).replace(/\"/g, "") : undefined;
65-
66-
if (repoDir !== cwd) {
67-
// The workspace directory is a subdirectory of the git repo folder so we need to prepend the the nested path
68-
var repoRelativePath = cwd.replace(repoDir, "/");
69-
subdir = repoRelativePath + subdir;
70-
}
66+
let subdir = repoDir !== fileFsPath ? '/' + path.relative(repoDir, fileFsPath) : '';
7167

7268
if (pr){
7369
try {
@@ -94,7 +90,37 @@ function getGitProviderLink(cb, fileFsPath, lines, pr) {
9490
});
9591
}
9692

93+
function locateGitConfig(repoDir) {
94+
return new Promise((resolve, reject) => {
95+
fs.lstat(path.join(repoDir, '.git'), (err, stat) => {
96+
if(err) { reject(err); }
97+
if(stat.isFile()) {
98+
// .git may be a file, similar to symbolic link, containing "gitdir: <relative path to git dir>""
99+
// this happens in gitsubmodules
100+
fs.readFile(path.join(repoDir, '.git'), 'utf-8', (err, data) => {
101+
if(err) { reject(err); }
102+
var match = data.match(/gitdir: (.*)/)[1];
103+
if(!match) {
104+
reject('Unable to find gitdir in .git file');
105+
}
106+
var configPath = path.join(repoDir, match, 'config');
107+
resolve(configPath);
108+
});
109+
} else {
110+
resolve(path.join(repoDir, '.git', 'config'));
111+
}
112+
});
113+
});
114+
}
97115

116+
function readConfigFile(path) {
117+
return new Promise((resolve, reject) => {
118+
fs.readFile(path, 'utf-8', (err, data) => {
119+
if(err) { reject(err); }
120+
resolve(ini.parse(data));
121+
});
122+
});
123+
}
98124

99125
function getGitProviderLinkForFile(fileFsPath, cb) {
100126
getGitProviderLink(cb, fileFsPath);

0 commit comments

Comments
 (0)