@ -45,7 +45,6 @@ package org.eclipse.jgit.pgm;
import java.io.IOException ;
import java.io.IOException ;
import java.text.MessageFormat ;
import java.text.MessageFormat ;
import java.util.ArrayList ;
import java.util.Collection ;
import java.util.Collection ;
import java.util.LinkedHashMap ;
import java.util.LinkedHashMap ;
import java.util.List ;
import java.util.List ;
@ -65,15 +64,18 @@ import org.eclipse.jgit.lib.RefUpdate;
import org.eclipse.jgit.lib.RefUpdate.Result ;
import org.eclipse.jgit.lib.RefUpdate.Result ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.lib.Repository ;
import org.eclipse.jgit.pgm.internal.CLIText ;
import org.eclipse.jgit.pgm.internal.CLIText ;
import org.eclipse.jgit.pgm.opt.CmdLinePars er ;
import org.eclipse.jgit.pgm.opt.OptionWithValuesListHandl er ;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.eclipse.jgit.revwalk.RevWalk ;
import org.kohsuke.args4j.Argument ;
import org.kohsuke.args4j.Argument ;
import org.kohsuke.args4j.ExampleMode ;
import org.kohsuke.args4j.Option ;
import org.kohsuke.args4j.Option ;
@Command ( common = true , usage = "usage_listCreateOrDeleteBranches" )
@Command ( common = true , usage = "usage_listCreateOrDeleteBranches" )
class Branch extends TextBuiltin {
class Branch extends TextBuiltin {
private String otherBranch ;
private boolean createForce ;
private boolean rename ;
@Option ( name = "--remote" , aliases = { "-r" } , usage = "usage_actOnRemoteTrackingBranches" )
@Option ( name = "--remote" , aliases = { "-r" } , usage = "usage_actOnRemoteTrackingBranches" )
private boolean remote = false ;
private boolean remote = false ;
@ -83,23 +85,69 @@ class Branch extends TextBuiltin {
@Option ( name = "--contains" , metaVar = "metaVar_commitish" , usage = "usage_printOnlyBranchesThatContainTheCommit" )
@Option ( name = "--contains" , metaVar = "metaVar_commitish" , usage = "usage_printOnlyBranchesThatContainTheCommit" )
private String containsCommitish ;
private String containsCommitish ;
@Option ( name = "--delete" , aliases = { "-d" } , usage = "usage_deleteFullyMergedBranch" )
private List < String > delete ;
private boolean delete = false ;
@Option ( name = "--delete-force" , aliases = { "-D" } , usage = "usage_deleteBranchEvenIfNotMerged" )
@Option ( name = "--delete" , aliases = {
private boolean deleteForce = false ;
"-d" } , metaVar = "metaVar_branchNames" , usage = "usage_deleteFullyMergedBranch" , handler = OptionWithValuesListHandler . class )
public void delete ( List < String > names ) {
if ( names . isEmpty ( ) ) {
throw die ( CLIText . get ( ) . branchNameRequired ) ;
}
delete = names ;
}
@Option ( name = "--create-force" , aliases = { "-f" } , usage = "usage_forceCreateBranchEvenExists" )
private List < String > deleteForce ;
private boolean createForce = false ;
@Option ( name = "-m" , usage = "usage_moveRenameABranch" )
@Option ( name = "--delete-force" , aliases = {
private boolean rename = false ;
"-D" } , metaVar = "metaVar_branchNames" , usage = "usage_deleteBranchEvenIfNotMerged" , handler = OptionWithValuesListHandler . class )
public void deleteForce ( List < String > names ) {
if ( names . isEmpty ( ) ) {
throw die ( CLIText . get ( ) . branchNameRequired ) ;
}
deleteForce = names ;
}
@Option ( name = "--create-force" , aliases = {
"-f" } , metaVar = "metaVar_branchAndStartPoint" , usage = "usage_forceCreateBranchEvenExists" , handler = OptionWithValuesListHandler . class )
public void createForce ( List < String > branchAndStartPoint ) {
createForce = true ;
if ( branchAndStartPoint . isEmpty ( ) ) {
throw die ( CLIText . get ( ) . branchNameRequired ) ;
}
if ( branchAndStartPoint . size ( ) > 2 ) {
throw die ( CLIText . get ( ) . tooManyRefsGiven ) ;
}
if ( branchAndStartPoint . size ( ) = = 1 ) {
branch = branchAndStartPoint . get ( 0 ) ;
} else {
branch = branchAndStartPoint . get ( 0 ) ;
otherBranch = branchAndStartPoint . get ( 1 ) ;
}
}
@Option ( name = "--move" , aliases = {
"-m" } , metaVar = "metaVar_oldNewBranchNames" , usage = "usage_moveRenameABranch" , handler = OptionWithValuesListHandler . class )
public void moveRename ( List < String > currentAndNew ) {
rename = true ;
if ( currentAndNew . isEmpty ( ) ) {
throw die ( CLIText . get ( ) . branchNameRequired ) ;
}
if ( currentAndNew . size ( ) > 2 ) {
throw die ( CLIText . get ( ) . tooManyRefsGiven ) ;
}
if ( currentAndNew . size ( ) = = 1 ) {
branch = currentAndNew . get ( 0 ) ;
} else {
branch = currentAndNew . get ( 0 ) ;
otherBranch = currentAndNew . get ( 1 ) ;
}
}
@Option ( name = "--verbose" , aliases = { "-v" } , usage = "usage_beVerbose" )
@Option ( name = "--verbose" , aliases = { "-v" } , usage = "usage_beVerbose" )
private boolean verbose = false ;
private boolean verbose = false ;
@Argument
@Argument ( metaVar = "metaVar_name" )
private List < String > branches = new ArrayList < String > ( ) ;
private String branch ;
private final Map < String , Ref > printRefs = new LinkedHashMap < String , Ref > ( ) ;
private final Map < String , Ref > printRefs = new LinkedHashMap < String , Ref > ( ) ;
@ -110,30 +158,33 @@ class Branch extends TextBuiltin {
@Override
@Override
protected void run ( ) throws Exception {
protected void run ( ) throws Exception {
if ( delete | | deleteForce )
if ( delete ! = null | | deleteForce ! = null ) {
delete ( deleteForce ) ;
if ( delete ! = null ) {
else {
delete ( delete , false ) ;
if ( branches . size ( ) > 2 )
}
throw die ( CLIText . get ( ) . tooManyRefsGiven + new CmdLineParser ( this ) . printExample ( ExampleMode . ALL ) ) ;
if ( deleteForce ! = null ) {
delete ( deleteForce , true ) ;
}
} else {
if ( rename ) {
if ( rename ) {
String src , dst ;
String src , dst ;
if ( branches . size ( ) = = 1 ) {
if ( otherBranch = = null ) {
final Ref head = db . getRef ( Constants . HEAD ) ;
final Ref head = db . getRef ( Constants . HEAD ) ;
if ( head ! = null & & head . isSymbolic ( ) )
if ( head ! = null & & head . isSymbolic ( ) ) {
src = head . getLeaf ( ) . getName ( ) ;
src = head . getLeaf ( ) . getName ( ) ;
else
} else {
throw die ( CLIText . get ( ) . cannotRenameDetachedHEAD ) ;
throw die ( CLIText . get ( ) . cannotRenameDetachedHEAD ) ;
dst = branches . get ( 0 ) ;
}
dst = branch ;
} else {
} else {
src = branches . get ( 0 ) ;
src = branch ;
final Ref old = db . getRef ( src ) ;
final Ref old = db . getRef ( src ) ;
if ( old = = null )
if ( old = = null )
throw die ( MessageFormat . format ( CLIText . get ( ) . doesNotExist , src ) ) ;
throw die ( MessageFormat . format ( CLIText . get ( ) . doesNotExist , src ) ) ;
if ( ! old . getName ( ) . startsWith ( Constants . R_HEADS ) )
if ( ! old . getName ( ) . startsWith ( Constants . R_HEADS ) )
throw die ( MessageFormat . format ( CLIText . get ( ) . notABranch , src ) ) ;
throw die ( MessageFormat . format ( CLIText . get ( ) . notABranch , src ) ) ;
src = old . getName ( ) ;
src = old . getName ( ) ;
dst = branches . get ( 1 ) ;
dst = otherBranch ;
}
}
if ( ! dst . startsWith ( Constants . R_HEADS ) )
if ( ! dst . startsWith ( Constants . R_HEADS ) )
@ -145,13 +196,14 @@ class Branch extends TextBuiltin {
if ( r . rename ( ) ! = Result . RENAMED )
if ( r . rename ( ) ! = Result . RENAMED )
throw die ( MessageFormat . format ( CLIText . get ( ) . cannotBeRenamed , src ) ) ;
throw die ( MessageFormat . format ( CLIText . get ( ) . cannotBeRenamed , src ) ) ;
} else if ( branches . size ( ) > 0 ) {
} else if ( createForce | | branch ! = null ) {
String newHead = branches . get ( 0 ) ;
String newHead = branch ;
String startBranch ;
String startBranch ;
if ( branches . size ( ) = = 2 )
if ( createForce ) {
startBranch = branches . get ( 1 ) ;
startBranch = otherBranch ;
else
} else {
startBranch = Constants . HEAD ;
startBranch = Constants . HEAD ;
}
Ref startRef = db . getRef ( startBranch ) ;
Ref startRef = db . getRef ( startBranch ) ;
ObjectId startAt = db . resolve ( startBranch + "^0" ) ; //$NON-NLS-1$
ObjectId startAt = db . resolve ( startBranch + "^0" ) ; //$NON-NLS-1$
if ( startRef ! = null ) {
if ( startRef ! = null ) {
@ -164,22 +216,27 @@ class Branch extends TextBuiltin {
}
}
startBranch = Repository . shortenRefName ( startBranch ) ;
startBranch = Repository . shortenRefName ( startBranch ) ;
String newRefName = newHead ;
String newRefName = newHead ;
if ( ! newRefName . startsWith ( Constants . R_HEADS ) )
if ( ! newRefName . startsWith ( Constants . R_HEADS ) ) {
newRefName = Constants . R_HEADS + newRefName ;
newRefName = Constants . R_HEADS + newRefName ;
if ( ! Repository . isValidRefName ( newRefName ) )
}
if ( ! Repository . isValidRefName ( newRefName ) ) {
throw die ( MessageFormat . format ( CLIText . get ( ) . notAValidRefName , newRefName ) ) ;
throw die ( MessageFormat . format ( CLIText . get ( ) . notAValidRefName , newRefName ) ) ;
if ( ! createForce & & db . resolve ( newRefName ) ! = null )
}
if ( ! createForce & & db . resolve ( newRefName ) ! = null ) {
throw die ( MessageFormat . format ( CLIText . get ( ) . branchAlreadyExists , newHead ) ) ;
throw die ( MessageFormat . format ( CLIText . get ( ) . branchAlreadyExists , newHead ) ) ;
}
RefUpdate updateRef = db . updateRef ( newRefName ) ;
RefUpdate updateRef = db . updateRef ( newRefName ) ;
updateRef . setNewObjectId ( startAt ) ;
updateRef . setNewObjectId ( startAt ) ;
updateRef . setForceUpdate ( createForce ) ;
updateRef . setForceUpdate ( createForce ) ;
updateRef . setRefLogMessage ( MessageFormat . format ( CLIText . get ( ) . branchCreatedFrom , startBranch ) , false ) ;
updateRef . setRefLogMessage ( MessageFormat . format ( CLIText . get ( ) . branchCreatedFrom , startBranch ) , false ) ;
Result update = updateRef . update ( ) ;
Result update = updateRef . update ( ) ;
if ( update = = Result . REJECTED )
if ( update = = Result . REJECTED ) {
throw die ( MessageFormat . format ( CLIText . get ( ) . couldNotCreateBranch , newHead , update . toString ( ) ) ) ;
throw die ( MessageFormat . format ( CLIText . get ( ) . couldNotCreateBranch , newHead , update . toString ( ) ) ) ;
}
} else {
} else {
if ( verbose )
if ( verbose ) {
rw = new RevWalk ( db ) ;
rw = new RevWalk ( db ) ;
}
list ( ) ;
list ( ) ;
}
}
}
}
@ -249,7 +306,8 @@ class Branch extends TextBuiltin {
outw . println ( ) ;
outw . println ( ) ;
}
}
private void delete ( boolean force ) throws IOException {
private void delete ( List < String > branches , boolean force )
throws IOException {
String current = db . getBranch ( ) ;
String current = db . getBranch ( ) ;
ObjectId head = db . resolve ( Constants . HEAD ) ;
ObjectId head = db . resolve ( Constants . HEAD ) ;
for ( String branch : branches ) {
for ( String branch : branches ) {