This is an automated email from the ASF dual-hosted git repository.
matthiasblaesing pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new 729f4dcb75 Git client: Enable forced pushes for configured push and
push to upstream
new 296b2bff0a Merge pull request #6823 from matthiasblaesing/git
729f4dcb75 is described below
commit 729f4dcb75e9d77c415406a8b3ca673f51933673
Author: Matthias Bläsing <[email protected]>
AuthorDate: Sat Nov 11 14:20:54 2023 +0100
Git client: Enable forced pushes for configured push and push to upstream
---
ide/git/nbproject/project.xml | 2 +-
.../modules/git/ui/fetch/BranchMapping.java | 10 ++---
.../modules/git/ui/fetch/FetchBranchesStep.java | 2 +-
.../modules/git/ui/fetch/PullBranchesStep.java | 2 +-
.../netbeans/modules/git/ui/push/PushAction.java | 2 +
.../modules/git/ui/push/PushBranchesStep.java | 8 ++--
.../netbeans/modules/git/ui/push/PushMapping.java | 36 ++++++++++------
.../modules/git/ui/push/PushToUpstreamAction.java | 49 +++++++++++++++++++++-
.../netbeans/modules/git/ui/push/PushWizard.java | 2 +-
.../modules/git/ui/selectors/Bundle.properties | 5 ++-
.../modules/git/ui/selectors/ItemSelector.java | 28 ++++++-------
.../modules/git/ui/selectors/ItemsPanel.form | 12 +++---
.../modules/git/ui/selectors/ItemsPanel.java | 12 +++---
.../org/netbeans/modules/git/utils/GitUtils.java | 7 +++-
ide/libs.git/apichanges.xml | 19 +++++++++
ide/libs.git/manifest.mf | 2 +-
.../libs/git/jgit/commands/PushCommand.java | 12 +-----
.../netbeans/libs/git/jgit/commands/PushTest.java | 4 +-
18 files changed, 143 insertions(+), 71 deletions(-)
diff --git a/ide/git/nbproject/project.xml b/ide/git/nbproject/project.xml
index 2a3a8514c8..9bc4b97802 100644
--- a/ide/git/nbproject/project.xml
+++ b/ide/git/nbproject/project.xml
@@ -53,7 +53,7 @@
<compile-dependency/>
<run-dependency>
<release-version>1</release-version>
- <specification-version>1.31</specification-version>
+ <specification-version>1.58</specification-version>
</run-dependency>
</dependency>
<dependency>
diff --git a/ide/git/src/org/netbeans/modules/git/ui/fetch/BranchMapping.java
b/ide/git/src/org/netbeans/modules/git/ui/fetch/BranchMapping.java
index 248a5fe834..08d3122e26 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/fetch/BranchMapping.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/fetch/BranchMapping.java
@@ -49,7 +49,7 @@ public class BranchMapping extends ItemSelector.Item {
this.remoteBranchName = remoteBranchName;
this.localBranch = localBranch;
this.remote = remote;
- if (isDeletion()) {
+ if (isDestructive()) {
// to remove
label = MessageFormat.format(BRANCH_DELETE_MAPPING_LABEL,
localBranch.getName(), "<font color=\"" + COLOR_REMOVED + "\">R</font>");
@@ -93,7 +93,7 @@ public class BranchMapping extends ItemSelector.Item {
}
public String getRefSpec () {
- if (isDeletion()) {
+ if (isDestructive()) {
return GitUtils.getDeletedRefSpec(localBranch);
} else {
return GitUtils.getRefSpec(remoteBranchName,
remote.getRemoteName());
@@ -125,12 +125,12 @@ public class BranchMapping extends ItemSelector.Item {
}
if(t instanceof BranchMapping) {
BranchMapping other = (BranchMapping) t;
- if (isDeletion() && other.isDeletion()) {
+ if (isDestructive() && other.isDestructive()) {
return
localBranch.getName().compareTo(other.localBranch.getName());
- } else if (isDeletion() && !other.isDeletion()) {
+ } else if (isDestructive() && !other.isDestructive()) {
// deleted branches should be at the bottom
return 1;
- } else if (!isDeletion() && other.isDeletion()) {
+ } else if (!isDestructive() && other.isDestructive()) {
// deleted branches should be at the bottom
return -1;
} else {
diff --git
a/ide/git/src/org/netbeans/modules/git/ui/fetch/FetchBranchesStep.java
b/ide/git/src/org/netbeans/modules/git/ui/fetch/FetchBranchesStep.java
index 2bb1c983e5..2fdd6a348d 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/fetch/FetchBranchesStep.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/fetch/FetchBranchesStep.java
@@ -228,7 +228,7 @@ public class FetchBranchesStep extends AbstractWizardPanel
implements WizardDesc
static String getDeletedBranchesMessage (List<BranchMapping>
selectedBranches) {
StringBuilder sb = new StringBuilder(100);
for (BranchMapping m : selectedBranches) {
- if (m.isDeletion()) {
+ if (m.isDestructive()) {
sb.append(Bundle.MSG_FetchBranchesStep_toBeDeletedBranch(m.getLocalBranch().getName())).append("<br>");
}
}
diff --git
a/ide/git/src/org/netbeans/modules/git/ui/fetch/PullBranchesStep.java
b/ide/git/src/org/netbeans/modules/git/ui/fetch/PullBranchesStep.java
index 913669e025..4d3704b821 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/fetch/PullBranchesStep.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/fetch/PullBranchesStep.java
@@ -206,7 +206,7 @@ public class PullBranchesStep extends AbstractWizardPanel
implements WizardDescr
mergingBranch = null;
List<BranchMapping> candidates = new
ArrayList<BranchMapping>(branches.getSelectedBranches().size());
for (BranchMapping mapping : branches.getSelectedBranches()) {
- if (!mapping.isDeletion()) {
+ if (!mapping.isDestructive()) {
candidates.add(mapping);
}
}
diff --git a/ide/git/src/org/netbeans/modules/git/ui/push/PushAction.java
b/ide/git/src/org/netbeans/modules/git/ui/push/PushAction.java
index 03302a8d53..89dda6cccb 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/push/PushAction.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/push/PushAction.java
@@ -190,6 +190,8 @@ public class PushAction extends SingleRepositoryAction {
"CTL_PushAction.report.outputButton.desc=Opens output with more
information",
"CTL_PushAction.report.pullButton.text=&Pull Changes",
"CTL_PushAction.report.pullButton.desc=Fetch and merge remote
changes.",
+ "CTL_PushAction.report.forceButton.text=&Force push",
+ "CTL_PushAction.report.forceButton.desc=Force push local branch to
remote.",
"LBL_PushAction.report.error.title=Git Push Failed",
"MSG_PushAction.pullingChanges=Waiting for pull to finish",
"LBL_PushAction.pullingChanges.finished=Remote Changes Pulled",
diff --git a/ide/git/src/org/netbeans/modules/git/ui/push/PushBranchesStep.java
b/ide/git/src/org/netbeans/modules/git/ui/push/PushBranchesStep.java
index 42c0320763..4925ef2ac2 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/push/PushBranchesStep.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/push/PushBranchesStep.java
@@ -80,7 +80,7 @@ public class PushBranchesStep extends AbstractWizardPanel
implements WizardDescr
} else if (isDeleteUpdateConflict(localObjects.getSelectedBranches()))
{
setValid(false, new
Message(NbBundle.getMessage(PushBranchesStep.class,
"MSG_PushBranchesPanel.errorMixedSeletion"), false)); //NOI18N
} else {
- String msgDeletedBranches =
getDeletedBranchesMessage(localObjects.getSelectedBranches());
+ String msgDeletedBranches =
getDestructiveActionMessage(localObjects.getSelectedBranches());
if (msgDeletedBranches != null) {
setValid(true, new Message(msgDeletedBranches, true));
}
@@ -232,10 +232,10 @@ public class PushBranchesStep extends AbstractWizardPanel
implements WizardDescr
return localObjects.getSelectedBranches();
}
- public static String getDeletedBranchesMessage (List<PushMapping>
selectedObjects) {
+ private static String getDestructiveActionMessage (List<PushMapping>
selectedObjects) {
StringBuilder sb = new StringBuilder(100);
for (PushMapping m : selectedObjects) {
- if (m.isDeletion()) {
+ if (m.isDestructive()) {
sb.append(m.getInfoMessage()).append("<br>");
}
}
@@ -251,7 +251,7 @@ public class PushBranchesStep extends AbstractWizardPanel
implements WizardDescr
Set<String> toDelete = new HashSet<String>(selectedObjects.size());
Set<String> toUpdate = new HashSet<String>(selectedObjects.size());
for (PushMapping m : selectedObjects) {
- if (m.isDeletion()) {
+ if (m.isDestructive() && m.getLocalName() != null) {
toDelete.add(m.getRemoteName());
} else {
toUpdate.add(m.getRemoteName());
diff --git a/ide/git/src/org/netbeans/modules/git/ui/push/PushMapping.java
b/ide/git/src/org/netbeans/modules/git/ui/push/PushMapping.java
index ebdbedf766..fa9006173e 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/push/PushMapping.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/push/PushMapping.java
@@ -46,7 +46,7 @@ public abstract class PushMapping extends ItemSelector.Item {
private static final String COLOR_CONFLICT =
GitUtils.getColorString(AnnotationColorProvider.getInstance().CONFLICT_FILE.getActualColor());
protected PushMapping (String localName, String localId, String
remoteName, boolean conflict, boolean preselected, boolean updateNeeded) {
- super(preselected, localName == null);
+ super(preselected, localName == null || conflict);
this.localName = localName;
this.remoteName = remoteName == null ? localName : remoteName;
if (localName == null) {
@@ -125,13 +125,13 @@ public abstract class PushMapping extends
ItemSelector.Item {
}
if (t instanceof PushMapping) {
PushMapping other = (PushMapping) t;
- if (isDeletion() && other.isDeletion()) {
+ if (isDestructive() && other.isDestructive()) {
return remoteName.compareTo(other.remoteName);
- } else if (isDeletion() && !other.isDeletion()) {
- // deleted branches should be at the bottom
+ } else if (isDestructive() && !other.isDestructive()) {
+ // destructive changes should be at the bottom
return 1;
- } else if (!isDeletion() && other.isDeletion()) {
- // deleted branches should be at the bottom
+ } else if (!isDestructive() && other.isDestructive()) {
+ // destructive changes should be at the bottom
return -1;
} else {
return localName.compareTo(other.localName);
@@ -197,23 +197,33 @@ public abstract class PushMapping extends
ItemSelector.Item {
@Override
public String getRefSpec () {
- if (isDeletion()) {
+ if (isDestructive() && getLocalName() == null) {
return GitUtils.getPushDeletedRefSpec(remoteBranchName);
} else {
- return GitUtils.getPushRefSpec(localBranch.getName(),
remoteBranchName == null ? localBranch.getName() : remoteBranchName);
+ return GitUtils.getPushRefSpec(
+ localBranch.getName(),
+ remoteBranchName == null ? localBranch.getName() :
remoteBranchName,
+ isDestructive()
+ );
}
}
@Override
@NbBundle.Messages({
"# {0} - branch name",
- "MSG_PushMapping.toBeDeletedBranch=Branch {0} will be permanently
removed from the remote repository."
+ "MSG_PushMapping.toBeDeletedBranch=Branch {0} will be permanently
removed from the remote repository.",
+ "# {0} - branch name",
+ "MSG_PushMapping.toBeForcepushedBranch=Branch {0} will be force
pushed to the remote repository."
})
String getInfoMessage () {
- if (isDeletion()) {
+ if (isDestructive() && getLocalName() == null) {
return
Bundle.MSG_PushMapping_toBeDeletedBranch(remoteBranchName);
} else {
- return super.getInfoMessage();
+ if(isDestructive()) {
+ return
Bundle.MSG_PushMapping_toBeForcepushedBranch(remoteBranchName);
+ } else {
+ return super.getInfoMessage();
+ }
}
}
@@ -255,7 +265,7 @@ public abstract class PushMapping extends ItemSelector.Item
{
@Override
public String getRefSpec() {
- if (isDeletion()) {
+ if (isDestructive() && !isUpdate) {
//get command for tag deletion
return GitUtils.getPushDeletedTagRefSpec(remoteTagName);
} else {
@@ -269,7 +279,7 @@ public abstract class PushMapping extends ItemSelector.Item
{
"MSG_PushMapping.toBeDeletedTag=Tag {0} will be permanently
removed from the remote repository."
})
String getInfoMessage() {
- if (isDeletion()) {
+ if (isDestructive() && !isUpdate) {
return Bundle.MSG_PushMapping_toBeDeletedTag(remoteTagName);
} else {
return super.getInfoMessage();
diff --git
a/ide/git/src/org/netbeans/modules/git/ui/push/PushToUpstreamAction.java
b/ide/git/src/org/netbeans/modules/git/ui/push/PushToUpstreamAction.java
index d2e5473f75..aeaf42541f 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/push/PushToUpstreamAction.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/push/PushToUpstreamAction.java
@@ -24,8 +24,12 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import org.netbeans.libs.git.GitBranch;
+import org.netbeans.libs.git.GitException;
import org.netbeans.libs.git.GitRemoteConfig;
+import org.netbeans.libs.git.GitRevisionInfo;
import org.netbeans.modules.git.Git;
import org.netbeans.modules.git.client.GitProgressSupport;
import org.netbeans.modules.git.ui.actions.MultipleRepositoryAction;
@@ -36,11 +40,14 @@ import org.openide.awt.ActionID;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;
+
import static org.netbeans.modules.git.ui.push.Bundle.*;
+
import org.netbeans.modules.git.ui.repository.RepositoryInfo.PushMode;
import org.netbeans.modules.git.utils.GitUtils;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
+import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.util.RequestProcessor;
import org.openide.util.RequestProcessor.Task;
@@ -102,6 +109,7 @@ public class PushToUpstreamAction extends
MultipleRepositoryAction {
List<String> fetchSpecs = cfg.getFetchRefSpecs();
String remoteBranchName;
String trackedBranchId = null;
+ boolean conflicted = false;
if (trackedBranch == null) {
if (shallCreateNewBranch(activeBranch)) {
remoteBranchName = activeBranch.getName();
@@ -115,8 +123,28 @@ public class PushToUpstreamAction extends
MultipleRepositoryAction {
GitUtils.notifyError(errorLabel,
MSG_Err_unknownRemoteBranchName(trackedBranch.getName()));
return;
}
+
+ try {
+ GitBranch remoteBranch = getClient()
+ .listRemoteBranches(uri, getProgressMonitor())
+ .get(remoteBranchName);
+ GitRevisionInfo rev =
getClient().getCommonAncestor(new String[]{activeBranch.getId(),
remoteBranch.getId()}, getProgressMonitor());
+ // conflict if
+ // A) rev == null : completely unrelated commits
+ // B) ancestor is neither remote branch (opposite
means EQUAL or PUSH needed but not CONFLICT)
+ // nor local head (opposite means EQUAL or pull
needed but not CONFLICT)
+ conflicted = rev == null ||
(!remoteBranch.getId().equals(rev.getRevision()) &&
!activeBranch.getId().equals(rev.getRevision()));
+ } catch (GitException ex) {
+
Logger.getLogger(PushBranchesStep.class.getName()).log(Level.INFO,
activeBranch.getId() + ", " + remoteBranchName, ex); //NOI18N
+ }
+
+ if(conflicted) {
+ if(!shallForcePush(remoteBranchName)) {
+ return;
+ }
+ }
}
- pushMappings.add(new
PushMapping.PushBranchMapping(remoteBranchName, trackedBranchId, activeBranch,
false, false));
+ pushMappings.add(new
PushMapping.PushBranchMapping(remoteBranchName, trackedBranchId, activeBranch,
conflicted, false));
Utils.logVCSExternalRepository("GIT", uri); //NOI18N
if (!isCanceled()) {
t[0] = SystemAction.get(PushAction.class).push(repository,
uri, pushMappings,
@@ -226,5 +254,24 @@ public class PushToUpstreamAction extends
MultipleRepositoryAction {
Bundle.LBL_Push_createNewBranch(),
NotifyDescriptor.YES_NO_OPTION,
NotifyDescriptor.QUESTION_MESSAGE));
}
+
+ @NbBundle.Messages({
+ "LBL_Push.forcePush=Conflicting change",
+ "# {0} - branch name",
+ "MSG_Push.forcePush=There are conflicting changes in the target branch
\"{0}\".\n"
+ + "Do you want to abort or force push?",
+ "BTN_Push.forcePush=Force push"
+ })
+ private static boolean shallForcePush (String branchName) {
+ String push = Bundle.BTN_Push_forcePush();
+ return push == DialogDisplayer.getDefault().notify(new
NotifyDescriptor(
+ Bundle.MSG_Push_forcePush(branchName),
+ Bundle.LBL_Push_forcePush(),
+ NotifyDescriptor.YES_NO_OPTION,
+ NotifyDescriptor.QUESTION_MESSAGE,
+ new Object[] {NotifyDescriptor.CANCEL_OPTION, push},
+ NotifyDescriptor.CANCEL_OPTION
+ ));
+ }
}
diff --git a/ide/git/src/org/netbeans/modules/git/ui/push/PushWizard.java
b/ide/git/src/org/netbeans/modules/git/ui/push/PushWizard.java
index e67d624a70..761310e2db 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/push/PushWizard.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/push/PushWizard.java
@@ -169,7 +169,7 @@ class PushWizard implements ChangeListener {
Collection<PushMapping> mappings =
pushBranchesStep.getSelectedMappings();
Map<String, String> remoteBranches = new LinkedHashMap<String,
String>(mappings.size());
for (PushMapping mapping : mappings) {
- if (!mapping.isDeletion() && mapping instanceof
PushMapping.PushBranchMapping) {
+ if ((!mapping.isDestructive() || mapping.getLocalName() !=
null) && mapping instanceof PushMapping.PushBranchMapping) {
PushBranchMapping pushMapping =
(PushMapping.PushBranchMapping) mapping;
remoteBranches.put(pushMapping.getRemoteRepositoryBranchName(),
pushMapping.getLocalRepositoryBranchHeadId());
}
diff --git
a/ide/git/src/org/netbeans/modules/git/ui/selectors/Bundle.properties
b/ide/git/src/org/netbeans/modules/git/ui/selectors/Bundle.properties
index 886cb7013a..99b18ff90b 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/selectors/Bundle.properties
+++ b/ide/git/src/org/netbeans/modules/git/ui/selectors/Bundle.properties
@@ -22,5 +22,6 @@ ItemsPanel.btnSelectAll.text=Select &All
ItemsPanel.btnSelectNone.text=Select &None
ItemsPanel.btnSelectNone.TTtext=Deselect all available branches
ItemsPanel.btnSelectAll.TTtext=Select all available branches
-ItemsPanel.btnAllowDeletes.text=Enable &Deletes
-ItemsPanel.btnDisableDeletes.text=Disable &Deletes
+ItemsPanel.btnDisableDestructiveActions.text=Disable &destructive Actions
+ItemsPanel.btnAllowDestructiveActions.text=Enable &destructive Actions
+ItemsPanel.btnAllowDestructiveActions.description=Enable/Disable destructive
actions like deletes and force pushes
diff --git
a/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemSelector.java
b/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemSelector.java
index 4587dead1e..9cd6183b11 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemSelector.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemSelector.java
@@ -56,7 +56,7 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
public ItemSelector(String title) {
panel = new ItemsPanel();
- panel.btnAllowDeletes.setVisible(false);
+ panel.btnAllowDestructiveActions.setVisible(false);
Mnemonics.setLocalizedText(panel.titleLabel, title);
panel.list.setCellRenderer(new ItemRenderer());
attachListeners();
@@ -79,8 +79,8 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
DefaultListModel<I> model = new DefaultListModel<>();
for (I i : branches) {
model.addElement(i);
- if (i.isDeletion()) {
- panel.btnAllowDeletes.setVisible(true);
+ if (i.isDestructive()) {
+ panel.btnAllowDestructiveActions.setVisible(true);
}
}
panel.list.setModel(model);
@@ -165,7 +165,7 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
selectAll(false);
}
});
- panel.btnAllowDeletes.addActionListener(new ActionListener() {
+ panel.btnAllowDestructiveActions.addActionListener(new
ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
@@ -175,7 +175,7 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
int maxItemsCount = panel.list.getModel().getSize();
for (int i = 0; i < maxItemsCount; i++) {
Item item = (Item)
panel.list.getModel().getElementAt(i);
- if (item.isDelete) {
+ if (item.isDestructive()) {
fireChange = item.isSelected;
item.isSelected = false;
}
@@ -183,9 +183,9 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
}
panel.list.repaint();
if (deletesAllowed) {
- Mnemonics.setLocalizedText(panel.btnAllowDeletes,
NbBundle.getMessage(ItemsPanel.class, "ItemsPanel.btnDisableDeletes.text"));
//NOI18N
+
Mnemonics.setLocalizedText(panel.btnAllowDestructiveActions,
NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnDisableDestructiveActions.text")); //NOI18N
} else {
- Mnemonics.setLocalizedText(panel.btnAllowDeletes,
NbBundle.getMessage(ItemsPanel.class, "ItemsPanel.btnAllowDeletes.text"));
//NOI18N
+
Mnemonics.setLocalizedText(panel.btnAllowDestructiveActions,
NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnAllowDestructiveActions.text")); //NOI18N
}
if (fireChange) {
changeSupport.fireChange();
@@ -224,7 +224,7 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
}
private boolean isSelectedStateAllowed (Item item) {
- return !item.isDelete || deletesAllowed;
+ return !item.isDestructive() || deletesAllowed;
}
public class ItemRenderer implements ListCellRenderer {
@@ -249,7 +249,7 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
renderer.setText("<html>" + item.getText() + "</html>");
renderer.setToolTipText(item.getTooltipText());
renderer.setSelected(item.isSelected);
- renderer.setEnabled(!item.isDelete || deletesAllowed);
+ renderer.setEnabled(!item.isDestructive() || deletesAllowed);
}
renderer.setBorder(isSelected ?
UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder);
return renderer;
@@ -259,18 +259,18 @@ public class ItemSelector<I extends Item> implements
ListSelectionListener {
public abstract static class Item implements Comparable<Item> {
boolean isSelected;
- private final boolean isDelete;
+ private final boolean isDestructive;
- protected Item (boolean selected, boolean delete) {
+ protected Item (boolean selected, boolean isDestructive) {
this.isSelected = selected;
- this.isDelete = delete;
+ this.isDestructive = isDestructive;
}
public abstract String getText();
public abstract String getTooltipText();
- public final boolean isDeletion () {
- return isDelete;
+ public final boolean isDestructive () {
+ return isDestructive;
}
}
diff --git a/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.form
b/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.form
index f45c271328..7add25b43f 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.form
+++ b/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.form
@@ -40,7 +40,7 @@
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
- <Component id="jScrollPane1" alignment="0" pref="360"
max="32767" attributes="0"/>
+ <Component id="jScrollPane1" alignment="0" max="32767"
attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="titleLabel" min="-2" max="-2"
attributes="0"/>
@@ -49,7 +49,7 @@
<EmptySpace max="-2" attributes="0"/>
<Component id="btnSelectNone" min="-2" max="-2"
attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
- <Component id="btnAllowDeletes" min="-2"
max="-2" attributes="0"/>
+ <Component id="btnAllowDestructiveActions"
min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@@ -70,7 +70,7 @@
<Group type="103" groupAlignment="0" attributes="0">
<Group type="103" alignment="0" groupAlignment="3"
attributes="0">
<Component id="btnSelectNone" alignment="3" min="-2"
max="-2" attributes="0"/>
- <Component id="btnAllowDeletes" alignment="3" min="-2"
max="-2" attributes="0"/>
+ <Component id="btnAllowDestructiveActions" alignment="3"
min="-2" max="-2" attributes="0"/>
</Group>
<Component id="btnSelectAll" min="-2" max="-2"
attributes="0"/>
</Group>
@@ -141,13 +141,13 @@
<AuxValue name="JavaCodeGenerator_VariableModifier"
type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
- <Component class="javax.swing.JButton" name="btnAllowDeletes">
+ <Component class="javax.swing.JButton" name="btnAllowDestructiveActions">
<Properties>
<Property name="text" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
- <ResourceString
bundle="org/netbeans/modules/git/ui/selectors/Bundle.properties"
key="ItemsPanel.btnAllowDeletes.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ <ResourceString
bundle="org/netbeans/modules/git/ui/selectors/Bundle.properties"
key="ItemsPanel.btnAllowDestructiveActions.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
</Property>
<Property name="toolTipText" type="java.lang.String"
editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
- <ResourceString
bundle="org/netbeans/modules/git/ui/selectors/Bundle.properties"
key="ItemsPanel.btnAllowDeletes.text"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
+ <ResourceString
bundle="org/netbeans/modules/git/ui/selectors/Bundle.properties"
key="ItemsPanel.btnAllowDestructiveActions.description"
replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class,
"{key}")"/>
</Property>
</Properties>
<AuxValues>
diff --git a/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.java
b/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.java
index 89716f18f0..d96760d1c9 100644
--- a/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.java
+++ b/ide/git/src/org/netbeans/modules/git/ui/selectors/ItemsPanel.java
@@ -65,8 +65,8 @@ public class ItemsPanel extends javax.swing.JPanel {
btnSelectAll.setToolTipText(org.openide.util.NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnSelectAll.TTtext")); // NOI18N
btnSelectAll.setEnabled(false);
- org.openide.awt.Mnemonics.setLocalizedText(btnAllowDeletes,
org.openide.util.NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnAllowDeletes.text")); // NOI18N
-
btnAllowDeletes.setToolTipText(org.openide.util.NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnAllowDeletes.text")); // NOI18N
+ org.openide.awt.Mnemonics.setLocalizedText(btnAllowDestructiveActions,
org.openide.util.NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnAllowDestructiveActions.text")); // NOI18N
+
btnAllowDestructiveActions.setToolTipText(org.openide.util.NbBundle.getMessage(ItemsPanel.class,
"ItemsPanel.btnAllowDestructiveActions.description")); // NOI18N
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
@@ -75,7 +75,7 @@ public class ItemsPanel extends javax.swing.JPanel {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jScrollPane1,
javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE)
+ .addComponent(jScrollPane1)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(titleLabel)
@@ -84,7 +84,7 @@ public class ItemsPanel extends javax.swing.JPanel {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnSelectNone)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(btnAllowDeletes)))
+ .addComponent(btnAllowDestructiveActions)))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
@@ -99,13 +99,13 @@ public class ItemsPanel extends javax.swing.JPanel {
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnSelectNone)
- .addComponent(btnAllowDeletes))
+ .addComponent(btnAllowDestructiveActions))
.addComponent(btnSelectAll))
.addContainerGap())
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
- final javax.swing.JButton btnAllowDeletes = new javax.swing.JButton();
+ final javax.swing.JButton btnAllowDestructiveActions = new
javax.swing.JButton();
javax.swing.JButton btnSelectAll;
javax.swing.JButton btnSelectNone;
private javax.swing.JScrollPane jScrollPane1;
diff --git a/ide/git/src/org/netbeans/modules/git/utils/GitUtils.java
b/ide/git/src/org/netbeans/modules/git/utils/GitUtils.java
index 874a9268bc..d4adf74092 100644
--- a/ide/git/src/org/netbeans/modules/git/utils/GitUtils.java
+++ b/ide/git/src/org/netbeans/modules/git/utils/GitUtils.java
@@ -835,6 +835,7 @@ public final class GitUtils {
private static final String REF_SPEC_GLOBAL_PATTERN =
"+refs/heads/*:refs/remotes/{0}/*"; //NOI18N
public static final String REF_SPEC_DEL_PREFIX = ":refs/remotes/"; //NOI18N
private static final String REF_PUSHSPEC_PATTERN =
"refs/heads/{0}:refs/heads/{1}"; //NOI18N
+ private static final String REF_PUSHSPEC_PATTERN_FORCE =
"+refs/heads/{0}:refs/heads/{1}"; //NOI18N
public static final String REF_PUSHSPEC_DEL_PREFIX = ":refs/heads/";
//NOI18N
public static final String REF_PUSHSPEC_DEL_TAG_PREFIX = ":refs/tags/";
//NOI18N
private static final String REF_TAG_PUSHSPEC_PATTERN =
"refs/tags/{0}:refs/tags/{0}"; //NOI18N
@@ -856,8 +857,10 @@ public final class GitUtils {
return MessageFormat.format(REF_SPEC_PATTERN, branchName, remoteName);
}
- public static String getPushRefSpec (String branchName, String
remoteRepositoryBranchName) {
- return MessageFormat.format(REF_PUSHSPEC_PATTERN, branchName,
remoteRepositoryBranchName);
+ public static String getPushRefSpec (String branchName, String
remoteRepositoryBranchName, boolean forceUpdate) {
+ return MessageFormat.format(forceUpdate
+ ? REF_PUSHSPEC_PATTERN_FORCE
+ : REF_PUSHSPEC_PATTERN, branchName,
remoteRepositoryBranchName);
}
public static String getPushDeletedRefSpec (String
remoteRepositoryBranchName) {
diff --git a/ide/libs.git/apichanges.xml b/ide/libs.git/apichanges.xml
index d2e84c13b2..1f90d5ae02 100644
--- a/ide/libs.git/apichanges.xml
+++ b/ide/libs.git/apichanges.xml
@@ -85,6 +85,25 @@ is the proper place.
<changes>
+ <change>
+ <api name="gitlibrary_api"/>
+ <summary>Enable forced pushing for branches</summary>
+ <version major="1" minor="58"/>
+ <date day="11" month="11" year="2023"/>
+ <author login="matthiasblaesing"/>
+ <compatibility modification="yes"/>
+ <description>
+ <ul>
+ <li>
+ PushCommand prevented forced pushes by overriding the
+ force flag in the specification. This overriding
+ behavior is removed and clients are now responsible to
+ not specify a forced push if they don't intent one.
+ </li>
+ </ul>
+ </description>
+ <class package="org.netbeans.libs.git.jgit.commands"
name="PushCommand"/>
+ </change>
<change>
<api name="gitlibrary_api"/>
<summary>API for git stash support.</summary>
diff --git a/ide/libs.git/manifest.mf b/ide/libs.git/manifest.mf
index 63052d6fcd..22429982ce 100644
--- a/ide/libs.git/manifest.mf
+++ b/ide/libs.git/manifest.mf
@@ -1,4 +1,4 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.libs.git/1
OpenIDE-Module-Localizing-Bundle: org/netbeans/libs/git/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.57
+OpenIDE-Module-Specification-Version: 1.58
diff --git
a/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/PushCommand.java
b/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/PushCommand.java
index c73a82397e..96d98b6777 100644
--- a/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/PushCommand.java
+++ b/ide/libs.git/src/org/netbeans/libs/git/jgit/commands/PushCommand.java
@@ -69,17 +69,7 @@ public class PushCommand extends TransportCommand {
protected void runTransportCommand () throws
GitException.AuthorizationException, GitException {
List<RefSpec> specs = new ArrayList<RefSpec>(pushRefSpecs.size());
for (String refSpec : pushRefSpecs) {
- // this may be extra strict. We do not allow force updates for
branches,
- // but maybe we should leave that decision on the caller
- RefSpec sp = new RefSpec(refSpec);
- String source = sp.getSource();
- String dest = sp.getDestination();
- if (source != null && Transport.REFSPEC_TAGS.matchSource(source)
- && dest != null &&
Transport.REFSPEC_TAGS.matchDestination(sp.getDestination())) {
- specs.add(sp);
- } else {
- specs.add(sp.setForceUpdate(false));
- }
+ specs.add(new RefSpec(refSpec));
}
// this will ensure that refs/remotes/abc/branch will be updated, too
List<RefSpec> fetchSpecs = new ArrayList<RefSpec>(fetchRefSpecs ==
null ? 0 : fetchRefSpecs.size());
diff --git
a/ide/libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/PushTest.java
b/ide/libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/PushTest.java
index f5ca3a7634..3d61d138db 100644
---
a/ide/libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/PushTest.java
+++
b/ide/libs.git/test/unit/src/org/netbeans/libs/git/jgit/commands/PushTest.java
@@ -250,7 +250,7 @@ public class PushTest extends AbstractGitTestCase {
write(f, "huhu2");
add(f);
id = getClient(workDir).commit(new File[] { f }, "some change before
merge", null, null, NULL_PROGRESS_MONITOR).getRevision();
- updates = getClient(workDir).push(remoteUri, Arrays.asList(new
String[] { "+refs/heads/localbranch:refs/heads/master" }),
Collections.<String>emptyList(),
NULL_PROGRESS_MONITOR).getRemoteRepositoryUpdates();
+ updates = getClient(workDir).push(remoteUri, Arrays.asList(new
String[] { "refs/heads/localbranch:refs/heads/master" }),
Collections.<String>emptyList(),
NULL_PROGRESS_MONITOR).getRemoteRepositoryUpdates();
remoteBranches = getClient(workDir).listRemoteBranches(remoteUri,
NULL_PROGRESS_MONITOR);
assertEquals(1, remoteBranches.size());
assertEquals(newid, remoteBranches.get("master").getId());
@@ -263,7 +263,7 @@ public class PushTest extends AbstractGitTestCase {
assertEquals(newid, remoteBranches.get("master").getId());
assertEquals(1, updates.size());
assertUpdate(updates.get("master"), "localbranch", "master", id,
newid, new URIish(remoteUri).toString(), Type.BRANCH,
GitRefUpdateResult.REJECTED_NONFASTFORWARD);
-
+
// if starts failing, the WA at GitTransportUpdate.(URIish uri,
TrackingRefUpdate update) should be removed
// this.result = GitRefUpdateResult.valueOf((update.getResult() ==
null ? RefUpdate.Result.NOT_ATTEMPTED : update.getResult()).name());
Transport transport =
Transport.open(getRepository(getClient(workDir)), new URIish(remoteUri));
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists