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 }