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 public void close() { 151 if (closeRepo) 152 repo.close(); 153 } 154 155 /** 156 * Returns a command object to execute a {@code clone} command 157 * 158 * @see <a 159 * href="http://www.kernel.org/pub/software/scm/git/docs/git-clone.html" 160 * >Git documentation about clone</a> 161 * @return a {@link CloneCommand} used to collect all optional parameters 162 * and to finally execute the {@code clone} command 163 */ 164 public static CloneCommand cloneRepository() { 165 return new CloneCommand(); 166 } 167 168 /** 169 * Returns a command to list remote branches/tags without a local 170 * repository. 171 * 172 * @return a {@link LsRemoteCommand} 173 * @since 3.1 174 */ 175 public static LsRemoteCommand lsRemoteRepository() { 176 return new LsRemoteCommand(null); 177 } 178 179 /** 180 * Returns a command object to execute a {@code init} command 181 * 182 * @see <a 183 * href="http://www.kernel.org/pub/software/scm/git/docs/git-init.html" 184 * >Git documentation about init</a> 185 * @return a {@link InitCommand} used to collect all optional parameters and 186 * to finally execute the {@code init} command 187 */ 188 public static InitCommand init() { 189 return new InitCommand(); 190 } 191 192 /** 193 * Constructs a new {@link Git} object which can interact with the specified 194 * git repository. 195 * <p> 196 * All command classes returned by methods of this class will always interact 197 * with this git repository. 198 * <p> 199 * The caller is responsible for closing the repository; {@link #close()} on 200 * this instance does not close the repo. 201 * 202 * @param repo 203 * the git repository this class is interacting with; 204 * {@code null} is not allowed. 205 */ 206 public Git(Repository repo) { 207 this(repo, false); 208 } 209 210 Git(Repository repo, boolean closeRepo) { 211 if (repo == null) 212 throw new NullPointerException(); 213 this.repo = repo; 214 this.closeRepo = closeRepo; 215 } 216 217 /** 218 * Returns a command object to execute a {@code Commit} command 219 * 220 * @see <a 221 * href="http://www.kernel.org/pub/software/scm/git/docs/git-commit.html" 222 * >Git documentation about Commit</a> 223 * @return a {@link CommitCommand} used to collect all optional parameters 224 * and to finally execute the {@code Commit} command 225 */ 226 public CommitCommand commit() { 227 return new CommitCommand(repo); 228 } 229 230 /** 231 * Returns a command object to execute a {@code Log} command 232 * 233 * @see <a 234 * href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html" 235 * >Git documentation about Log</a> 236 * @return a {@link LogCommand} used to collect all optional parameters and 237 * to finally execute the {@code Log} command 238 */ 239 public LogCommand log() { 240 return new LogCommand(repo); 241 } 242 243 /** 244 * Returns a command object to execute a {@code Merge} command 245 * 246 * @see <a 247 * href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html" 248 * >Git documentation about Merge</a> 249 * @return a {@link MergeCommand} used to collect all optional parameters 250 * and to finally execute the {@code Merge} command 251 */ 252 public MergeCommand merge() { 253 return new MergeCommand(repo); 254 } 255 256 /** 257 * Returns a command object to execute a {@code Pull} command 258 * 259 * @return a {@link PullCommand} 260 */ 261 public PullCommand pull() { 262 return new PullCommand(repo); 263 } 264 265 /** 266 * Returns a command object used to create branches 267 * 268 * @return a {@link CreateBranchCommand} 269 */ 270 public CreateBranchCommand branchCreate() { 271 return new CreateBranchCommand(repo); 272 } 273 274 /** 275 * Returns a command object used to delete branches 276 * 277 * @return a {@link DeleteBranchCommand} 278 */ 279 public DeleteBranchCommand branchDelete() { 280 return new DeleteBranchCommand(repo); 281 } 282 283 /** 284 * Returns a command object used to list branches 285 * 286 * @return a {@link ListBranchCommand} 287 */ 288 public ListBranchCommand branchList() { 289 return new ListBranchCommand(repo); 290 } 291 292 /** 293 * 294 * Returns a command object used to list tags 295 * 296 * @return a {@link ListTagCommand} 297 */ 298 public ListTagCommand tagList() { 299 return new ListTagCommand(repo); 300 } 301 302 /** 303 * Returns a command object used to rename branches 304 * 305 * @return a {@link RenameBranchCommand} 306 */ 307 public RenameBranchCommand branchRename() { 308 return new RenameBranchCommand(repo); 309 } 310 311 /** 312 * Returns a command object to execute a {@code Add} command 313 * 314 * @see <a 315 * href="http://www.kernel.org/pub/software/scm/git/docs/git-add.html" 316 * >Git documentation about Add</a> 317 * @return a {@link AddCommand} used to collect all optional parameters and 318 * to finally execute the {@code Add} command 319 */ 320 public AddCommand add() { 321 return new AddCommand(repo); 322 } 323 324 /** 325 * Returns a command object to execute a {@code Tag} command 326 * 327 * @see <a 328 * href="http://www.kernel.org/pub/software/scm/git/docs/git-tag.html" 329 * >Git documentation about Tag</a> 330 * @return a {@link TagCommand} used to collect all optional parameters and 331 * to finally execute the {@code Tag} command 332 */ 333 public TagCommand tag() { 334 return new TagCommand(repo); 335 } 336 337 /** 338 * Returns a command object to execute a {@code Fetch} command 339 * 340 * @see <a 341 * href="http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html" 342 * >Git documentation about Fetch</a> 343 * @return a {@link FetchCommand} used to collect all optional parameters 344 * and to finally execute the {@code Fetch} command 345 */ 346 public FetchCommand fetch() { 347 return new FetchCommand(repo); 348 } 349 350 /** 351 * Returns a command object to execute a {@code Push} command 352 * 353 * @see <a 354 * href="http://www.kernel.org/pub/software/scm/git/docs/git-push.html" 355 * >Git documentation about Push</a> 356 * @return a {@link PushCommand} used to collect all optional parameters and 357 * to finally execute the {@code Push} command 358 */ 359 public PushCommand push() { 360 return new PushCommand(repo); 361 } 362 363 /** 364 * Returns a command object to execute a {@code cherry-pick} command 365 * 366 * @see <a 367 * href="http://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html" 368 * >Git documentation about cherry-pick</a> 369 * @return a {@link CherryPickCommand} used to collect all optional 370 * parameters and to finally execute the {@code cherry-pick} command 371 */ 372 public CherryPickCommand cherryPick() { 373 return new CherryPickCommand(repo); 374 } 375 376 /** 377 * Returns a command object to execute a {@code revert} command 378 * 379 * @see <a 380 * href="http://www.kernel.org/pub/software/scm/git/docs/git-revert.html" 381 * >Git documentation about reverting changes</a> 382 * @return a {@link RevertCommand} used to collect all optional parameters 383 * and to finally execute the {@code cherry-pick} command 384 */ 385 public RevertCommand revert() { 386 return new RevertCommand(repo); 387 } 388 389 /** 390 * Returns a command object to execute a {@code Rebase} command 391 * 392 * @see <a 393 * href="http://www.kernel.org/pub/software/scm/git/docs/git-rebase.html" 394 * >Git documentation about rebase</a> 395 * @return a {@link RebaseCommand} used to collect all optional parameters 396 * and to finally execute the {@code rebase} command 397 */ 398 public RebaseCommand rebase() { 399 return new RebaseCommand(repo); 400 } 401 402 /** 403 * Returns a command object to execute a {@code rm} command 404 * 405 * @see <a 406 * href="http://www.kernel.org/pub/software/scm/git/docs/git-rm.html" 407 * >Git documentation about rm</a> 408 * @return a {@link RmCommand} used to collect all optional parameters and 409 * to finally execute the {@code rm} command 410 */ 411 public RmCommand rm() { 412 return new RmCommand(repo); 413 } 414 415 /** 416 * Returns a command object to execute a {@code checkout} command 417 * 418 * @see <a 419 * href="http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html" 420 * >Git documentation about checkout</a> 421 * @return a {@link CheckoutCommand} used to collect all optional parameters 422 * and to finally execute the {@code checkout} command 423 */ 424 public CheckoutCommand checkout() { 425 return new CheckoutCommand(repo); 426 } 427 428 /** 429 * Returns a command object to execute a {@code reset} command 430 * 431 * @see <a 432 * href="http://www.kernel.org/pub/software/scm/git/docs/git-reset.html" 433 * >Git documentation about reset</a> 434 * @return a {@link ResetCommand} used to collect all optional parameters 435 * and to finally execute the {@code reset} command 436 */ 437 public ResetCommand reset() { 438 return new ResetCommand(repo); 439 } 440 441 /** 442 * Returns a command object to execute a {@code status} command 443 * 444 * @see <a 445 * href="http://www.kernel.org/pub/software/scm/git/docs/git-status.html" 446 * >Git documentation about status</a> 447 * @return a {@link StatusCommand} used to collect all optional parameters 448 * and to finally execute the {@code status} command 449 */ 450 public StatusCommand status() { 451 return new StatusCommand(repo); 452 } 453 454 /** 455 * Returns a command to create an archive from a tree 456 * 457 * @return a {@link ArchiveCommand} 458 * @since 3.1 459 */ 460 public ArchiveCommand archive() { 461 return new ArchiveCommand(repo); 462 } 463 464 /** 465 * Returns a command to add notes to an object 466 * 467 * @return a {@link AddNoteCommand} 468 */ 469 public AddNoteCommand notesAdd() { 470 return new AddNoteCommand(repo); 471 } 472 473 /** 474 * Returns a command to remove notes on an object 475 * 476 * @return a {@link RemoveNoteCommand} 477 */ 478 public RemoveNoteCommand notesRemove() { 479 return new RemoveNoteCommand(repo); 480 } 481 482 /** 483 * Returns a command to list all notes 484 * 485 * @return a {@link ListNotesCommand} 486 */ 487 public ListNotesCommand notesList() { 488 return new ListNotesCommand(repo); 489 } 490 491 /** 492 * Returns a command to show notes on an object 493 * 494 * @return a {@link ShowNoteCommand} 495 */ 496 public ShowNoteCommand notesShow() { 497 return new ShowNoteCommand(repo); 498 } 499 500 /** 501 * Returns a command object to execute a {@code ls-remote} command 502 * 503 * @see <a 504 * href="http://www.kernel.org/pub/software/scm/git/docs/git-ls-remote.html" 505 * >Git documentation about ls-remote</a> 506 * @return a {@link LsRemoteCommand} used to collect all optional parameters 507 * and to finally execute the {@code status} command 508 */ 509 public LsRemoteCommand lsRemote() { 510 return new LsRemoteCommand(repo); 511 } 512 513 /** 514 * Returns a command object to execute a {@code clean} command 515 * 516 * @see <a 517 * href="http://www.kernel.org/pub/software/scm/git/docs/git-clean.html" 518 * >Git documentation about Clean</a> 519 * @return a {@link CleanCommand} used to collect all optional parameters 520 * and to finally execute the {@code clean} command 521 */ 522 public CleanCommand clean() { 523 return new CleanCommand(repo); 524 } 525 526 /** 527 * Returns a command object to execute a {@code blame} command 528 * 529 * @see <a 530 * href="http://www.kernel.org/pub/software/scm/git/docs/git-blame.html" 531 * >Git documentation about Blame</a> 532 * @return a {@link BlameCommand} used to collect all optional parameters 533 * and to finally execute the {@code blame} command 534 */ 535 public BlameCommand blame() { 536 return new BlameCommand(repo); 537 } 538 539 /** 540 * Returns a command object to execute a {@code reflog} command 541 * 542 * @see <a 543 * href="http://www.kernel.org/pub/software/scm/git/docs/git-reflog.html" 544 * >Git documentation about reflog</a> 545 * @return a {@link ReflogCommand} used to collect all optional parameters 546 * and to finally execute the {@code reflog} command 547 */ 548 public ReflogCommand reflog() { 549 return new ReflogCommand(repo); 550 } 551 552 /** 553 * Returns a command object to execute a {@code diff} command 554 * 555 * @see <a 556 * href="http://www.kernel.org/pub/software/scm/git/docs/git-diff.html" 557 * >Git documentation about diff</a> 558 * @return a {@link DiffCommand} used to collect all optional parameters and 559 * to finally execute the {@code diff} command 560 */ 561 public DiffCommand diff() { 562 return new DiffCommand(repo); 563 } 564 565 /** 566 * Returns a command object used to delete tags 567 * 568 * @return a {@link DeleteTagCommand} 569 */ 570 public DeleteTagCommand tagDelete() { 571 return new DeleteTagCommand(repo); 572 } 573 574 /** 575 * Returns a command object to execute a {@code submodule add} command 576 * 577 * @return a {@link SubmoduleAddCommand} used to add a new submodule to a 578 * parent repository 579 */ 580 public SubmoduleAddCommand submoduleAdd() { 581 return new SubmoduleAddCommand(repo); 582 } 583 584 /** 585 * Returns a command object to execute a {@code submodule init} command 586 * 587 * @return a {@link SubmoduleInitCommand} used to initialize the 588 * repository's config with settings from the .gitmodules file in 589 * the working tree 590 */ 591 public SubmoduleInitCommand submoduleInit() { 592 return new SubmoduleInitCommand(repo); 593 } 594 595 /** 596 * Returns a command object to execute a {@code submodule status} command 597 * 598 * @return a {@link SubmoduleStatusCommand} used to report the status of a 599 * repository's configured submodules 600 */ 601 public SubmoduleStatusCommand submoduleStatus() { 602 return new SubmoduleStatusCommand(repo); 603 } 604 605 /** 606 * Returns a command object to execute a {@code submodule sync} command 607 * 608 * @return a {@link SubmoduleSyncCommand} used to update the URL of a 609 * submodule from the parent repository's .gitmodules file 610 */ 611 public SubmoduleSyncCommand submoduleSync() { 612 return new SubmoduleSyncCommand(repo); 613 } 614 615 /** 616 * Returns a command object to execute a {@code submodule update} command 617 * 618 * @return a {@link SubmoduleUpdateCommand} used to update the submodules in 619 * a repository to the configured revision 620 */ 621 public SubmoduleUpdateCommand submoduleUpdate() { 622 return new SubmoduleUpdateCommand(repo); 623 } 624 625 /** 626 * Returns a command object used to list stashed commits 627 * 628 * @return a {@link StashListCommand} 629 */ 630 public StashListCommand stashList() { 631 return new StashListCommand(repo); 632 } 633 634 /** 635 * Returns a command object used to create a stashed commit 636 * 637 * @return a {@link StashCreateCommand} 638 * @since 2.0 639 */ 640 public StashCreateCommand stashCreate() { 641 return new StashCreateCommand(repo); 642 } 643 644 /** 645 * Returns a command object used to apply a stashed commit 646 * 647 * @return a {@link StashApplyCommand} 648 * @since 2.0 649 */ 650 public StashApplyCommand stashApply() { 651 return new StashApplyCommand(repo); 652 } 653 654 /** 655 * Returns a command object used to drop a stashed commit 656 * 657 * @return a {@link StashDropCommand} 658 * @since 2.0 659 */ 660 public StashDropCommand stashDrop() { 661 return new StashDropCommand(repo); 662 } 663 664 /** 665 * Returns a command object to execute a {@code apply} command 666 * 667 * @see <a 668 * href="http://www.kernel.org/pub/software/scm/git/docs/git-apply.html" 669 * >Git documentation about apply</a> 670 * 671 * @return a {@link ApplyCommand} used to collect all optional parameters 672 * and to finally execute the {@code apply} command 673 * @since 2.0 674 */ 675 public ApplyCommand apply() { 676 return new ApplyCommand(repo); 677 } 678 679 /** 680 * Returns a command object to execute a {@code gc} command 681 * 682 * @see <a 683 * href="http://www.kernel.org/pub/software/scm/git/docs/git-gc.html" 684 * >Git documentation about gc</a> 685 * 686 * @return a {@link GarbageCollectCommand} used to collect all optional 687 * parameters and to finally execute the {@code gc} command 688 * @since 2.2 689 */ 690 public GarbageCollectCommand gc() { 691 return new GarbageCollectCommand(repo); 692 } 693 694 /** 695 * Returns a command object to find human-readable names of revisions. 696 * 697 * @return a {@link NameRevCommand}. 698 * @since 3.0 699 */ 700 public NameRevCommand nameRev() { 701 return new NameRevCommand(repo); 702 } 703 704 /** 705 * Returns a command object to come up with a short name that describes a 706 * commit in terms of the nearest git tag. 707 * 708 * @return a {@link DescribeCommand}. 709 * @since 3.2 710 */ 711 public DescribeCommand describe() { 712 return new DescribeCommand(repo); 713 } 714 715 /** 716 * Return a command used to list the available remotes. 717 * 718 * @return a {@link RemoteListCommand} 719 * @since 4.2 720 */ 721 public RemoteListCommand remoteList() { 722 return new RemoteListCommand(repo); 723 } 724 725 /** 726 * Return a command used to add a new remote. 727 * 728 * @return a {@link RemoteAddCommand} 729 * @since 4.2 730 */ 731 public RemoteAddCommand remoteAdd() { 732 return new RemoteAddCommand(repo); 733 } 734 735 /** 736 * Return a command used to remove an existing remote. 737 * 738 * @return a {@link RemoteRemoveCommand} 739 * @since 4.2 740 */ 741 public RemoteRemoveCommand remoteRemove() { 742 return new RemoteRemoveCommand(repo); 743 } 744 745 /** 746 * Return a command used to change the URL of an existing remote. 747 * 748 * @return a {@link RemoteSetUrlCommand} 749 * @since 4.2 750 */ 751 public RemoteSetUrlCommand remoteSetUrl() { 752 return new RemoteSetUrlCommand(repo); 753 } 754 755 /** 756 * @return the git repository this class is interacting with; see 757 * {@link #close()} for notes on closing this repository. 758 */ 759 public Repository getRepository() { 760 return repo; 761 } 762 763 @Override 764 public String toString() { 765 return "Git[" + repo + "]"; //$NON-NLS-1$//$NON-NLS-2$ 766 } 767 }