1 /* 2 * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> 3 * Copyright (C) 2010, Chris Aniszczyk <caniszczyk@gmail.com> 4 * and other copyright owners as documented in the project's IP log. 5 * 6 * This program and the accompanying materials are made available 7 * under the terms of the Eclipse Distribution License v1.0 which 8 * accompanies this distribution, is reproduced below, and is 9 * available at http://www.eclipse.org/org/documents/edl-v10.php 10 * 11 * All rights reserved. 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 20 * - Redistributions in binary form must reproduce the above 21 * copyright notice, this list of conditions and the following 22 * disclaimer in the documentation and/or other materials provided 23 * with the distribution. 24 * 25 * - Neither the name of the Eclipse Foundation, Inc. nor the 26 * names of its contributors may be used to endorse or promote 27 * products derived from this software without specific prior 28 * written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 31 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 32 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 33 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 34 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 35 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 36 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 37 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 39 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 42 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43 */ 44 package org.eclipse.jgit.api; 45 46 import java.io.File; 47 import java.io.IOException; 48 49 import org.eclipse.jgit.lib.Repository; 50 import org.eclipse.jgit.lib.RepositoryBuilder; 51 import org.eclipse.jgit.lib.RepositoryCache; 52 import org.eclipse.jgit.util.FS; 53 54 /** 55 * Offers a "GitPorcelain"-like API to interact with a git repository. 56 * <p> 57 * The GitPorcelain commands are described in the <a href= 58 * "http://www.kernel.org/pub/software/scm/git/docs/git.html#_high_level_commands_porcelain" 59 * >Git Documentation</a>. 60 * <p> 61 * This class only offers methods to construct so-called command classes. Each 62 * GitPorcelain command is represented by one command class.<br> 63 * Example: this class offers a {@code commit()} method returning an instance of 64 * the {@code CommitCommand} class. The {@code CommitCommand} class has setters 65 * for all the arguments and options. The {@code CommitCommand} class also has a 66 * {@code call} method to actually execute the commit. The following code show's 67 * how to do a simple commit: 68 * 69 * <pre> 70 * Git git = new Git(myRepo); 71 * git.commit().setMessage("Fix393").setAuthor(developerIdent).call(); 72 * </pre> 73 * 74 * All mandatory parameters for commands have to be specified in the methods of 75 * this class, the optional parameters have to be specified by the 76 * setter-methods of the Command class. 77 * <p> 78 * This class is intended to be used internally (e.g. by JGit tests) or by 79 * external components (EGit, third-party tools) when they need exactly the 80 * functionality of a GitPorcelain command. There are use-cases where this class 81 * is not optimal and where you should use the more low-level JGit classes. The 82 * methods in this class may for example offer too much functionality or they 83 * offer the functionality with the wrong arguments. 84 */ 85 public class Git implements AutoCloseable { 86 /** The git repository this class is interacting with */ 87 private final Repository repo; 88 89 private final boolean closeRepo; 90 91 /** 92 * @param dir 93 * the repository to open. May be either the GIT_DIR, or the 94 * working tree directory that contains {@code .git}. 95 * @return a {@link Git} object for the existing git repository 96 * @throws IOException 97 */ 98 public static Git open(File dir) throws IOException { 99 return open(dir, FS.DETECTED); 100 } 101 102 /** 103 * @param dir 104 * the repository to open. May be either the GIT_DIR, or the 105 * working tree directory that contains {@code .git}. 106 * @param fs 107 * filesystem abstraction to use when accessing the repository. 108 * @return a {@link Git} object for the existing git repository. Closing this 109 * instance will close the repo. 110 * @throws IOException 111 */ 112 public static Git open(File dir, FS fs) throws IOException { 113 RepositoryCache.FileKey key; 114 115 key = RepositoryCache.FileKey.lenient(dir, fs); 116 Repository db = new RepositoryBuilder().setFS(fs).setGitDir(key.getFile()) 117 .setMustExist(true).build(); 118 return new Git(db, true); 119 } 120 121 /** 122 * @param repo 123 * the git repository this class is interacting with; 124 * {@code null} is not allowed. 125 * @return a {@link Git} object for the existing git repository. The caller is 126 * responsible for closing the repository; {@link #close()} on this 127 * instance does not close the repo. 128 */ 129 public static Git wrap(Repository repo) { 130 return new Git(repo); 131 } 132 133 /** 134 * Frees resources associated with this instance. 135 * <p> 136 * If the repository was opened by a static factory method in this class, then 137 * this method calls {@link Repository#close()} on the underlying repository 138 * instance. (Whether this actually releases underlying resources, such as 139 * file handles, may vary; see {@link Repository} for more details.) 140 * <p> 141 * If the repository was created by a caller and passed into {@link 142 * #Git(Repository)} or a static factory method in this class, then this 143 * method does not call close on the underlying repository. 144 * <p> 145 * In all cases, after calling this method you should not use this {@link Git} 146 * instance anymore. 147 * 148 * @since 3.2 149 */ 150 @Override 151 public void close() { 152 if (closeRepo) 153 repo.close(); 154 } 155 156 /** 157 * Returns a command object to execute a {@code clone} command 158 * 159 * @see <a 160 * href="http://www.kernel.org/pub/software/scm/git/docs/git-clone.html" 161 * >Git documentation about clone</a> 162 * @return a {@link CloneCommand} used to collect all optional parameters 163 * and to finally execute the {@code clone} command 164 */ 165 public static CloneCommand cloneRepository() { 166 return new CloneCommand(); 167 } 168 169 /** 170 * Returns a command to list remote branches/tags without a local 171 * repository. 172 * 173 * @return a {@link LsRemoteCommand} 174 * @since 3.1 175 */ 176 public static LsRemoteCommand lsRemoteRepository() { 177 return new LsRemoteCommand(null); 178 } 179 180 /** 181 * Returns a command object to execute a {@code init} command 182 * 183 * @see <a 184 * href="http://www.kernel.org/pub/software/scm/git/docs/git-init.html" 185 * >Git documentation about init</a> 186 * @return a {@link InitCommand} used to collect all optional parameters and 187 * to finally execute the {@code init} command 188 */ 189 public static InitCommand init() { 190 return new InitCommand(); 191 } 192 193 /** 194 * Constructs a new {@link Git} object which can interact with the specified 195 * git repository. 196 * <p> 197 * All command classes returned by methods of this class will always interact 198 * with this git repository. 199 * <p> 200 * The caller is responsible for closing the repository; {@link #close()} on 201 * this instance does not close the repo. 202 * 203 * @param repo 204 * the git repository this class is interacting with; 205 * {@code null} is not allowed. 206 */ 207 public Git(Repository repo) { 208 this(repo, false); 209 } 210 211 Git(Repository repo, boolean closeRepo) { 212 if (repo == null) 213 throw new NullPointerException(); 214 this.repo = repo; 215 this.closeRepo = closeRepo; 216 } 217 218 /** 219 * Returns a command object to execute a {@code Commit} command 220 * 221 * @see <a 222 * href="http://www.kernel.org/pub/software/scm/git/docs/git-commit.html" 223 * >Git documentation about Commit</a> 224 * @return a {@link CommitCommand} used to collect all optional parameters 225 * and to finally execute the {@code Commit} command 226 */ 227 public CommitCommand commit() { 228 return new CommitCommand(repo); 229 } 230 231 /** 232 * Returns a command object to execute a {@code Log} command 233 * 234 * @see <a 235 * href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html" 236 * >Git documentation about Log</a> 237 * @return a {@link LogCommand} used to collect all optional parameters and 238 * to finally execute the {@code Log} command 239 */ 240 public LogCommand log() { 241 return new LogCommand(repo); 242 } 243 244 /** 245 * Returns a command object to execute a {@code Merge} command 246 * 247 * @see <a 248 * href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html" 249 * >Git documentation about Merge</a> 250 * @return a {@link MergeCommand} used to collect all optional parameters 251 * and to finally execute the {@code Merge} command 252 */ 253 public MergeCommand merge() { 254 return new MergeCommand(repo); 255 } 256 257 /** 258 * Returns a command object to execute a {@code Pull} command 259 * 260 * @return a {@link PullCommand} 261 */ 262 public PullCommand pull() { 263 return new PullCommand(repo); 264 } 265 266 /** 267 * Returns a command object used to create branches 268 * 269 * @return a {@link CreateBranchCommand} 270 */ 271 public CreateBranchCommand branchCreate() { 272 return new CreateBranchCommand(repo); 273 } 274 275 /** 276 * Returns a command object used to delete branches 277 * 278 * @return a {@link DeleteBranchCommand} 279 */ 280 public DeleteBranchCommand branchDelete() { 281 return new DeleteBranchCommand(repo); 282 } 283 284 /** 285 * Returns a command object used to list branches 286 * 287 * @return a {@link ListBranchCommand} 288 */ 289 public ListBranchCommand branchList() { 290 return new ListBranchCommand(repo); 291 } 292 293 /** 294 * 295 * Returns a command object used to list tags 296 * 297 * @return a {@link ListTagCommand} 298 */ 299 public ListTagCommand tagList() { 300 return new ListTagCommand(repo); 301 } 302 303 /** 304 * Returns a command object used to rename branches 305 * 306 * @return a {@link RenameBranchCommand} 307 */ 308 public RenameBranchCommand branchRename() { 309 return new RenameBranchCommand(repo); 310 } 311 312 /** 313 * Returns a command object to execute a {@code Add} command 314 * 315 * @see <a 316 * href="http://www.kernel.org/pub/software/scm/git/docs/git-add.html" 317 * >Git documentation about Add</a> 318 * @return a {@link AddCommand} used to collect all optional parameters and 319 * to finally execute the {@code Add} command 320 */ 321 public AddCommand add() { 322 return new AddCommand(repo); 323 } 324 325 /** 326 * Returns a command object to execute a {@code Tag} command 327 * 328 * @see <a 329 * href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html" 330 * >Git documentation about Tag</a> 331 * @return a {@link TagCommand} used to collect all optional parameters and 332 * to finally execute the {@code Tag} command 333 */ 334 public TagCommand tag() { 335 return new TagCommand(repo); 336 } 337 338 /** 339 * Returns a command object to execute a {@code Fetch} command 340 * 341 * @see <a 342 * href="http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html" 343 * >Git documentation about Fetch</a> 344 * @return a {@link FetchCommand} used to collect all optional parameters 345 * and to finally execute the {@code Fetch} command 346 */ 347 public FetchCommand fetch() { 348 return new FetchCommand(repo); 349 } 350 351 /** 352 * Returns a command object to execute a {@code Push} command 353 * 354 * @see <a 355 * href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html" 356 * >Git documentation about Push</a> 357 * @return a {@link PushCommand} used to collect all optional parameters and 358 * to finally execute the {@code Push} command 359 */ 360 public PushCommand push() { 361 return new PushCommand(repo); 362 } 363 364 /** 365 * Returns a command object to execute a {@code cherry-pick} command 366 * 367 * @see <a 368 * href="http://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html" 369 * >Git documentation about cherry-pick</a> 370 * @return a {@link CherryPickCommand} used to collect all optional 371 * parameters and to finally execute the {@code cherry-pick} command 372 */ 373 public CherryPickCommand cherryPick() { 374 return new CherryPickCommand(repo); 375 } 376 377 /** 378 * Returns a command object to execute a {@code revert} command 379 * 380 * @see <a 381 * href="http://www.kernel.org/pub/software/scm/git/docs/git-revert.html" 382 * >Git documentation about reverting changes</a> 383 * @return a {@link RevertCommand} used to collect all optional parameters 384 * and to finally execute the {@code cherry-pick} command 385 */ 386 public RevertCommand revert() { 387 return new RevertCommand(repo); 388 } 389 390 /** 391 * Returns a command object to execute a {@code Rebase} command 392 * 393 * @see <a 394 * href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html" 395 * >Git documentation about rebase</a> 396 * @return a {@link RebaseCommand} used to collect all optional parameters 397 * and to finally execute the {@code rebase} command 398 */ 399 public RebaseCommand rebase() { 400 return new RebaseCommand(repo); 401 } 402 403 /** 404 * Returns a command object to execute a {@code rm} command 405 * 406 * @see <a 407 * href="http://www.kernel.org/pub/software/scm/git/docs/git-rm.html" 408 * >Git documentation about rm</a> 409 * @return a {@link RmCommand} used to collect all optional parameters and 410 * to finally execute the {@code rm} command 411 */ 412 public RmCommand rm() { 413 return new RmCommand(repo); 414 } 415 416 /** 417 * Returns a command object to execute a {@code checkout} command 418 * 419 * @see <a 420 * href="http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html" 421 * >Git documentation about checkout</a> 422 * @return a {@link CheckoutCommand} used to collect all optional parameters 423 * and to finally execute the {@code checkout} command 424 */ 425 public CheckoutCommand checkout() { 426 return new CheckoutCommand(repo); 427 } 428 429 /** 430 * Returns a command object to execute a {@code reset} command 431 * 432 * @see <a 433 * href="http://www.kernel.org/pub/software/scm/git/docs/git-reset.html" 434 * >Git documentation about reset</a> 435 * @return a {@link ResetCommand} used to collect all optional parameters 436 * and to finally execute the {@code reset} command 437 */ 438 public ResetCommand reset() { 439 return new ResetCommand(repo); 440 } 441 442 /** 443 * Returns a command object to execute a {@code status} command 444 * 445 * @see <a 446 * href="http://www.kernel.org/pub/software/scm/git/docs/git-status.html" 447 * >Git documentation about status</a> 448 * @return a {@link StatusCommand} used to collect all optional parameters 449 * and to finally execute the {@code status} command 450 */ 451 public StatusCommand status() { 452 return new StatusCommand(repo); 453 } 454 455 /** 456 * Returns a command to create an archive from a tree 457 * 458 * @return a {@link ArchiveCommand} 459 * @since 3.1 460 */ 461 public ArchiveCommand archive() { 462 return new ArchiveCommand(repo); 463 } 464 465 /** 466 * Returns a command to add notes to an object 467 * 468 * @return a {@link AddNoteCommand} 469 */ 470 public AddNoteCommand notesAdd() { 471 return new AddNoteCommand(repo); 472 } 473 474 /** 475 * Returns a command to remove notes on an object 476 * 477 * @return a {@link RemoveNoteCommand} 478 */ 479 public RemoveNoteCommand notesRemove() { 480 return new RemoveNoteCommand(repo); 481 } 482 483 /** 484 * Returns a command to list all notes 485 * 486 * @return a {@link ListNotesCommand} 487 */ 488 public ListNotesCommand notesList() { 489 return new ListNotesCommand(repo); 490 } 491 492 /** 493 * Returns a command to show notes on an object 494 * 495 * @return a {@link ShowNoteCommand} 496 */ 497 public ShowNoteCommand notesShow() { 498 return new ShowNoteCommand(repo); 499 } 500 501 /** 502 * Returns a command object to execute a {@code ls-remote} command 503 * 504 * @see <a 505 * href="http://www.kernel.org/pub/software/scm/git/docs/git-ls-remote.html" 506 * >Git documentation about ls-remote</a> 507 * @return a {@link LsRemoteCommand} used to collect all optional parameters 508 * and to finally execute the {@code status} command 509 */ 510 public LsRemoteCommand lsRemote() { 511 return new LsRemoteCommand(repo); 512 } 513 514 /** 515 * Returns a command object to execute a {@code clean} command 516 * 517 * @see <a 518 * href="http://www.kernel.org/pub/software/scm/git/docs/git-clean.html" 519 * >Git documentation about Clean</a> 520 * @return a {@link CleanCommand} used to collect all optional parameters 521 * and to finally execute the {@code clean} command 522 */ 523 public CleanCommand clean() { 524 return new CleanCommand(repo); 525 } 526 527 /** 528 * Returns a command object to execute a {@code blame} command 529 * 530 * @see <a 531 * href="http://www.kernel.org/pub/software/scm/git/docs/git-blame.html" 532 * >Git documentation about Blame</a> 533 * @return a {@link BlameCommand} used to collect all optional parameters 534 * and to finally execute the {@code blame} command 535 */ 536 public BlameCommand blame() { 537 return new BlameCommand(repo); 538 } 539 540 /** 541 * Returns a command object to execute a {@code reflog} command 542 * 543 * @see <a 544 * href="http://www.kernel.org/pub/software/scm/git/docs/git-reflog.html" 545 * >Git documentation about reflog</a> 546 * @return a {@link ReflogCommand} used to collect all optional parameters 547 * and to finally execute the {@code reflog} command 548 */ 549 public ReflogCommand reflog() { 550 return new ReflogCommand(repo); 551 } 552 553 /** 554 * Returns a command object to execute a {@code diff} command 555 * 556 * @see <a 557 * href="http://www.kernel.org/pub/software/scm/git/docs/git-diff.html" 558 * >Git documentation about diff</a> 559 * @return a {@link DiffCommand} used to collect all optional parameters and 560 * to finally execute the {@code diff} command 561 */ 562 public DiffCommand diff() { 563 return new DiffCommand(repo); 564 } 565 566 /** 567 * Returns a command object used to delete tags 568 * 569 * @return a {@link DeleteTagCommand} 570 */ 571 public DeleteTagCommand tagDelete() { 572 return new DeleteTagCommand(repo); 573 } 574 575 /** 576 * Returns a command object to execute a {@code submodule add} command 577 * 578 * @return a {@link SubmoduleAddCommand} used to add a new submodule to a 579 * parent repository 580 */ 581 public SubmoduleAddCommand submoduleAdd() { 582 return new SubmoduleAddCommand(repo); 583 } 584 585 /** 586 * Returns a command object to execute a {@code submodule init} command 587 * 588 * @return a {@link SubmoduleInitCommand} used to initialize the 589 * repository's config with settings from the .gitmodules file in 590 * the working tree 591 */ 592 public SubmoduleInitCommand submoduleInit() { 593 return new SubmoduleInitCommand(repo); 594 } 595 596 /** 597 * Returns a command object to execute a {@code submodule status} command 598 * 599 * @return a {@link SubmoduleStatusCommand} used to report the status of a 600 * repository's configured submodules 601 */ 602 public SubmoduleStatusCommand submoduleStatus() { 603 return new SubmoduleStatusCommand(repo); 604 } 605 606 /** 607 * Returns a command object to execute a {@code submodule sync} command 608 * 609 * @return a {@link SubmoduleSyncCommand} used to update the URL of a 610 * submodule from the parent repository's .gitmodules file 611 */ 612 public SubmoduleSyncCommand submoduleSync() { 613 return new SubmoduleSyncCommand(repo); 614 } 615 616 /** 617 * Returns a command object to execute a {@code submodule update} command 618 * 619 * @return a {@link SubmoduleUpdateCommand} used to update the submodules in 620 * a repository to the configured revision 621 */ 622 public SubmoduleUpdateCommand submoduleUpdate() { 623 return new SubmoduleUpdateCommand(repo); 624 } 625 626 /** 627 * Returns a command object used to list stashed commits 628 * 629 * @return a {@link StashListCommand} 630 */ 631 public StashListCommand stashList() { 632 return new StashListCommand(repo); 633 } 634 635 /** 636 * Returns a command object used to create a stashed commit 637 * 638 * @return a {@link StashCreateCommand} 639 * @since 2.0 640 */ 641 public StashCreateCommand stashCreate() { 642 return new StashCreateCommand(repo); 643 } 644 645 /** 646 * Returns a command object used to apply a stashed commit 647 * 648 * @return a {@link StashApplyCommand} 649 * @since 2.0 650 */ 651 public StashApplyCommand stashApply() { 652 return new StashApplyCommand(repo); 653 } 654 655 /** 656 * Returns a command object used to drop a stashed commit 657 * 658 * @return a {@link StashDropCommand} 659 * @since 2.0 660 */ 661 public StashDropCommand stashDrop() { 662 return new StashDropCommand(repo); 663 } 664 665 /** 666 * Returns a command object to execute a {@code apply} command 667 * 668 * @see <a 669 * href="http://www.kernel.org/pub/software/scm/git/docs/git-apply.html" 670 * >Git documentation about apply</a> 671 * 672 * @return a {@link ApplyCommand} used to collect all optional parameters 673 * and to finally execute the {@code apply} command 674 * @since 2.0 675 */ 676 public ApplyCommand apply() { 677 return new ApplyCommand(repo); 678 } 679 680 /** 681 * Returns a command object to execute a {@code gc} command 682 * 683 * @see <a 684 * href="http://www.kernel.org/pub/software/scm/git/docs/git-gc.html" 685 * >Git documentation about gc</a> 686 * 687 * @return a {@link GarbageCollectCommand} used to collect all optional 688 * parameters and to finally execute the {@code gc} command 689 * @since 2.2 690 */ 691 public GarbageCollectCommand gc() { 692 return new GarbageCollectCommand(repo); 693 } 694 695 /** 696 * Returns a command object to find human-readable names of revisions. 697 * 698 * @return a {@link NameRevCommand}. 699 * @since 3.0 700 */ 701 public NameRevCommand nameRev() { 702 return new NameRevCommand(repo); 703 } 704 705 /** 706 * Returns a command object to come up with a short name that describes a 707 * commit in terms of the nearest git tag. 708 * 709 * @return a {@link DescribeCommand}. 710 * @since 3.2 711 */ 712 public DescribeCommand describe() { 713 return new DescribeCommand(repo); 714 } 715 716 /** 717 * Return a command used to list the available remotes. 718 * 719 * @return a {@link RemoteListCommand} 720 * @since 4.2 721 */ 722 public RemoteListCommand remoteList() { 723 return new RemoteListCommand(repo); 724 } 725 726 /** 727 * Return a command used to add a new remote. 728 * 729 * @return a {@link RemoteAddCommand} 730 * @since 4.2 731 */ 732 public RemoteAddCommand remoteAdd() { 733 return new RemoteAddCommand(repo); 734 } 735 736 /** 737 * Return a command used to remove an existing remote. 738 * 739 * @return a {@link RemoteRemoveCommand} 740 * @since 4.2 741 */ 742 public RemoteRemoveCommand remoteRemove() { 743 return new RemoteRemoveCommand(repo); 744 } 745 746 /** 747 * Return a command used to change the URL of an existing remote. 748 * 749 * @return a {@link RemoteSetUrlCommand} 750 * @since 4.2 751 */ 752 public RemoteSetUrlCommand remoteSetUrl() { 753 return new RemoteSetUrlCommand(repo); 754 } 755 756 /** 757 * @return the git repository this class is interacting with; see 758 * {@link #close()} for notes on closing this repository. 759 */ 760 public Repository getRepository() { 761 return repo; 762 } 763 764 @Override 765 public String toString() { 766 return "Git[" + repo + "]"; //$NON-NLS-1$//$NON-NLS-2$ 767 } 768 }