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 }