.on("dblclick", ".modified-file", function (e) { var $this = $(e.currentTarget); if ($this.attr("x-status") === Git.FILE_STATUS.DELETED) { return; } FileViewController.addToWorkingSetAndSelect(Utils.getProjectRoot() + $this.attr("x-file")); });
EventEmitter.on(Events.BRACKETS_FILE_CHANGED, function (evt, file) { if (file.fullPath === Utils.getProjectRoot() + ".gitignore") { refreshIgnoreEntries().finally(function () { refreshBoth(); }); } });
function open(event) { var folder = Utils.getProjectRoot(), customCmd = Preferences.get("terminalCommand"), customArgs = Preferences.get("terminalCommandArgs"); var cmd, args, opts = { timeout: false }; cmd = customCmd; args = customArgs.split(" ").map(function (arg) { return arg.replace("$1", Cli.escapeShellArg(normalizeUncUrls(folder))); }); console.log(cmd, args, opts); return Cli.executeCommand(cmd, args, opts).catch(function (err) { if (ErrorHandler.isTimeout(err)) { // process is running after 1 second timeout so terminal is opened return; } var pathExecuted = [cmd].concat(args).join(" "); throw new Error(err + ": " + pathExecuted); }).catch(function (err) { if (event !== "retry" && ErrorHandler.contains(err, "Permission denied")) { chmodTerminalScript().catch(function (err) { throw ErrorHandler.showError(err); }).then(function () { open("retry"); }); return; } ErrorHandler.showError(err); }); }
function commitMerge() { Utils.loadPathContent(Utils.getProjectRoot() + "/.git/MERGE_MSG").then(function (msg) { handleGitCommit(msg); }).catch(function (err) { ErrorHandler.showError(err, "Merge commit failed"); }); }
function lintFile(filename) { var fullPath = Utils.getProjectRoot() + filename; return Promise.cast(CodeInspection.inspectFile(FileSystem.getFileForPath(fullPath))) .catch(function (err) { ErrorHandler.logError(err + " on CodeInspection.inspectFile for " + fullPath); }); }
function _addRemoveItemInGitignore(selectedEntry, method) { var projectRoot = Utils.getProjectRoot(), entryPath = "/" + selectedEntry.fullPath.substring(projectRoot.length), gitignoreEntry = FileSystem.getFileForPath(projectRoot + ".gitignore"); gitignoreEntry.read(function (err, content) { if (err) { Utils.consoleLog(err, "warn"); content = ""; } // use trimmed lines only var lines = content.split("\n").map(function (l) { return l.trim(); }); // clean start and end empty lines while (lines.length > 0 && !lines[0]) { lines.shift(); } while (lines.length > 0 && !lines[lines.length - 1]) { lines.pop(); } if (method === "add") { // add only when not already present if (lines.indexOf(entryPath) === -1) { lines.push(entryPath); } } else if (method === "remove") { lines = _.without(lines, entryPath); } // always have an empty line at the end of the file if (lines[lines.length - 1]) { lines.push(""); } gitignoreEntry.write(lines.join("\n"), function (err) { if (err) { return ErrorHandler.showError(err, "Failed modifying .gitignore"); } Panel.refresh(); }); }); }
function createGitIgnore() { var gitIgnorePath = Utils.getProjectRoot() + ".gitignore"; return Utils.pathExists(gitIgnorePath).then(function (exists) { if (!exists) { return Promise.cast(FileUtils.writeText(FileSystem.getFileForPath(gitIgnorePath), gitignoreTemplate)); } }); }
.on("click", ".modified-file", function (e) { var $this = $(e.currentTarget); if ($this.attr("x-status") === Git.FILE_STATUS.DELETED) { return; } CommandManager.execute(Commands.FILE_OPEN, { fullPath: Utils.getProjectRoot() + $this.attr("x-file") }); })
Git.discardFileChanges(file).then(function () { var currentProjectRoot = Utils.getProjectRoot(); DocumentManager.getAllOpenDocuments().forEach(function (doc) { if (doc.file.fullPath === currentProjectRoot + file) { Utils.reloadDoc(doc); } }); refresh(); }).catch(function (err) {
function _getCurrentFilePath(editor) { var projectRoot = Utils.getProjectRoot(), document = editor ? editor.document : DocumentManager.getCurrentDocument(), filePath = document.file.fullPath; if (filePath.indexOf(projectRoot) === 0) { filePath = filePath.substring(projectRoot.length); } return filePath; }
.then(function () { var currentProjectRoot = Utils.getProjectRoot(); var currentDoc = DocumentManager.getCurrentDocument(); if (currentDoc) { var relativePath = currentDoc.file.fullPath.substring(currentProjectRoot.length); return Git.stage(relativePath).then(function () { return handleGitCommit(); }); } });
function commitMerge() { Utils.loadPathContent(Utils.getProjectRoot() + "/.git/MERGE_MSG").then(function (msg) { handleGitCommit(msg, true); EventEmitter.once(Events.GIT_COMMITED, function () { EventEmitter.emit(Events.REFRESH_ALL); }); }).catch(function (err) { ErrorHandler.showError(err, "Merge commit failed"); }); }
return new Promise(function (resolve) { if (!Preferences.get("markModifiedInTree")) { return resolve(); } var projectRoot = Utils.getProjectRoot(); FileSystem.getFileForPath(projectRoot + ".gitignore").read(function (err, content) { if (err) { _ignoreEntries = []; return resolve(); } _ignoreEntries = _.compact(_.map(content.split("\n"), function (line) { line = line.trim(); if (!line || line.indexOf("#") === 0) { return; } var path, type = "ignore"; if (line.indexOf("/") === 0) { line = line.substring(1); path = projectRoot + line; } else if (line.indexOf("!") === 0) { type = "include"; line = line.substring(1); path = projectRoot + line; } else { path = projectRoot + "(**/)?" + line; } path = path.replace(/\\/, ""); path = path.replace(/\./, "\\."); path = "^" + path + "/?$"; path = path.replace(/\*+/g, function (match) { if (match.length === 2) { return ".*"; } if (match.length === 1) { return "[^/]*"; } }); return {regexp: new RegExp(path), type: type}; })); return resolve(); }); });
return new Promise(function (resolve) { if (!Preferences.get("markModifiedInTree")) { return resolve(); } var projectRoot = Utils.getProjectRoot(); FileSystem.getFileForPath(projectRoot + ".gitignore").read(function (err, content) { if (err) { ignoreEntries = []; return resolve(); } ignoreEntries = _.compact(_.map(content.split("\n"), function (line) { var type = "deny", isNegative, leadingSlash, regex; line = line.trim(); if (!line || line.indexOf("#") === 0) { return; } isNegative = line.indexOf("!") === 0; if (isNegative) { line = line.slice(1); type = "accept"; } if (line.indexOf("\\") === 0) { line = line.slice(1); } if (line.indexOf("/") === 0) { line = line.slice(1); leadingSlash = true; } line = line.replace(/[^*]$/, "$&**"); regex = projectRoot + (leadingSlash ? "" : "**") + line; // NOTE: We cannot use StringUtils.regexEscape() here because we don't wanna replace * regex = regex.replace(/([.?+\^$\[\]\\(){}|\-])/g, "\\$1"); regex = regex.replace(/\*\*$/g, "(.{0,})").replace(/\*\*/g, "(.+)").replace(/\*/g, "([^/]+)"); regex = "^" + regex + "$"; return {regexp: new RegExp(regex), type: type}; })); return resolve(); }); });
function refreshCurrentFile() { var currentProjectRoot = Utils.getProjectRoot(); var currentDoc = DocumentManager.getCurrentDocument(); if (currentDoc) { $gitPanel.find("tr").each(function () { var currentFullPath = currentDoc.file.fullPath, thisFile = $(this).attr("x-file"); $(this).toggleClass("selected", currentProjectRoot + thisFile === currentFullPath); }); } else { $gitPanel.find("tr").removeClass("selected"); } }
function getMergeInfo() { var baseCheck = ["MERGE_MODE", "rebase-apply"], mergeCheck = ["MERGE_HEAD", "MERGE_MSG"], rebaseCheck = ["rebase-apply/next", "rebase-apply/last", "rebase-apply/head-name"], gitFolder = Utils.getProjectRoot() + "/.git/"; return Promise.all(baseCheck.map(function (fileName) { return Utils.loadPathContent(gitFolder + fileName); })).spread(function (mergeMode, rebaseMode) { var obj = { mergeMode: mergeMode !== null, rebaseMode: rebaseMode !== null }; if (obj.mergeMode) { return Promise.all(mergeCheck.map(function (fileName) { return Utils.loadPathContent(gitFolder + fileName); })).spread(function (head, msg) { if (head) { obj.mergeHead = head.trim(); } var msgSplit = msg ? msg.trim().split(/conflicts:/i) : []; if (msgSplit[0]) { obj.mergeMessage = msgSplit[0].trim(); } if (msgSplit[1]) { obj.mergeConflicts = msgSplit[1].trim().split("\n").map(function (line) { return line.trim(); }); } return obj; }); } if (obj.rebaseMode) { return Promise.all(rebaseCheck.map(function (fileName) { return Utils.loadPathContent(gitFolder + fileName); })).spread(function (next, last, head) { if (next) { obj.rebaseNext = next.trim(); } if (last) { obj.rebaseLast = last.trim(); } if (head) { obj.rebaseHead = head.trim().substring("refs/heads/".length); } return obj; }); } return obj; }); }
function lintFile(filename) { var fullPath = Utils.getProjectRoot() + filename, codeInspectionPromise; try { codeInspectionPromise = CodeInspection.inspectFile(FileSystem.getFileForPath(fullPath)); } catch (e) { ErrorHandler.logError("CodeInspection.inspectFile failed to execute for file " + fullPath); ErrorHandler.logError(e); codeInspectionPromise = Promise.reject(e); } return Promise.cast(codeInspectionPromise); }
Main.gitControl.getGitStatus().then(function (modifiedFiles) { var openFiles = DocumentManager.getWorkingSet(), projectRoot = Utils.getProjectRoot(); openFiles.forEach(function (openFile) { var removeOpenFile = true; modifiedFiles.forEach(function (modifiedFile) { if (projectRoot + modifiedFile.file === openFile.fullPath) { removeOpenFile = false; } }); if (removeOpenFile) { DocumentManager.closeFullEditor(openFile); } }); EditorManager.focus(); });
function getDefaultRemote(allRemotes) { var defaultRemotes = Preferences.get("defaultRemotes") || {}, candidate = defaultRemotes[Utils.getProjectRoot()]; var exists = _.find(allRemotes, function (remote) { return remote.name === candidate; }); if (!exists) { candidate = null; if (allRemotes.length > 0) { candidate = _.first(allRemotes).name; } } return candidate; }
Dialogs.showModalDialogUsingTemplate(compiledTemplate).done(function (buttonId) { if (buttonId === "ok") { FileSystem.resolve(Utils.getProjectRoot() + file, function (err, fileEntry) { if (err) { ErrorHandler.showError(err, "Could not resolve file"); return; } Promise.cast(ProjectManager.deleteItem(fileEntry)) .then(function () { refresh(); }) .catch(function (err) { ErrorHandler.showError(err, "File deletion failed"); }); }); } });
return new Promise(function (resolve, reject) { // FUTURE: maybe use git commit --file=- var fileEntry = FileSystem.getFileForPath(Utils.getProjectRoot() + ".bracketsGitTemp"); Promise.cast(FileUtils.writeText(fileEntry, message)) .then(function () { args.push("-F", ".bracketsGitTemp"); return git(args); }) .then(function (res) { fileEntry.unlink(function () { resolve(res); }); }) .catch(function (err) { fileEntry.unlink(function () { reject(err); }); }); });
EventEmitter.on(Events.GIT_STATUS_RESULTS, function (files) { var projectRoot = Utils.getProjectRoot(), modifiedPaths = [], newPaths = []; files.forEach(function (entry) { var isNew = entry.status.indexOf(Git.FILE_STATUS.UNTRACKED) !== -1 || entry.status.indexOf(Git.FILE_STATUS.ADDED) !== -1; var fullPath = projectRoot + entry.file; if (isNew) { newPaths.push(fullPath); } else { modifiedPaths.push(fullPath); } }); refreshProjectFiles(modifiedPaths, newPaths); });
Git.status().then(function (modifiedFiles) { var openFiles = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES), projectRoot = Utils.getProjectRoot(); openFiles.forEach(function (openFile) { var removeOpenFile = true; modifiedFiles.forEach(function (modifiedFile) { if (projectRoot + modifiedFile.file === openFile.fullPath) { removeOpenFile = false; modifiedFile.isOpen = true; } }); if (removeOpenFile) { // check if file doesn't have any unsaved changes var doc = DocumentManager.getOpenDocumentForPath(openFile.fullPath); if (doc && doc.isDirty) { removeOpenFile = false; } } if (removeOpenFile && !reopenModified) { MainViewManager._close(MainViewManager.ALL_PANES, openFile); } }); if (reopenModified) { var filesToReopen = modifiedFiles.filter(function (modifiedFile) { return !modifiedFile.isOpen; }); filesToReopen.forEach(function (fileObj) { var fileEntry = FileSystem.getFileForPath(projectRoot + fileObj.file); MainViewManager.addToWorkingSet(MainViewManager.ACTIVE_PANE, fileEntry); }); } MainViewManager.focusActivePane(); });
Git.status().then(function (modifiedFiles) { var openFiles = DocumentManager.getWorkingSet(), projectRoot = Utils.getProjectRoot(); openFiles.forEach(function (openFile) { var removeOpenFile = true; modifiedFiles.forEach(function (modifiedFile) { if (projectRoot + modifiedFile.file === openFile.fullPath) { removeOpenFile = false; } }); if (removeOpenFile) { // check if file doesn't have any unsaved changes var doc = DocumentManager.getOpenDocumentForPath(openFile.fullPath); if (doc && doc.isDirty) { removeOpenFile = false; } } if (removeOpenFile) { DocumentManager.closeFullEditor(openFile); } }); EditorManager.focusEditor(); });
Utils.isProjectRootWritable().then(function (writable) { if (!writable) { throw new ExpectedError("Folder " + Utils.getProjectRoot() + " is not writable!"); } return Git.init().catch(function (err) { if (ErrorHandler.contains(err, "Please tell me who you are")) { var defer = Promise.defer(); EventEmitter.emit(Events.GIT_CHANGE_USERNAME, null, function () { EventEmitter.emit(Events.GIT_CHANGE_EMAIL, null, function () { Git.init().then(function (result) { defer.resolve(result); }).catch(function (err) { defer.reject(err); }); }); }); return defer.promise; } throw err; }); }).then(function () {
function getGitRoot() { var projectRoot = Utils.getProjectRoot(); return git(["rev-parse", "--show-toplevel"], { cwd: projectRoot }) .catch(function (e) { if (ErrorHandler.contains(e, "Not a git repository")) { return null; } throw e; }) .then(function (root) { if (root === null) { return root; } // paths on cygwin look a bit different // root = fixCygwinPath(root); // we know projectRoot is in a Git repo now // because --show-toplevel didn't return Not a git repository // we need to find closest .git function checkPathRecursive(path) { if (strEndsWith(path, "/")) { path = path.slice(0, -1); } Utils.consoleDebug("Checking path for .git: " + path); return new Promise(function (resolve) { // keep .git away from file tree for now // this branch of code will not run for intel xdk if (typeof brackets !== "undefined" && brackets.fs && brackets.fs.stat) { brackets.fs.stat(path + "/.git", function (err, result) { var exists = err ? false : (result.isFile() || result.isDirectory()); if (exists) { Utils.consoleDebug("Found .git in path: " + path); resolve(path); } else { Utils.consoleDebug("Failed to find .git in path: " + path); path = path.split("/"); path.pop(); path = path.join("/"); resolve(checkPathRecursive(path)); } }); return; } FileSystem.resolve(path + "/.git", function (err, item, stat) { var exists = err ? false : (stat.isFile || stat.isDirectory); if (exists) { Utils.consoleDebug("Found .git in path: " + path); resolve(path); } else { Utils.consoleDebug("Failed to find .git in path: " + path); path = path.split("/"); path.pop(); path = path.join("/"); resolve(checkPathRecursive(path)); } }); }); } return checkPathRecursive(projectRoot).then(function (path) { return path + "/"; }); }); }
return new Promise(function (resolve, reject) { opts = opts || {}; // it is possible to set a custom working directory in options // otherwise the current project root is used to execute commands if (opts.cwd) { opts.customCwd = true; } else { opts.cwd = Utils.getProjectRoot(); } // convert paths like c:/foo/bar to c:\foo\bar on windows opts.cwd = normalizePathForOs(opts.cwd); // execute commands have to be escaped, spawn does this automatically and will fail if cmd is escaped if (method === "execute") { cmd = "\"" + cmd + "\""; } // log all cli communication into console when debug mode is on if (debugOn) { var startTime = (new Date()).getTime(); console.log(extName + "cmd-" + method + ": " + (opts.customCwd ? opts.cwd + "\\" : "") + cmd + " " + args.join(" ")); } // we connect to node (promise is returned immediately if we are already connected) connectToNode().then(function (wasConnected) { var resolved = false; // nodeConnection returns jQuery deffered nodeConnection.domains["brackets-git"][method](opts.cwd, cmd, args) .fail(function (err) { // jQuery promise - .fail is fine if (!resolved) { err = sanitizeOutput(err); if (debugOn) { logDebug(startTime, wasConnected, method, "fail", err); } reject(err); } }) .then(function (out) { if (!resolved) { out = sanitizeOutput(out); if (debugOn) { logDebug(startTime, wasConnected, method, "out", out); } resolve(out); } }) .always(function () { resolved = true; }) .done(); function timeoutPromise() { if (debugOn) { logDebug(startTime, wasConnected, method, "timeout"); } var err = new Error("cmd-" + method + "-timeout: " + cmd + " " + args.join(" ")); if (!opts.timeoutExpected) { ErrorHandler.logError(err); } reject(err); resolved = true; } function timeoutCall() { setTimeout(function () { if (!resolved) { if (typeof opts.timeoutCheck === "function") { Promise.cast(opts.timeoutCheck()) .catch(function (err) { ErrorHandler.logError("timeoutCheck failed: " + opts.timeoutCheck.toString()); ErrorHandler.logError(err); }) .then(function (continueExecution) { if (continueExecution) { // check again later timeoutCall(); } else { timeoutPromise(); } }); } else { // we don't have any custom handler, so just kill the promise here // note that command WILL keep running in the background // so even when timeout occurs, operation might finish after it timeoutPromise(); } } }, opts.timeout ? (opts.timeout * 1000) : TIMEOUT_VALUE); } // when opts.timeout === false then never timeout the process if (opts.timeout !== false) { timeoutCall(); } }).catch(function (err) { // failed to connect to node for some reason ErrorHandler.showError(err, "Failed to connect to Node.js"); }); });
function cliHandler(method, cmd, args, opts, retry) { var cliId = getNextCliId(), deferred = Promise.defer(); deferredMap[cliId] = deferred; args = args || []; opts = opts || {}; var watchProgress = args.indexOf("--progress") !== -1; // it is possible to set a custom working directory in options // otherwise the current project root is used to execute commands if (!opts.cwd) { opts.cwd = Preferences.get("currentGitRoot") || Utils.getProjectRoot(); } // convert paths like c:/foo/bar to c:\foo\bar on windows opts.cwd = normalizePathForOs(opts.cwd); // log all cli communication into console when debug mode is on if (debugOn) { var startTime = (new Date()).getTime(); Utils.consoleDebug("cmd-" + method + (watchProgress ? "-watch" : "") + ": " + opts.cwd + " -> " + cmd + " " + args.join(" ")); } // we connect to node (promise is returned immediately if we are already connected) connectToNode().catch(function (err) { // failed to connect to node for some reason throw ErrorHandler.showError(new ExpectedError(err), Strings.ERROR_CONNECT_NODEJS); }).then(function (wasConnected) { var resolved = false, timeoutLength = opts.timeout ? (opts.timeout * 1000) : TIMEOUT_VALUE; var domainOpts = { cliId: cliId, watchProgress: watchProgress }; var debugInfo = { startTime: startTime, wasConnected: wasConnected }; if (watchProgress) { deferred.progress("Running command: git " + args.join(" ")); } // nodeConnection returns jQuery deferred nodeConnection.domains[domainName][method](opts.cwd, cmd, args, domainOpts) .fail(function (err) { // jQuery promise - .fail is fine if (!resolved) { err = sanitizeOutput(err); if (debugOn) { logDebug(domainOpts, debugInfo, method, "fail", err); } delete deferredMap[cliId]; err = ErrorHandler.toError(err); // socket was closed so we should try this once again (if not already retrying) if (err.stack && err.stack.indexOf("WebSocket.self._ws.onclose") !== -1 && !retry) { cliHandler(method, cmd, args, opts, true) .then(function (response) { deferred.resolve(response); }) .catch(function (err) { deferred.reject(err); }); return; } deferred.reject(err); } }) .then(function (out) { if (!resolved) { out = sanitizeOutput(out); if (debugOn) { logDebug(domainOpts, debugInfo, method, "out", out); } delete deferredMap[cliId]; deferred.resolve(out); } }) .always(function () { resolved = true; }) .done(); function timeoutPromise() { if (debugOn) { logDebug(domainOpts, debugInfo, method, "timeout"); } var err = new Error("cmd-" + method + "-timeout: " + cmd + " " + args.join(" ")); if (!opts.timeoutExpected) { ErrorHandler.logError(err); } // process still lives and we need to kill it nodeConnection.domains[domainName].kill(domainOpts.cliId) .fail(function (err) { ErrorHandler.logError(err); }); delete deferredMap[cliId]; deferred.reject(ErrorHandler.toError(err)); resolved = true; } var lastProgressTime = 0; function timeoutCall() { setTimeout(function () { if (!resolved) { if (typeof opts.timeoutCheck === "function") { Promise.cast(opts.timeoutCheck()) .catch(function (err) { ErrorHandler.logError("timeoutCheck failed: " + opts.timeoutCheck.toString()); ErrorHandler.logError(err); }) .then(function (continueExecution) { if (continueExecution) { // check again later timeoutCall(); } else { timeoutPromise(); } }); } else if (domainOpts.watchProgress) { // we are watching the promise progress in the domain // so we should check if the last message was sent in more than timeout time var currentTime = (new Date()).getTime(); var diff = currentTime - lastProgressTime; if (diff > timeoutLength) { if (debugOn) { Utils.consoleDebug("cmd(" + cliId + ") - last progress message was sent " + diff + "ms ago - timeout"); } timeoutPromise(); } else { if (debugOn) { Utils.consoleDebug("cmd(" + cliId + ") - last progress message was sent " + diff + "ms ago - delay"); } timeoutCall(); } } else { // we don't have any custom handler, so just kill the promise here // note that command WILL keep running in the background // so even when timeout occurs, operation might finish after it timeoutPromise(); } } }, timeoutLength); } // when opts.timeout === false then never timeout the process if (opts.timeout !== false) { // if we are watching for progress events, mark the time when last progress was made if (domainOpts.watchProgress) { deferred.promise.progressed(function () { lastProgressTime = (new Date()).getTime(); }); } // call the method which will timeout the promise after a certain period of time timeoutCall(); } }).catch(function (err) { throw ErrorHandler.showError(err, "Unexpected error in CLI handler - close all instances of Brackets and start again to reload"); }); return deferred.promise; }
return Git.getGitRoot().then(function (gitRoot) { var projectRoot = Utils.getProjectRoot(), isRepositoryRootOrChild = gitRoot && projectRoot.indexOf(gitRoot) === 0; $gitBranchName.parent().toggle(isRepositoryRootOrChild); if (!isRepositoryRootOrChild) { Preferences.set("currentGitRoot", projectRoot); Preferences.set("currentGitSubfolder", ""); $gitBranchName .off("click") .text("not a git repo"); Panel.disable("not-repo"); return; } Preferences.set("currentGitRoot", gitRoot); Preferences.set("currentGitSubfolder", projectRoot.substring(gitRoot.length)); // we are in a .git repo so read the head addHeadToTheFileIndex(); return Git.getCurrentBranchName().then(function (branchName) { Git.getMergeInfo().then(function (mergeInfo) { if (mergeInfo.mergeMode) { branchName += "|MERGING"; } if (mergeInfo.rebaseMode) { if (mergeInfo.rebaseHead) { branchName = mergeInfo.rebaseHead; } branchName += "|REBASE"; if (mergeInfo.rebaseNext && mergeInfo.rebaseLast) { branchName += "(" + mergeInfo.rebaseNext + "/" + mergeInfo.rebaseLast + ")"; } } EventEmitter.emit(Events.REBASE_MERGE_MODE, mergeInfo.rebaseMode, mergeInfo.mergeMode); var MAX_LEN = 20; $gitBranchName .text(branchName.length > MAX_LEN ? branchName.substring(0, MAX_LEN) + "\u2026" : branchName) .attr("title", branchName.length > MAX_LEN ? branchName : null) .off("click") .on("click", toggleDropdown) .append($("<span class='dropdown-arrow' />")); Panel.enable(); }).catch(function (err) { ErrorHandler.showError(err, "Reading .git state failed"); }); }).catch(function (ex) { if (ErrorHandler.contains(ex, "unknown revision")) { $gitBranchName .off("click") .text("no branch"); Panel.enable(); } else { throw ex; } }); }).catch(function (err) {
var readMergeMessage = function () { return Utils.loadPathContent(Utils.getProjectRoot() + "/.git/MERGE_MSG").then(function (msg) { return msg; }); };