@NotNull private Pair<String, String> getUserNameAndEmailFromGitConfig( @NotNull Project project, @NotNull VirtualFile root) throws VcsException { String name = GitConfigUtil.getValue(project, root, GitConfigUtil.USER_NAME); String email = GitConfigUtil.getValue(project, root, GitConfigUtil.USER_EMAIL); return Pair.create(name, email); }
@Nullable private VcsUser readCurrentUser(@NotNull Project project, @NotNull VirtualFile root) throws VcsException { String userName = GitConfigUtil.getValue(project, root, GitConfigUtil.USER_NAME); String userEmail = StringUtil.notNullize(GitConfigUtil.getValue(project, root, GitConfigUtil.USER_EMAIL)); return userName == null ? null : myFactory.createUser(userName, userEmail); }
/** * Setup remotes combobox. The default remote for the current branch is selected by default. * * @param project the project * @param root the git root * @param currentBranch the current branch * @param remoteCombobox the combobox to update * @param fetchUrl if true, the fetch url is shown for remotes, push otherwise */ public static void setupRemotes( final Project project, final VirtualFile root, final String currentBranch, final JComboBox remoteCombobox, final boolean fetchUrl) { try { List<GitDeprecatedRemote> remotes = GitDeprecatedRemote.list(project, root); String remote = null; if (currentBranch != null) { remote = GitConfigUtil.getValue(project, root, "branch." + currentBranch + ".remote"); } remoteCombobox.setRenderer( getGitRemoteListCellRenderer(remote, fetchUrl, remoteCombobox.getRenderer())); GitDeprecatedRemote toSelect = null; remoteCombobox.removeAllItems(); for (GitDeprecatedRemote r : remotes) { remoteCombobox.addItem(r); if (r.name().equals(remote)) { toSelect = r; } } if (toSelect != null) { remoteCombobox.setSelectedItem(toSelect); } } catch (VcsException e) { GitVcs.getInstance(project) .showErrors(Collections.singletonList(e), GitBundle.getString("pull.retrieving.remotes")); } }
@NotNull private static GitUpdater getDefaultUpdaterForBranch( @NotNull Project project, @NotNull Git git, @NotNull VirtualFile root, @NotNull Map<VirtualFile, GitBranchPair> trackedBranches, @NotNull ProgressIndicator progressIndicator, @NotNull UpdatedFiles updatedFiles) { try { GitLocalBranch branch = GitBranchUtil.getCurrentBranch(project, root); boolean rebase = false; if (branch != null) { String rebaseValue = GitConfigUtil.getValue(project, root, "branch." + branch.getName() + ".rebase"); rebase = rebaseValue != null && rebaseValue.equalsIgnoreCase("true"); } if (rebase) { return new GitRebaseUpdater( project, git, root, trackedBranches, progressIndicator, updatedFiles); } } catch (VcsException e) { LOG.info("getDefaultUpdaterForBranch branch", e); } return new GitMergeUpdater( project, git, root, trackedBranches, progressIndicator, updatedFiles); }
private void setCoreAutoCrlfAttribute(@NotNull VirtualFile aRoot) { try { GitConfigUtil.setValue( myProject, aRoot, GitConfigUtil.CORE_AUTOCRLF, GitCrlfUtil.RECOMMENDED_VALUE, "--global"); } catch (VcsException e) { // it is not critical: the user just will get the dialog again next time LOG.warn("Couldn't globally set core.autocrlf in " + aRoot, e); } }
/** * Create a file that contains the specified message * * @param root a git repository root * @param message a message to write * @return a file reference * @throws IOException if file cannot be created */ private File createMessageFile(VirtualFile root, final String message) throws IOException { // filter comment lines File file = FileUtil.createTempFile(GIT_COMMIT_MSG_FILE_PREFIX, GIT_COMMIT_MSG_FILE_EXT); file.deleteOnExit(); @NonNls String encoding = GitConfigUtil.getCommitEncoding(myProject, root); Writer out = new OutputStreamWriter(new FileOutputStream(file), encoding); try { out.write(message); } finally { out.close(); } return file; }
@Nullable public static Pair<AbstractHash, AbstractHash> getStashTop( @NotNull Project project, @NotNull VirtualFile root) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH.readLockingCommand()); GitLogParser parser = new GitLogParser(project, SHORT_HASH, SHORT_PARENTS); h.setSilent(true); h.setNoSSH(true); h.addParameters("list"); h.addParameters("-n1"); h.addParameters(parser.getPretty()); String out; h.setCharset(Charset.forName(GitConfigUtil.getLogEncoding(project, root))); out = h.run(); final List<GitLogRecord> gitLogRecords = parser.parse(out); for (GitLogRecord gitLogRecord : gitLogRecords) { ProgressManager.checkCanceled(); GitSimpleHandler h1 = new GitSimpleHandler(project, root, GitCommand.LOG); GitLogParser parser1 = new GitLogParser(project, SHORT_HASH, SHORT_PARENTS, SUBJECT); h1.setSilent(true); h1.setNoSSH(true); h1.addParameters("-n1"); h1.addParameters(parser1.getPretty()); // h1.endOptions(); h1.addParameters(gitLogRecord.getShortHash()); String out1; out1 = h1.run(); final List<GitLogRecord> gitLogRecords1 = parser1.parse(out1); assert gitLogRecords1.size() == 1; final GitLogRecord logRecord = gitLogRecords1.get(0); final String[] parentsShortHashes = logRecord.getParentsShortHashes(); String indexCommit = null; // heuristics if (parentsShortHashes.length == 2) { if (logRecord.getSubject().contains(parentsShortHashes[0])) { indexCommit = parentsShortHashes[1]; } if (logRecord.getSubject().contains(parentsShortHashes[1])) { indexCommit = parentsShortHashes[0]; } } return new Pair<AbstractHash, AbstractHash>( AbstractHash.create(gitLogRecord.getShortHash()), indexCommit == null ? null : AbstractHash.create(indexCommit)); } return null; }
@Nullable public static List<Pair<String, GitCommit>> loadStashStackAsCommits( @NotNull Project project, @NotNull VirtualFile root, SymbolicRefsI refs, final String... parameters) throws VcsException { GitSimpleHandler h = new GitSimpleHandler(project, root, GitCommand.STASH.readLockingCommand()); GitLogParser parser = new GitLogParser( project, GitLogParser.NameStatus.STATUS, SHORT_HASH, HASH, COMMIT_TIME, AUTHOR_NAME, AUTHOR_TIME, AUTHOR_EMAIL, COMMITTER_NAME, COMMITTER_EMAIL, SHORT_PARENTS, REF_NAMES, SHORT_REF_LOG_SELECTOR, SUBJECT, BODY, RAW_BODY); h.setSilent(true); h.setNoSSH(true); h.addParameters("list"); h.addParameters(parameters); h.addParameters(parser.getPretty()); String out; h.setCharset(Charset.forName(GitConfigUtil.getLogEncoding(project, root))); out = h.run(); final List<GitLogRecord> gitLogRecords = parser.parse(out); final List<Pair<String, GitCommit>> result = new ArrayList<Pair<String, GitCommit>>(); for (GitLogRecord gitLogRecord : gitLogRecords) { ProgressManager.checkCanceled(); final GitCommit gitCommit = createCommit(project, refs, root, gitLogRecord); result.add(new Pair<String, GitCommit>(gitLogRecord.getShortenedRefLog(), gitCommit)); } return result; }
@Nullable public String getDefaultMessageFor(FilePath[] filesToCheckin) { LinkedHashSet<String> messages = ContainerUtil.newLinkedHashSet(); for (VirtualFile root : GitUtil.gitRoots(Arrays.asList(filesToCheckin))) { VirtualFile mergeMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_MERGE_MSG); VirtualFile squashMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_SQUASH_MSG); try { if (mergeMsg == null && squashMsg == null) { continue; } String encoding = GitConfigUtil.getCommitEncoding(myProject, root); if (mergeMsg != null) { messages.add(loadMessage(mergeMsg, encoding)); } else { messages.add(loadMessage(squashMsg, encoding)); } } catch (IOException e) { if (log.isDebugEnabled()) { log.debug("Unable to load merge message", e); } } } return DvcsUtil.joinMessagesOrNull(messages); }
private ReturnResult checkUserName() { Project project = myPanel.getProject(); GitVcs vcs = GitVcs.getInstance(project); assert vcs != null; Collection<VirtualFile> notDefined = new ArrayList<VirtualFile>(); Map<VirtualFile, Pair<String, String>> defined = new HashMap<VirtualFile, Pair<String, String>>(); Collection<VirtualFile> allRoots = new ArrayList<VirtualFile>( Arrays.asList(ProjectLevelVcsManager.getInstance(project).getRootsUnderVcs(vcs))); Collection<VirtualFile> affectedRoots = getSelectedRoots(); for (VirtualFile root : affectedRoots) { try { Pair<String, String> nameAndEmail = getUserNameAndEmailFromGitConfig(project, root); String name = nameAndEmail.getFirst(); String email = nameAndEmail.getSecond(); if (name == null || email == null) { notDefined.add(root); } else { defined.put(root, nameAndEmail); } } catch (VcsException e) { LOG.error("Couldn't get user.name and user.email for root " + root, e); // doing nothing - let commit with possibly empty user.name/email } } if (notDefined.isEmpty()) { return ReturnResult.COMMIT; } GitVersion version = vcs.getVersion(); if (System.getenv("HOME") == null && GitVersionSpecialty.DOESNT_DEFINE_HOME_ENV_VAR.existsIn(version)) { Messages.showErrorDialog( project, "You are using Git " + version + " which doesn't define %HOME% environment variable properly.\n" + "Consider updating Git to a newer version " + "or define %HOME% to point to the place where the global .gitconfig is stored \n" + "(it is usually %USERPROFILE% or %HOMEDRIVE%%HOMEPATH%).", "HOME Variable Is Not Defined"); return ReturnResult.CANCEL; } if (defined.isEmpty() && allRoots.size() > affectedRoots.size()) { allRoots.removeAll(affectedRoots); for (VirtualFile root : allRoots) { try { Pair<String, String> nameAndEmail = getUserNameAndEmailFromGitConfig(project, root); String name = nameAndEmail.getFirst(); String email = nameAndEmail.getSecond(); if (name != null && email != null) { defined.put(root, nameAndEmail); break; } } catch (VcsException e) { LOG.error("Couldn't get user.name and user.email for root " + root, e); // doing nothing - not critical not to find the values for other roots not affected by // commit } } } GitUserNameNotDefinedDialog dialog = new GitUserNameNotDefinedDialog(project, notDefined, affectedRoots, defined); dialog.show(); if (dialog.isOK()) { try { if (dialog.isGlobal()) { GitConfigUtil.setValue( project, notDefined.iterator().next(), GitConfigUtil.USER_NAME, dialog.getUserName(), "--global"); GitConfigUtil.setValue( project, notDefined.iterator().next(), GitConfigUtil.USER_EMAIL, dialog.getUserEmail(), "--global"); } else { for (VirtualFile root : notDefined) { GitConfigUtil.setValue(project, root, GitConfigUtil.USER_NAME, dialog.getUserName()); GitConfigUtil.setValue( project, root, GitConfigUtil.USER_EMAIL, dialog.getUserEmail()); } } } catch (VcsException e) { String message = "Couldn't set user.name and user.email"; LOG.error(message, e); Messages.showErrorDialog(myPanel.getComponent(), message); return ReturnResult.CANCEL; } return ReturnResult.COMMIT; } return ReturnResult.CLOSE_WINDOW; }
/** * Unescape path returned by Git. * * <p>If there are quotes in the file name, Git not only escapes them, but also encloses the file * name into quotes: <code>"\"quote"</code> * * <p>If there are spaces in the file name, Git displays the name as is, without escaping spaces * and without enclosing name in quotes. * * @param path a path to unescape * @return unescaped path ready to be searched in the VFS or file system. * @throws com.intellij.openapi.vcs.VcsException if the path in invalid */ @NotNull public static String unescapePath(@NotNull String path) throws VcsException { final String QUOTE = "\""; if (path.startsWith(QUOTE) && path.endsWith(QUOTE)) { path = path.substring(1, path.length() - 1); } final int l = path.length(); StringBuilder rc = new StringBuilder(l); for (int i = 0; i < path.length(); i++) { char c = path.charAt(i); if (c == '\\') { //noinspection AssignmentToForLoopParameter i++; if (i >= l) { throw new VcsException("Unterminated escape sequence in the path: " + path); } final char e = path.charAt(i); switch (e) { case '\\': rc.append('\\'); break; case 't': rc.append('\t'); break; case 'n': rc.append('\n'); break; case '"': rc.append('"'); break; default: if (VcsFileUtil.isOctal(e)) { // collect sequence of characters as a byte array. // count bytes first int n = 0; for (int j = i; j < l; ) { if (VcsFileUtil.isOctal(path.charAt(j))) { n++; for (int k = 0; k < 3 && j < l && VcsFileUtil.isOctal(path.charAt(j)); k++) { //noinspection AssignmentToForLoopParameter j++; } } if (j + 1 >= l || path.charAt(j) != '\\' || !VcsFileUtil.isOctal(path.charAt(j + 1))) { break; } //noinspection AssignmentToForLoopParameter j++; } // convert to byte array byte[] b = new byte[n]; n = 0; while (i < l) { if (VcsFileUtil.isOctal(path.charAt(i))) { int code = 0; for (int k = 0; k < 3 && i < l && VcsFileUtil.isOctal(path.charAt(i)); k++) { code = code * 8 + (path.charAt(i) - '0'); //noinspection AssignmentToForLoopParameter i++; } b[n++] = (byte) code; } if (i + 1 >= l || path.charAt(i) != '\\' || !VcsFileUtil.isOctal(path.charAt(i + 1))) { break; } //noinspection AssignmentToForLoopParameter i++; } //noinspection AssignmentToForLoopParameter i--; assert n == b.length; // add them to string final String encoding = GitConfigUtil.getFileNameEncoding(); try { rc.append(new String(b, encoding)); } catch (UnsupportedEncodingException e1) { throw new IllegalStateException( "The file name encoding is unsuported: " + encoding); } } else { throw new VcsException( "Unknown escape sequence '\\" + path.charAt(i) + "' in the path: " + path); } } } else { rc.append(c); } } return rc.toString(); }