View Javadoc
1   /*
2    * Copyright (C) 2010, 2012 Chris Aniszczyk <caniszczyk@gmail.com>
3    * Copyright (C) 2013, Obeo and others
4    *
5    * This program and the accompanying materials are made available under the
6    * terms of the Eclipse Distribution License v. 1.0 which is available at
7    * https://www.eclipse.org/org/documents/edl-v10.php.
8    *
9    * SPDX-License-Identifier: BSD-3-Clause
10   */
11  
12  package org.eclipse.jgit.pgm;
13  
14  import java.text.MessageFormat;
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  import org.eclipse.jgit.api.CheckoutCommand;
19  import org.eclipse.jgit.api.Git;
20  import org.eclipse.jgit.api.errors.CheckoutConflictException;
21  import org.eclipse.jgit.api.errors.RefAlreadyExistsException;
22  import org.eclipse.jgit.api.errors.RefNotFoundException;
23  import org.eclipse.jgit.lib.Constants;
24  import org.eclipse.jgit.lib.ObjectId;
25  import org.eclipse.jgit.lib.Ref;
26  import org.eclipse.jgit.lib.Repository;
27  import org.eclipse.jgit.lib.TextProgressMonitor;
28  import org.eclipse.jgit.pgm.internal.CLIText;
29  import org.kohsuke.args4j.Argument;
30  import org.kohsuke.args4j.Option;
31  import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
32  
33  @Command(common = true, usage = "usage_checkout")
34  class Checkout extends TextBuiltin {
35  
36  	@Option(name = "-b", usage = "usage_createBranchAndCheckout")
37  	private boolean createBranch = false;
38  
39  	@Option(name = "-B", usage = "usage_forcedSwitchBranch")
40  	private boolean forceSwitchBranch = false;
41  
42  	@Option(name = "--force", aliases = { "-f" }, usage = "usage_forceCheckout")
43  	private boolean forced = false;
44  
45  	@Option(name = "--orphan", usage = "usage_orphan")
46  	private boolean orphan = false;
47  
48  	@Argument(required = false, index = 0, metaVar = "metaVar_name", usage = "usage_checkout")
49  	private String name;
50  
51  	@Option(name = "--", metaVar = "metaVar_paths", handler = RestOfArgumentsHandler.class)
52  	private List<String> paths = new ArrayList<>();
53  
54  	/** {@inheritDoc} */
55  	@Override
56  	protected void run() throws Exception {
57  		if (createBranch) {
58  			final ObjectId head = db.resolve(Constants.HEAD);
59  			if (head == null)
60  				throw die(CLIText.get().onBranchToBeBorn);
61  		}
62  
63  		try (Git git = new Git(db)) {
64  			CheckoutCommand command = git.checkout()
65  					.setProgressMonitor(new TextProgressMonitor(errw));
66  			if (!paths.isEmpty()) {
67  				command.setStartPoint(name);
68  				if (paths.size() == 1 && paths.get(0).equals(".")) { //$NON-NLS-1$
69  					command.setAllPaths(true);
70  				} else {
71  					command.addPaths(paths);
72  				}
73  			} else {
74  				command.setCreateBranch(createBranch);
75  				command.setName(name);
76  				command.setForceRefUpdate(forceSwitchBranch);
77  				command.setForced(forced);
78  				command.setOrphan(orphan);
79  			}
80  			try {
81  				String oldBranch = db.getBranch();
82  				Ref ref = command.call();
83  				if (ref == null)
84  					return;
85  				if (Repository.shortenRefName(ref.getName()).equals(oldBranch)) {
86  					outw.println(MessageFormat.format(
87  							CLIText.get().alreadyOnBranch,
88  							name));
89  					return;
90  				}
91  				if (createBranch || orphan)
92  					outw.println(MessageFormat.format(
93  							CLIText.get().switchedToNewBranch, name));
94  				else
95  					outw.println(MessageFormat.format(
96  							CLIText.get().switchedToBranch,
97  							Repository.shortenRefName(ref.getName())));
98  			} catch (RefNotFoundException e) {
99  				throw die(MessageFormat
100 						.format(CLIText.get().pathspecDidNotMatch, name), e);
101 			} catch (RefAlreadyExistsException e) {
102 				throw die(MessageFormat
103 						.format(CLIText.get().branchAlreadyExists, name), e);
104 			} catch (CheckoutConflictException e) {
105 				StringBuilder builder = new StringBuilder();
106 				builder.append(CLIText.get().checkoutConflict);
107 				builder.append(System.lineSeparator());
108 				for (String path : e.getConflictingPaths()) {
109 					builder.append(MessageFormat.format(
110 							CLIText.get().checkoutConflictPathLine, path));
111 					builder.append(System.lineSeparator());
112 				}
113 				throw die(builder.toString(), e);
114 			}
115 		}
116 	}
117 }