File indexing completed on 2024-04-28 16:01:33
0001 /****************************************************************************** 0002 * This file is part of the libqgit2 library 0003 * Copyright (c) 2011 Laszlo Papp <djszapi@archlinux.us> 0004 * Copyright (C) 2013 Leonardo Giordani 0005 * 0006 * This library is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU Lesser General Public 0008 * License as published by the Free Software Foundation; either 0009 * version 2.1 of the License, or (at your option) any later version. 0010 * 0011 * This library is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 * Lesser General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU Lesser General Public 0017 * License along with this library; if not, write to the Free Software 0018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 0019 */ 0020 0021 #ifndef LIBQGIT2_REPOSITORY_H 0022 #define LIBQGIT2_REPOSITORY_H 0023 0024 #include <QtCore/QSharedPointer> 0025 #include <QtCore/QStringList> 0026 #include <QtCore/QObject> 0027 #include <QtCore/QMap> 0028 0029 // #include "libqgit2_export.h" 0030 0031 #include "qgitcommit.h" 0032 #include "qgitdatabase.h" 0033 #include "qgitobject.h" 0034 #include "qgitref.h" 0035 #include "qgittree.h" 0036 #include "qgitindex.h" 0037 #include "qgitstatuslist.h" 0038 #include "qgitstatusoptions.h" 0039 #include "qgitcheckoutoptions.h" 0040 #include "qgitmergeoptions.h" 0041 #include "qgitcherrypickoptions.h" 0042 #include "qgitrebase.h" 0043 #include "qgitrebaseoptions.h" 0044 0045 namespace LibQGit2 0046 { 0047 class Commit; 0048 class Config; 0049 class Tag; 0050 class Tree; 0051 class Blob; 0052 class Signature; 0053 class Credentials; 0054 class Remote; 0055 class Diff; 0056 0057 /** 0058 * @brief Wrapper class for git_repository. 0059 * Represents a Git repository. 0060 * 0061 * @ingroup LibQGit2 0062 * @{ 0063 */ 0064 class LIBQGIT2_EXPORT Repository : public QObject 0065 { 0066 Q_OBJECT 0067 0068 public: 0069 0070 /** 0071 * Construct a wrapper around a libgit2 repository pointer. 0072 * 0073 * If `own` is true, this Repository takes ownership of the pointer, and makes 0074 * sure it is freed when the owner is deleted, unless there are other instances 0075 * sharing the ownership. If `own` is true, the pointer must not be freed manually, 0076 * and must not be passed to another Repository instance also with `own` true. 0077 */ 0078 explicit Repository(git_repository *repository = 0, bool own = false); 0079 0080 /** 0081 * Copy constructor; creates a copy of the object, sharing the same underlaying data 0082 * structure. 0083 */ 0084 Repository(const Repository& other); 0085 0086 /** 0087 * Destruct a previously allocated repository 0088 */ 0089 ~Repository(); 0090 0091 /** 0092 * Look for a git repository and return its path. The lookup start from startPath and 0093 * walk across parent directories if nothing has been found. The lookup ends when the 0094 * first repository is found, or when reaching a directory that is referenced in 0095 * ceilingDirs, or when the filesystem changes (unless acrossFs is true). 0096 * 0097 * The method will automatically detect if the repository is bare (if there is a 0098 * repository). 0099 * 0100 * The function will only return successfully if a repository was found, otherwise an 0101 * exception is thrown, providing an error message. 0102 * 0103 * @param startPath 0104 * The base path where the lookup starts. 0105 * 0106 * @param acrossFs 0107 * If true, then the lookup will not stop when a filesystem device change is detected 0108 * while exploring parent directories. 0109 * 0110 * @param ceilingDirs 0111 * A list of absolute symbolic link free paths. The lookup will stop if any of these 0112 * paths are reached. Note that the lookup always performs on startPath no matter if 0113 * startPath appears in ceilingDirs. 0114 * 0115 * @return The path of the found repository 0116 * @throws LibQGit2::Exception 0117 */ 0118 static QString discover(const QString& startPath, 0119 bool acrossFs = false, 0120 const QStringList& ceilingDirs = QStringList()); 0121 0122 /** 0123 * Constructs a new Git repository in the given folder. 0124 * 0125 * @param path the path to the repository 0126 * @param isBare if true, a Git repository without a working directory is created 0127 * at the pointed path. If false, provided path will be considered as the working 0128 * directory into which the .git directory will be created. 0129 * 0130 * @throws LibQGit2::Exception 0131 */ 0132 void init(const QString& path, bool isBare = false); 0133 0134 /** 0135 * Open a git repository. 0136 * 0137 * The 'path' argument must point to an existing git repository 0138 * folder, e.g. 0139 * 0140 * /path/to/my_repo/.git/ (normal repository) 0141 * objects/ 0142 * index 0143 * HEAD 0144 * 0145 * /path/to/bare_repo/ (bare repository) 0146 * objects/ 0147 * index 0148 * HEAD 0149 * 0150 * The method will automatically detect if 'path' is a normal 0151 * or bare repository or fail is 'path' is neither. 0152 * 0153 * @param path the path to the repository 0154 * @throws LibQGit2::Exception 0155 */ 0156 void open(const QString& path); 0157 0158 /** 0159 * Convenience function for finding and opening a git repository. 0160 * 0161 * Calls discover() with the given arguments, and passes the result to open(). 0162 * 0163 * @throws LibQGit2::Exception 0164 */ 0165 void discoverAndOpen(const QString &startPath, 0166 bool acrossFs = false, 0167 const QStringList &ceilingDirs = QStringList()); 0168 0169 /** 0170 * Retrieve and resolve the reference pointed at by HEAD. 0171 * 0172 * @throws LibQGit2::Exception 0173 */ 0174 Reference head() const; 0175 0176 /** 0177 * Check if a repository's HEAD is detached 0178 * 0179 * A repository's HEAD is detached when it points directly to a commit 0180 * instead of a branch. 0181 * 0182 * @throws LibQGit2::Exception 0183 */ 0184 bool isHeadDetached() const; 0185 0186 /** 0187 * Check if the current branch is unborn 0188 * 0189 * An unborn branch is one named from HEAD but which doesn't exist 0190 * in the refs namespace, because it doesn't have any commit to point to. 0191 * 0192 * @throws LibQGit2::Exception 0193 */ 0194 bool isHeadUnborn() const; 0195 0196 /** 0197 * Check if a repository is empty 0198 * 0199 * An empty repository has just been initialized and contains 0200 * no commits. 0201 * 0202 * @throws LibQGit2::Exception 0203 */ 0204 bool isEmpty() const; 0205 0206 /** 0207 * Check if a repository is bare 0208 * 0209 * @throws LibQGit2::Exception 0210 */ 0211 bool isBare() const; 0212 0213 /** 0214 * The name equals the repositories working directory name. 0215 * In case of a bare repository, the name equals the repositorie's directory. 0216 */ 0217 QString name() const; 0218 0219 /** 0220 * Get the path to the repository 0221 */ 0222 QString path() const; 0223 0224 /** 0225 * Get the path to the working directory 0226 */ 0227 QString workDirPath() const; 0228 0229 /** 0230 * The repositories configuration file. Includes the global git configuration file. 0231 */ 0232 Config configuration() const; 0233 0234 /** 0235 * Lookup a reference by its name in a repository. 0236 * 0237 * @throws LibQGit2::Exception 0238 * @return The reference with the given name 0239 */ 0240 Reference lookupRef(const QString& name) const; 0241 0242 /** 0243 * Lookup a reference by its name in a repository and returns the oid of its target. 0244 * 0245 * @throws LibQGit2::Exception 0246 * @return The OId of the target 0247 */ 0248 OId lookupRefOId(const QString& name) const; 0249 0250 /** 0251 * Lookup a reference by its shorthand name in a repository. 0252 * 0253 * @throws LibQGit2::Exception 0254 * @return The reference with the given name 0255 */ 0256 Reference lookupShorthandRef(const QString& shorthand) const; 0257 0258 /** 0259 * Lookup a commit object from a repository. 0260 * 0261 * @throws LibQGit2::Exception 0262 */ 0263 Commit lookupCommit(const OId& oid) const; 0264 0265 /** 0266 * Lookup a tag object from the repository. 0267 * 0268 * @throws LibQGit2::Exception 0269 */ 0270 Tag lookupTag(const OId& oid) const; 0271 0272 /** 0273 * Lookup a tree object from the repository. 0274 * 0275 * @throws LibQGit2::Exception 0276 */ 0277 Tree lookupTree(const OId& oid) const; 0278 0279 /** 0280 * Lookup a blob object from a repository. 0281 * 0282 * @throws LibQGit2::Exception 0283 */ 0284 Blob lookupBlob(const OId& oid) const; 0285 0286 /** 0287 * Lookup a reference to one of the objects in a repostory. 0288 * 0289 * @throws LibQGit2::Exception 0290 */ 0291 Object lookupAny(const OId& oid) const; 0292 0293 /** 0294 * @brief Lookup an \c Object by a revision specifier. 0295 * 0296 * See `man gitrevisions`, or 0297 * [the Git documentation](http://git-scm.com/docs/git-rev-parse.html#_specifying_revisions) 0298 * for information about the accepted syntax. 0299 * @param revspec the revision specifier. 0300 * @throws LibQGit2::Exception 0301 * @return The found object if any. 0302 */ 0303 Object lookupRevision(const QString &revspec) const; 0304 0305 /** 0306 * Create a new object id reference. 0307 * 0308 * The reference will be created in the repository and written 0309 * to the disk. 0310 * 0311 * @param name The name of the reference 0312 * @param oid The target of the reference 0313 * @param overwrite If there already exists a reference with the same name, whether to overwrite it 0314 * @param message The one line long message to be appended to the reflog 0315 * @throws LibQGit2::Exception 0316 */ 0317 Reference createRef(const QString& name, const OId& oid, bool overwrite = true, const QString &message = QString()); 0318 0319 /** 0320 * Create a new symbolic reference. 0321 * 0322 * The reference will be created in the repository and written 0323 * to the disk. 0324 * 0325 * @param name The name of the reference 0326 * @param target The target of the reference 0327 * @param overwrite If there already exists a reference with the same name, whether to overwrite it 0328 * @param message The one line long message to be appended to the reflog 0329 * @throws LibQGit2::Exception 0330 */ 0331 Reference createSymbolicRef(const QString& name, const QString& target, bool overwrite = true, const QString &message = QString()); 0332 0333 /** 0334 * Create a new commit in the repository. 0335 * 0336 * @param tree The Tree to be used for the new Commit. 0337 * @param parents The parent Commits for the new Commit. Can be empty for the root (initial) 0338 * Commit to the repository. 0339 * @param author Author signature. 0340 * @param committer Committer signature. 0341 * @param message The message for the new Commit. 0342 * @param ref Name of the reference that will be updated to point to this commit. If the 0343 * reference is not direct, it will be resolved to a direct reference. Use "HEAD" to 0344 * update the HEAD of the current branch and make it point to this commit. If the 0345 * reference doesn't exist yet, it will be created. If it does exist, the first 0346 * parent must be the tip of this branch. 0347 * @return The OId of the newly created commit. 0348 * @throws LibQGit2::Exception 0349 */ 0350 OId createCommit(const Tree& tree, const QList<Commit>& parents, const Signature& author, const Signature& committer, const QString& message, const QString& ref = QString()); 0351 0352 /** 0353 * Create a new lightweight tag pointing at a target object 0354 * 0355 * A new direct reference will be created pointing to 0356 * this target object. If `force` is true and a reference 0357 * already exists with the given name, it'll be replaced. 0358 * 0359 * @throws LibQGit2::Exception 0360 */ 0361 OId createTag(const QString& name, 0362 const Object& target, 0363 bool overwrite = true); 0364 0365 /** 0366 * Create a new tag in the repository from an object 0367 * 0368 * A new reference will also be created pointing to 0369 * this tag object. If `overwrite` is true and a reference 0370 * already exists with the given name, it'll be replaced. 0371 * 0372 * @throws LibQGit2::Exception 0373 */ 0374 OId createTag(const QString& name, 0375 const Object& target, 0376 const Signature& tagger, 0377 const QString& message, 0378 bool overwrite = true); 0379 0380 /** 0381 * Delete an existing tag reference. 0382 * 0383 * @throws LibQGit2::Exception 0384 */ 0385 void deleteTag(const QString& name); 0386 0387 /** 0388 * Read a file from the working folder of a repository 0389 * and write it to the Object Database as a loose blob 0390 * 0391 * @throws LibQGit2::Exception 0392 */ 0393 OId createBlobFromFile(const QString& path); 0394 0395 /** 0396 * Write an in-memory buffer to the ODB as a blob 0397 * 0398 * @throws LibQGit2::Exception 0399 */ 0400 OId createBlobFromBuffer(const QByteArray& buffer); 0401 0402 /** 0403 * Creates a new branch to this repository. 0404 * @param branchName The name of the new branch. 0405 * @param target The starting point of the branch, i.e. where the new branch will point to. Defaults to HEAD. 0406 * @param force Controls whether to overwrite an already existing branch. 0407 * @return A reference to the newly created branch 0408 * @throws LibQGit2::Exception 0409 */ 0410 Reference createBranch(const QString &branchName, const Commit &target = Commit(), bool force = false); 0411 0412 /** 0413 * Deletes a local branch. 0414 * @param branchName The name of the branch. 0415 * @throws LibQGit2::Exception 0416 */ 0417 void deleteBranch(const QString &branchName); 0418 0419 /** 0420 * Cherry-picks a commit. 0421 * @param commit The commit to cherry-pick. 0422 * @param opts The options specifying how the cherry-pick is made. 0423 * @throws LibQGit2::Exception 0424 */ 0425 void cherryPick(const Commit &commit, const CherryPickOptions &opts = CherryPickOptions()); 0426 0427 /** 0428 * Create a list with all the tags in the Repository 0429 * which name match a defined pattern 0430 * 0431 * If an empty pattern is provided, all the tags 0432 * will be returned. 0433 * 0434 * @param pattern Standard fnmatch pattern 0435 * @throws LibQGit2::Exception 0436 */ 0437 QStringList listTags(const QString& pattern = QString()) const; 0438 0439 /** 0440 * Create a list with all references in the Repository. 0441 * 0442 * @param pattern Standard fnmatch pattern 0443 * @throws LibQGit2::Exception 0444 */ 0445 QStringList listReferences() const; 0446 0447 /** 0448 * @brief Get the object database behind a Git repository 0449 * 0450 * @return a pointer to the object db 0451 */ 0452 LibQGit2::Database database() const; 0453 0454 /** 0455 * @brief Get the Index file of a Git repository 0456 * 0457 * This is a cheap operation; the index is only opened on the first call, 0458 * and subsequent calls only retrieve the previous pointer. 0459 * 0460 * @throws LibQGit2::Exception 0461 * @return The index file of the repository 0462 */ 0463 Index index() const; 0464 0465 /** 0466 * @brief Get the status information of the Git repository 0467 * 0468 * This function returns the status of the repository entries, according to 0469 * the given options. 0470 * 0471 * @throws LibQGit2::Exception 0472 * @return The list of status entries 0473 */ 0474 StatusList status(const StatusOptions &options) const; 0475 0476 /** 0477 * How two nodes are related to each other in a graph. 0478 */ 0479 struct GraphRelationship { 0480 /** How many steps one node is ahead of another. */ 0481 size_t ahead; 0482 /** How many steps one node is behind of another. */ 0483 size_t behind; 0484 }; 0485 0486 /** 0487 * Solves how the \a local commit is situated in the commit tree in relation to the 0488 * \a upstream commit. Both arguments can be any arbitrary commits in this repository 0489 * but it's useful to think them as the local branch tip commit and its corresponding 0490 * remote branch tip. 0491 * 0492 * @note The \a local commit can be both ahead of and behind from the \a upstream 0493 * commit if the branches have diverged. 0494 * 0495 * @param local The local commit. 0496 * @param upstream The upstream commit. 0497 * @return The relationship between the commits. 0498 * @throws LibQGit2::Exception 0499 */ 0500 GraphRelationship commitRelationship(const Commit &local, const Commit &upstream) const; 0501 0502 /** 0503 * @brief Makes a Diff between two Trees. 0504 * 0505 * Either Tree argument can be a NULL Tree, but not both. 0506 * 0507 * @param oldTree the Tree on the `old' side of the diff. 0508 * @param newTree the Tree on the `new' side of the diff. 0509 * @throws LibQGit2::Exception 0510 * @return The Diff between the provided Trees. 0511 */ 0512 Diff diffTrees(const Tree &oldTree, const Tree &newTree) const; 0513 0514 /** 0515 * Finds a merge base between two commits. 0516 * @param one The first Commit. 0517 * @param two The second Commit. 0518 * @return The merge base Commit. 0519 * @throws LibQGit2::Exception 0520 */ 0521 Commit mergeBase(const Commit &one, const Commit &two) const; 0522 0523 /** 0524 * Merge two trees, producing an Index that reflects the result of the merge. The index 0525 * may be written as-is to the working directory or checked out. If the index is to be 0526 * converted to a tree, the caller should resolve any conflicts that arose as part of the merge. 0527 * 0528 * At least one of \a our or \a their must be a valid Tree. 0529 * 0530 * @param our The tree that reflects the destination tree. 0531 * @param their The tree to merge into the destination tree. 0532 * @param ancestor The common ancestor between the trees. May be null. 0533 * @param opts The merge options. 0534 * @return The merged index. 0535 */ 0536 Index mergeTrees(const Tree &our, const Tree &their, const Tree &ancestor = Tree(), const MergeOptions &opts = MergeOptions()); 0537 0538 /** 0539 * @brief Sets a \c Credentials object to be used for a named remote. 0540 * 0541 * Some remotes require authentication when communicating with them. Authentication 0542 * is performed by using \c Credentials objects. Each named remote can have its own 0543 * \c Credentials object. The credentials for a remote must be set using this method 0544 * before trying to communicate with it. 0545 * 0546 * @param remoteName the name of the remote 0547 * @param credentials the \c Credentials to be used for the remote 0548 */ 0549 void setRemoteCredentials(const QString& remoteName, Credentials credentials); 0550 0551 /** 0552 * Clone a git repository. 0553 * 0554 * Signal cloneProgress(int) is emitted with progress in percent. 0555 * 0556 * @param url URL of the git repository 0557 * @param path non-existing directory for the new clone 0558 * @throws LibQGit2::Exception 0559 */ 0560 void clone(const QString& url, const QString& path); 0561 0562 /** 0563 * Add remote repository. 0564 * 0565 * @param name name of the remote 0566 * @param url URL of the remote git repository 0567 * @param changeUrlIfExists affects the behaviour if the remote already exists: 0568 * if true changes the remote's URL, if false throws an exception. 0569 * @throws LibQGit2::Exception 0570 */ 0571 void remoteAdd(const QString& name, const QString& url, bool changeUrlIfExists = false); 0572 0573 /** 0574 * Gets a named remote from this repository. The caller is responsible for 0575 * managing the returned object. 0576 * @param remoteName the name of the remote 0577 * @param parent the parent for the object that is returned 0578 * @throws LibQGit2::Exception 0579 */ 0580 Remote* remote(const QString &remoteName, QObject *parent = 0) const; 0581 0582 /** 0583 * Fetch from known remote repository. 0584 * 0585 * @param remote Name of the remote repository (e.g. "origin") 0586 * @param head Name of head to fetch (e.g. "master"). If left as the default 0587 * the fetch heads configured for the remote are used. 0588 * @param message The message to insert into the reflogs. If left as the 0589 * default (a null string), a message "fetch <name>" is used , where <name> 0590 * is the name of the remote (or its url, for in-memory remotes). 0591 * @throws LibQGit2::Exception 0592 */ 0593 void fetch(const QString& remote, const QString& head = QString(), const QString &message = QString()); 0594 0595 QStringList remoteBranches(const QString& remoteName); 0596 0597 0598 /** 0599 * Checkout a treeish, i.e. a Commit, Tag or Tree. 0600 * @param treeish the Object to checkout 0601 * @param opts the options used in the checkout 0602 * @throws LibQGit2::Exception 0603 */ 0604 void checkoutTree(const Object &treeish, const CheckoutOptions &opts = CheckoutOptions()); 0605 0606 /** 0607 * Updates files in the index and the working tree to match the content 0608 * of the commit pointed at by HEAD. 0609 * @param opts the options used in the checkout 0610 * @throws LibQGit2::Exception 0611 */ 0612 void checkoutHead(const CheckoutOptions &opts = CheckoutOptions()); 0613 0614 /** 0615 * Checkout a remote branch without creating a local branch. 0616 * 0617 * @param branch branch name 0618 * @param opts the options used in the checkout 0619 * @param remote remote which should be used, default is 'origin' 0620 * @throws LibQGit2::Exception 0621 */ 0622 void checkoutRemote(const QString& branch, const CheckoutOptions &opts = CheckoutOptions(), const QString& remote = "origin"); 0623 0624 /** 0625 * Types of reset operation. 0626 */ 0627 enum ResetType { 0628 Soft, ///< Move the head to the given commit 0629 Mixed, ///< Soft plus reset index to the commit 0630 Hard ///< Mixed plus changes in working tree discarded 0631 }; 0632 0633 /** 0634 * Sets the current head to the specified \a target oid and optionally 0635 * resets the index and working tree to match. 0636 * 0637 * @param target the committish to which the HEAD should be moved to 0638 * @param type what kind of reset should be performed 0639 * @throws LibQGit2::Exception 0640 */ 0641 void reset(const Object &target, ResetType type = Mixed); 0642 0643 /** 0644 * Initializes a rebase object for rebasing the changes in \a branch 0645 * relative to \a upstream onto another branch. 0646 * 0647 * @param branch The terminal commit to rebase 0648 * @param upstream The commit to begin rebasing from, or \c null to rebase all 0649 * reachable commits 0650 * @param onto The branch to rebase onto, or \c null to rebase onto the given 0651 * upstream 0652 * @param opts Options to specify how rebase is performed 0653 * @return The initialized rebase object 0654 * @throws LibQGit2::Exception 0655 */ 0656 Rebase rebase(const Reference &branch, const Reference &upstream, const Reference &onto, const RebaseOptions &opts); 0657 0658 /** 0659 * Checks if the repository's ignore rules would ignore the given \a path. 0660 * 0661 * If \a path is relative it is considered to be relative to the Repository's 0662 * working directory. If \a path is absolute it must point to a location 0663 * within this Repository's working directory or an exception is thrown. 0664 * 0665 * @throws LibQGit2::Exception 0666 */ 0667 bool shouldIgnore(const QString &path) const; 0668 0669 struct Identity { 0670 QString name; 0671 QString email; 0672 }; 0673 0674 /** 0675 * Set the identity to be used for writing reflogs. 0676 * 0677 * @param id The name and email to use for the reflog entries 0678 * 0679 * If both \c name and \c email are set in the given \a id, then \a id will be 0680 * used to write to the reflog. Set either \c name or \c email to empty string 0681 * to unset. When unset, the identity will be taken from the repository's 0682 * configuration. 0683 * 0684 * @throws LibQGit2::Exception 0685 */ 0686 void setIdentity(const Identity &id); 0687 0688 /** 0689 * Retrieve the configured identity to use for reflogs. 0690 * 0691 * @throws LibQGit2::Exception 0692 */ 0693 Identity identity() const; 0694 0695 git_repository* data() const; 0696 const git_repository* constData() const; 0697 0698 signals: 0699 void cloneProgress(int); 0700 void fetchProgress(int); 0701 0702 private: 0703 class Private; 0704 QSharedPointer<Private> d_ptr; 0705 Q_DECLARE_PRIVATE() 0706 }; 0707 0708 /**@}*/ 0709 } 0710 0711 #endif // LIBQGIT2_REPOSITORY_H