diff --git a/git/nbproject/project.xml b/git/nbproject/project.xml --- a/git/nbproject/project.xml +++ b/git/nbproject/project.xml @@ -20,7 +20,7 @@ 1 - 1.5 + 1.7 diff --git a/git/src/org/netbeans/modules/git/GitModuleConfig.java b/git/src/org/netbeans/modules/git/GitModuleConfig.java --- a/git/src/org/netbeans/modules/git/GitModuleConfig.java +++ b/git/src/org/netbeans/modules/git/GitModuleConfig.java @@ -136,7 +136,7 @@ public void setLastCanceledCommitMessage(String message) { lastCanceledCommitMessage = message; } - + /** * @param paths collection of paths, of File.getAbsolutePath() */ diff --git a/git/src/org/netbeans/modules/git/client/GitClient.java b/git/src/org/netbeans/modules/git/client/GitClient.java --- a/git/src/org/netbeans/modules/git/client/GitClient.java +++ b/git/src/org/netbeans/modules/git/client/GitClient.java @@ -290,11 +290,15 @@ } public GitRevisionInfo commit (final File[] roots, final String commitMessage, final GitUser author, final GitUser commiter, final ProgressMonitor monitor) throws GitException { + return commit(roots, commitMessage, author, commiter, false, monitor); + } + + public GitRevisionInfo commit (final File[] roots, final String commitMessage, final GitUser author, final GitUser commiter, final boolean amend, final ProgressMonitor monitor) throws GitException { return new CommandInvoker().runMethod(new Callable() { @Override public GitRevisionInfo call () throws Exception { - return delegate.commit(roots, commitMessage, author, commiter, monitor); + return delegate.commit(roots, commitMessage, author, commiter, amend, monitor); } }, "commit", roots); //NOI18N } diff --git a/git/src/org/netbeans/modules/git/ui/commit/Bundle.properties b/git/src/org/netbeans/modules/git/ui/commit/Bundle.properties --- a/git/src/org/netbeans/modules/git/ui/commit/Bundle.properties +++ b/git/src/org/netbeans/modules/git/ui/commit/Bundle.properties @@ -72,11 +72,11 @@ CommitOptionsPanel.jLabel2.text=Commiter: CommitOptionsPanel.jLabel1.text_1=Author: CommitOptionsPanel.sighOffCheckBox.text=Add Signed-off-by line by the committer at the end of the commit log message -CommitPanel.jLabel2.text=Author: -CommitPanel.jLabel3.text=Commiter: +CommitPanel.jLabel2.text=&Author: +CommitPanel.jLabel3.text=Commi&ter: CommitPanel.recentLabel.text= CommitPanel.templatesLabel.text= -CommitPanel.messageLabel.text=Commit Message: +CommitPanel.messageLabel.text=Commit &Message: MSG_CommitForm_ErrorConflicts=You cannot commit Files with Conflicts. Edit Files and resolve Conflicts first. MSG_ERROR_NO_FILES=No files available for commit. LBL_CommitAction_CannotCommit = Cannot commit @@ -103,4 +103,6 @@ #includeInCommitAction LBL_IncludeInCommitAction_Name = &Include In Commit -LBL_IncludeInCommitAction_PopupName = Include In Commit \ No newline at end of file +LBL_IncludeInCommitAction_PopupName = Include In Commit +CommitPanel.amendCheckBox.text=Am&end Last Commit +CommitPanel.amendCheckBox.TTtext=Modifies the last commit and updates its commit message and modified files diff --git a/git/src/org/netbeans/modules/git/ui/commit/CommitAction.java b/git/src/org/netbeans/modules/git/ui/commit/CommitAction.java --- a/git/src/org/netbeans/modules/git/ui/commit/CommitAction.java +++ b/git/src/org/netbeans/modules/git/ui/commit/CommitAction.java @@ -200,6 +200,8 @@ String message = parameters.getCommitMessage(); GitUser author = parameters.getAuthor(); GitUser commiter = parameters.getCommiter(); + boolean amend = parameters.isAmend(); + Collection hooks = panel.getHooks(); try { @@ -219,7 +221,7 @@ String origMessage = message; message = beforeCommitHook(commitCandidates, hooks, message); - GitRevisionInfo info = commit(commitCandidates, message, author, commiter); + GitRevisionInfo info = commit(commitCandidates, message, author, commiter, amend); GitModuleConfig.getDefault().putRecentCommitAuthors(GitCommitParameters.getUserString(author)); GitModuleConfig.getDefault().putRecentCommiter(GitCommitParameters.getUserString(commiter)); @@ -314,11 +316,11 @@ } } - private GitRevisionInfo commit (List commitCandidates, String message, GitUser author, GitUser commiter) throws GitException { + private GitRevisionInfo commit (List commitCandidates, String message, GitUser author, GitUser commiter, boolean amend) throws GitException { try { GitRevisionInfo info = getClient().commit( state == GitRepositoryState.MERGING_RESOLVED ? new File[0] : commitCandidates.toArray(new File[commitCandidates.size()]), - message, author, commiter, getProgressMonitor()); + message, author, commiter, amend, getProgressMonitor()); printInfo(info); return info; } catch (GitException ex) { diff --git a/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.form b/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.form --- a/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.form +++ b/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.form @@ -5,7 +5,7 @@ - + @@ -17,27 +17,32 @@ - + - + - + + - + - + + + + + - + @@ -51,7 +56,7 @@ - + @@ -59,7 +64,9 @@ - + + + @@ -95,6 +102,9 @@ + + + @@ -124,6 +134,9 @@ + + + @@ -149,5 +162,22 @@ + + + + + + + + + + + + + + + + + diff --git a/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.java b/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.java --- a/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.java +++ b/git/src/org/netbeans/modules/git/ui/commit/CommitPanel.java @@ -72,6 +72,8 @@ public class CommitPanel extends javax.swing.JPanel { private final GitCommitParameters parameters; private UndoRedoSupport um; + private String headCommitMessage; + private boolean commitMessageAmended; /** Creates new form CommitPanel */ public CommitPanel(GitCommitParameters parameters, String commitMessage, String user) { @@ -121,6 +123,8 @@ List messages = parameters.getCommitMessages(); if (messages.size() > 0) { lastCommitMessage = messages.get(0); + } else { + lastCommitMessage = headCommitMessage; } } if (!lastCommitMessage.isEmpty()) { @@ -166,25 +170,37 @@ jLabel3 = new javax.swing.JLabel(); templatesLabel = parameters.getMessagesTemplateLink(messageTextArea); recentLabel = parameters.getRecentMessagesLink(messageTextArea); + amendCheckBox = new javax.swing.JCheckBox(); messageLabel.setLabelFor(messageTextArea); - messageLabel.setText(org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.messageLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(messageLabel, org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.messageLabel.text")); // NOI18N messageTextArea.setColumns(20); messageTextArea.setRows(5); jScrollPane1.setViewportView(messageTextArea); - jLabel2.setText(org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.jLabel2.text")); // NOI18N + jLabel2.setLabelFor(authorComboBox); + org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.jLabel2.text")); // NOI18N authorComboBox.setEditable(true); commiterComboBox.setEditable(true); - jLabel3.setText(org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.jLabel3.text")); // NOI18N + jLabel3.setLabelFor(commiterComboBox); + org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.jLabel3.text")); // NOI18N - templatesLabel.setText(org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.templatesLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(templatesLabel, org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.templatesLabel.text")); // NOI18N - recentLabel.setText(org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.recentLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(recentLabel, org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.recentLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(amendCheckBox, org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.amendCheckBox.text")); // NOI18N + amendCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(CommitPanel.class, "CommitPanel.amendCheckBox.TTtext")); // NOI18N + amendCheckBox.setEnabled(false); + amendCheckBox.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + amendCheckBoxActionPerformed(evt); + } + }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -193,21 +209,25 @@ .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 585, Short.MAX_VALUE) + .addComponent(jScrollPane1) .addGroup(layout.createSequentialGroup() .addComponent(messageLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 465, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 355, Short.MAX_VALUE) .addComponent(recentLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(templatesLabel)) + .addComponent(templatesLabel) + .addGap(57, 57, 57)) .addGroup(layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(authorComboBox, 0, 219, Short.MAX_VALUE) + .addComponent(authorComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel3) .addGap(18, 18, 18) - .addComponent(commiterComboBox, 0, 219, Short.MAX_VALUE))) + .addComponent(commiterComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(amendCheckBox) + .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( @@ -219,19 +239,29 @@ .addComponent(templatesLabel) .addComponent(recentLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 113, Short.MAX_VALUE) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(jLabel3) .addComponent(authorComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(commiterComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(amendCheckBox) .addContainerGap()) ); }// //GEN-END:initComponents + private void amendCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_amendCheckBoxActionPerformed + if (amendCheckBox.isSelected() && !commitMessageAmended) { + this.messageTextArea.setText(headCommitMessage); + commitMessageAmended = true; + } + }//GEN-LAST:event_amendCheckBoxActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables + javax.swing.JCheckBox amendCheckBox; final javax.swing.JComboBox authorComboBox = new javax.swing.JComboBox(); final javax.swing.JComboBox commiterComboBox = new javax.swing.JComboBox(); private javax.swing.JLabel jLabel2; @@ -247,6 +277,15 @@ return NbBundle.getMessage(CommitPanel.class, msgKey); } + public String getHeadCommitMessage() { + return headCommitMessage; + } + + public void setHeadCommitMessage(String headCommitMessage) { + this.headCommitMessage = headCommitMessage; + this.amendCheckBox.setEnabled(true); + } + private ComboBoxModel prepareUserModel (List authors, String user) { DefaultComboBoxModel model; if (authors == null) { diff --git a/git/src/org/netbeans/modules/git/ui/commit/GitCommitPanel.java b/git/src/org/netbeans/modules/git/ui/commit/GitCommitPanel.java --- a/git/src/org/netbeans/modules/git/ui/commit/GitCommitPanel.java +++ b/git/src/org/netbeans/modules/git/ui/commit/GitCommitPanel.java @@ -43,6 +43,8 @@ package org.netbeans.modules.git.ui.commit; import java.awt.EventQueue; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.io.File; import java.util.ArrayList; import java.util.Arrays; @@ -62,6 +64,7 @@ import javax.swing.ImageIcon; import javax.swing.JComponent; import org.netbeans.libs.git.GitException; +import org.netbeans.libs.git.GitRevisionInfo; import org.netbeans.libs.git.GitUser; import org.netbeans.modules.git.FileInformation; import org.netbeans.modules.git.FileInformation.Mode; @@ -124,18 +127,25 @@ } public static GitCommitPanel create(final File[] roots, final File repository, GitUser user, boolean fromGitView) { - Preferences preferences = GitModuleConfig.getDefault().getPreferences(); String lastCanceledCommitMessage = GitModuleConfig.getDefault().getLastCanceledCommitMessage(); - - DefaultCommitParameters parameters = new GitCommitParameters(preferences, lastCanceledCommitMessage, user); + + GitCommitParameters parameters = new GitCommitParameters(preferences, lastCanceledCommitMessage, user); Collection hooks = VCSHooks.getInstance().getHooks(GitHook.class); GitHookContext hooksCtx = new GitHookContext(roots, null, new GitHookContext.LogEntry[] {}); DiffProvider diffProvider = new DiffProvider(); - - return new GitCommitPanel(new GitCommitTable(), roots, repository, parameters, preferences, hooks, hooksCtx, diffProvider, fromGitView, createFilters(fromGitView)); + final GitCommitTable gitCommitTable = new GitCommitTable(); + final CommitPanel panel = parameters.getPanel(); + panel.amendCheckBox.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + gitCommitTable.setAmend(panel.amendCheckBox.isSelected()); + } + }); + return new GitCommitPanel(gitCommitTable, roots, repository, parameters, preferences, hooks, hooksCtx, diffProvider, fromGitView, createFilters(fromGitView)); } private static void disableFilters () { @@ -220,81 +230,101 @@ // merge-type commit dialog can hook into this method protected GitProgressSupport getProgressSupport (final boolean[] refreshFinished) { - return new GitProgressSupport() { - @Override - public void perform() { - try { - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - getCommitTable().setNodes(new GitFileNode[0]); - } - }); - // Ensure that cache is uptodate - FileStatusCache cache = Git.getInstance().getFileStatusCache(); - cache.refreshAllRoots(Collections.>singletonMap(repository, Arrays.asList(roots)), getProgressMonitor()); - // the realy time consuming part is over; - // no need to show the progress component, - // which only makes the dialog flicker - refreshFinished[0] = true; - File[][] split = Utils.splitFlatOthers(roots); - List fileList = new ArrayList(); - for (int c = 0; c < split.length; c++) { - File[] splitRoots = split[c]; - boolean recursive = c == 1; - if (recursive) { - File[] files = cache.listFiles(splitRoots, getAcceptedStatus()); - for (int i = 0; i < files.length; i++) { - for(int r = 0; r < splitRoots.length; r++) { - if(Utils.isAncestorOrEqual(splitRoots[r], files[i])) - { - if(!fileList.contains(files[i])) { - fileList.add(files[i]); - } - } - } - } - } else { - File[] files = GitUtils.flatten(splitRoots, getAcceptedStatus()); - for (int i= 0; i>singletonMap(repository, Arrays.asList(roots)), getProgressMonitor()); + // the realy time consuming part is over; + // no need to show the progress component, + // which only makes the dialog flicker + refreshFinished[0] = true; + File[][] split = Utils.splitFlatOthers(roots); + List fileList = new ArrayList(); + for (int c = 0; c < split.length; c++) { + File[] splitRoots = split[c]; + boolean recursive = c == 1; + if (recursive) { + File[] files = cache.listFiles(splitRoots, getAcceptedStatus()); + for (int i = 0; i < files.length; i++) { + for (int r = 0; r < splitRoots.length; r++) { + if (Utils.isAncestorOrEqual(splitRoots[r], files[i])) { + if (!fileList.contains(files[i])) { fileList.add(files[i]); } } } } - if(fileList.isEmpty()) { - return; - } - - ArrayList nodesList = new ArrayList(fileList.size()); - - Git git = Git.getInstance(); - for (Iterator it = fileList.iterator(); it.hasNext();) { - File file = it.next(); - if (repository.equals(git.getRepositoryRoot(file))) { - GitFileNode node = new GitFileNode(repository, file); - nodesList.add(node); + } else { + File[] files = GitUtils.flatten(splitRoots, getAcceptedStatus()); + for (int i = 0; i < files.length; i++) { + if (!fileList.contains(files[i])) { + fileList.add(files[i]); } } - final GitFileNode[] nodes = nodesList.toArray(new GitFileNode[nodesList.size()]); - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - getCommitTable().setNodes(nodes); - } - }); - } finally { - refreshFinished[0] = true; - EventQueue.invokeLater(new Runnable() { - @Override - public void run() { - stopProgress(); - } - }); } } - }; + if (fileList.isEmpty()) { + return true; + } + List nodesList = new ArrayList(fileList.size()); + Git git = Git.getInstance(); + for (Iterator it = fileList.iterator(); it.hasNext();) { + File file = it.next(); + if (repository.equals(git.getRepositoryRoot(file))) { + GitFileNode node = new GitFileNode(repository, file); + nodesList.add(node); + } + } + final GitFileNode[] nodes = nodesList.toArray(new GitFileNode[nodesList.size()]); + EventQueue.invokeLater(new Runnable() { + @Override + public void run() { + getCommitTable().setNodes(nodes); + } + }); + return false; + } } private EnumSet getAcceptedStatus() { diff --git a/git/src/org/netbeans/modules/git/ui/commit/GitCommitParameters.java b/git/src/org/netbeans/modules/git/ui/commit/GitCommitParameters.java --- a/git/src/org/netbeans/modules/git/ui/commit/GitCommitParameters.java +++ b/git/src/org/netbeans/modules/git/ui/commit/GitCommitParameters.java @@ -82,6 +82,7 @@ ((JTextField) panel.authorComboBox.getEditor().getEditorComponent()).getDocument().addDocumentListener(this); ((JTextField) panel.commiterComboBox.getEditor().getEditorComponent()).getDocument().addDocumentListener(this); + panel.amendCheckBox.addItemListener(this); panel.authorComboBox.addItemListener(this); panel.commiterComboBox.addItemListener(this); } @@ -120,6 +121,10 @@ public String getCommitMessage() { return ((CommitPanel) getPanel()).messageTextArea.getText(); } + + public boolean isAmend() { + return getPanel().amendCheckBox.isSelected(); + } public GitUser getAuthor() { return getUser(getPanel().authorComboBox); diff --git a/git/src/org/netbeans/modules/git/ui/commit/GitCommitTable.java b/git/src/org/netbeans/modules/git/ui/commit/GitCommitTable.java --- a/git/src/org/netbeans/modules/git/ui/commit/GitCommitTable.java +++ b/git/src/org/netbeans/modules/git/ui/commit/GitCommitTable.java @@ -57,6 +57,7 @@ public class GitCommitTable extends VCSCommitTable { private String errroMessage; + private boolean amend; public GitCommitTable() { this(true); @@ -74,6 +75,9 @@ boolean ret = false; errroMessage = null; boolean isEmpty = true; + if (amend) { + return true; + } for(GitFileNode fileNode : list) { VCSCommitOptions co = fileNode.getCommitOptions(); @@ -102,5 +106,13 @@ public String getErrorMessage() { return errroMessage; } + + public boolean isAmend() { + return amend; + } + + public void setAmend(boolean amend) { + this.amend = amend; + } }