aboutsummaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.test/tst/org/eclipse/jgit/api
Commit message (Collapse)AuthorAgeFilesLines
* AddCommand: implement --all/--no-allThomas Wolf2025-02-261-4/+14
| | | | | | | | | | | | | | | | | | | Command-line git stages deletions if file paths are given. (i.e., --all is implied.) File paths are also optional if --update or --all (or --no-all) are given. Add a setter and getter for an "all" flag on AddCommand. Check consistency with the "update" flag in call(). Make file paths optional (imply a "." path) if update is set or if setAll() had been called. If file paths are given, set the all flag. Stage deletions if update is set, or if the "all" flag is set. Add the C git command-line options for the "all" flag to jgit.pgm.Add. Bug: jgit-122 Change-Id: Iedddedcaa2d7a2e75162454ea047f34ec1cf3660
* Merge changes I83adebe5,Ibbc9ba97Matthias Sohn2025-02-252-0/+118
|\ | | | | | | | | | | * changes: DirCacheCheckout.preScanOneTree: consider mode bits Merge: improve handling of case-variants
| * DirCacheCheckout.preScanOneTree: consider mode bitsThomas Wolf2025-02-091-0/+26
| | | | | | | | | | | | | | | | If only the file mode is changed, it's still a change and we must check out the entry from the commit. Bug: jgit-138 Change-Id: I83adebe563fcdb4cbe330edb44884d55ed463c2c
| * Merge: improve handling of case-variantsThomas Wolf2025-02-091-0/+92
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Ensure that on a case-insensitive filesystem a merge that includes a rename of a file from one case variant to another does not delete the file. Basically make sure that we don't delete files that we had marked under a case variant as "keep" before, and ensure that when checking out a file, it is written to the file system with the exact casing recorded in the git tree. Bug: egit-76 Change-Id: Ibbc9ba97c70971ba3e83381b41364a5529f5a5dc
* | DescribeCommand: Add exclusion matches using setExclude()Jonathing2025-02-251-0/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | As of right now, the describe command in JGit only supports adding matches for tag inclusion. It does not support adding matches for excluding tags, which is something that can be done with git on the command line using the "--excludes" flag. This change adds a sister method to setMatches(), called setExcludes(), which does exactly that. A few preliminary tests have also been included in DescribeCommandTest. Change-Id: Id1449c7b83c42f1d875eabd5796c748507d69362 Signed-off-by: Jonathing <me@jonathing.me>
* | Replace usage of deprecated Config#getEnum methodMatthias Sohn2025-02-172-17/+11
| | | | | | | | | | | | | | Need to make DirCacheVersions public otherwise Config#allValuesOf cannot invoke its #values method via introspection. Change-Id: Id11a6fdbe7ce3d84f04bf47e98746424dcc761b4
* | BlameGeneratorTest: Extract "file.txt" to a constantIvan Frade2025-02-141-16/+20
|/ | | | | | | | | | Following change will add many tests, all using the same "file.txt" and they read better with a constant. Extract it now, so we have a clean change with only new tests without modifying the old ones. Change-Id: Ib5de86ce434358e8ce8c0514f76010dca31bdd6b
* RefDatabase#getReflogReader(String): use #exactRef to resolve refNameMatthias Sohn2025-01-276-17/+21
| | | | | | Don't accept short ref names anymore which is more predictable. Change-Id: I5e7323c610c68b25facd6f2286456716d8e6cf1a
* Deprecate Repository#getReflogReader methodsMatthias Sohn2025-01-2711-97/+134
| | | | | | instead use Repository.getRefDatabase().getReflogReader(). Change-Id: I5e66a512c12e11d0ec3275fffde4adb8483430f2
* RebaseCommandTest: replace deprecated PersonIdent constructorMatthias Sohn2024-12-291-6/+11
| | | | Change-Id: Ib5e367c88662defc0471a0487a576bb4b750b778
* GarbageCollectCommandTest: replace deprecated GitDateParserMatthias Sohn2024-12-291-11/+6
| | | | Change-Id: Ide7f67345fa9a63da16562eed76ca5b2a88b8f8a
* GarbageCollectCommand, GC: use java.time APIMatthias Sohn2024-12-282-2/+4
| | | | | | | | | We are moving away from the old java.util.Date API to the java.time API. Add GitTimeParser#parseInstant to support this. Change-Id: I3baeafeda5b65421dc94c1045b0ba576d4f79662
* CommitCommandTest: use java.time APIMatthias Sohn2024-12-251-7/+8
| | | | | | | We are moving away from the old java.util.Date API to the java.time API. Change-Id: I44947d26086396b0779ce6e1f9b9f30375032388
* ArchiveCommandTest: add more detailed message if test failedXenoAmess2024-12-131-1/+4
| | | | Change-Id: I05230cd79d5b744bd1b37a2fb5ba69a8ad6bab62
* RevertCommand: use only first line in revert commit messageThomas Wolf2024-12-111-3/+6
| | | | | | | | | | | | | | | C git uses only the first line of the title paragraph of the reverted commit to build the title of the revert commit. Align the JGit behavior with that. Since git 2.43.0, a revert of a revert uses a title "Reapply "xxx"" instead of "Revert "Revert "xxx""".[1] This is _not_ implemented in this change. [1] https://github.com/git/git/commit/883cb1b8f86d Bug: jgit-117 Change-Id: I030092c6b9447bb738e6d761af5ce50df58cc6d3
* Submodules: use relative paths for worktree and gitdirSimon Eder2024-12-111-5/+6
| | | | | | | | | | | | | | | | Currently absolute paths are used for a submodules 'worktree' and 'gitdir'. This has drawbacks if a git repository containing submodules is copied to a different location. Enable using relative paths when creating a file-based repository. Add optional relative path support to the clone and init commands, and use it in the submodule commands to generate relative paths. The new implementation mimics the cgit behavior which also uses relative paths instead of absolute ones. Bug: jgit-78 Change-Id: I31c5a938d5cbc030d273fc649c94ee0c90b4ce01
* PullCommandTest: assert git status in some simple testsMatthias Sohn2024-11-141-0/+7
| | | | | Bug: jgit-107 Change-Id: I54856849df7c6959ccc2b6f10de510950d3da401
* [errorprone] Remove deprecated security managerIvan Frade2024-11-012-299/+0
| | | | | | | | | | | | | Errorprone warns about this deprecated classes. The recommendation is stop using SecurityManager all together. The Security Manager is deprecated and subject to removal in a future release. There is no replacement for the Security Manager. See JEP 411 [1] for discussion and alternatives. [1] https://openjdk.org/jeps/411 Change-Id: I3c67136e97d13cf24b85e41d94408631c26e8be8
* Signing: refactor interfacesThomas Wolf2024-08-241-16/+57
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a big API-breaking change cleaning up the signing interfaces. Initially, these interfaces were GPG/OpenPGP-specific. When EGit added new signers and signature verifiers that called an external GPG executable, they were found inadequate and were extended to be able to pass in the GpgConfig to get access to the "gpg.program" setting. With the introduction of X.509 S/MIME signing, it was discovered that the interfaces were still not quite adequate, and the "Gpg" prefix on the class names were confusing. Since 7.0 is a major version bump, I'm taking this chance to overhaul these interfaces from ground up. For signing, there is a new Signer interface. With it goes a SignerFactory SPI interface, and a final Signers class managing the currently set signers. By default, signers for the different signature types are created from the signer factories, which are discovered via the ServiceLoader. External code can install its own signers, overriding the default factories. For signature verification, exactly the same mechanism is used. This simplifies the setup of signers and signature verifiers, and makes it all more regular. Signer instances just get a byte[] to sign and don't have to worry about ObjectBuilders at all. SignatureVerifier instances also just get the data and signature as byte[] and don't have to worry about extracting the signature from a commit or tag, or about what kind of signature it is. Both Signers and SignatureVerifiers always get passed the Repository and the GpgConfig. The repository will be needed in an implementation for SSH signatures because gpg.ssh.* configs may need to be loaded explicitly, and some of those values need the current workspace location. For signature verification, there is exactly one place in core JGit in SignatureVerifiers that extracts signatures, determines the signature type, and then calls the right signature verifier. Change RevTag to recognize all signature types known in git (GPG, X509, and SSH). Change-Id: I26d2731e7baebb38976c87b7f328b63a239760d5 Signed-off-by: Thomas Wolf <twolf@apache.org>
* Add worktrees read supportJanne Valkealahti2024-07-142-1/+193
| | | | | | | | | | | | | | | | | | | | | | | | Based on deritative work done in Andre's work in [1]. This change focuses on adding support for reading the repository state when branches are checked out using git's worktrees. I've refactored original work by removing all unrelevant changes which were mostly around refactoring to extract i.e. constants which mostly created noise for a review. I've tried to address original review comments: - Not adding non-behavioral changes - "HEAD" should get resolved from gitDir - Reftable recently landed in cgit 2.45, see https://github.com/git/git/blob/master/Documentation/RelNotes/2.45.0.txt#L8 We can add worktree support for reftable in a later change. - Some new tests to read from a linked worktree which is created manually as there's no write support. [1] https://git.eclipse.org/r/c/jgit/jgit/+/163940/18 Change-Id: Id077d58fb6c09ecb090eb09d5dbc7edc351a581d
* [errorprone] Fix pattern UseCorrectAssertInTestsMatthias Sohn2024-04-291-3/+5
| | | | | | See https://errorprone.info/bugpattern/UseCorrectAssertInTests Change-Id: Iffde63ac795ad30c3e7774764cb8189cb089ed86
* [errorprone] Fix pattern CatchFailMatthias Sohn2024-04-291-1/+3
| | | | | | See https://errorprone.info/bugpattern/CatchFail Change-Id: If1c637a420c4e669a5bdbe4abcefc5c3a2b3a43b
* [errorprone] Fix pattern see UnusedVariableMatthias Sohn2024-04-294-20/+17
| | | | | | See https://errorprone.info/bugpattern/UnusedVariable Change-Id: I75d7602af31ed7d3264d2beab2d159cfbf29e7cb
* [errorprone] Fix UnnecessaryParentheses errorsMatthias Sohn2024-04-281-2/+2
| | | | | | See https://errorprone.info/bugpattern/UnnecessaryParentheses Change-Id: I783fd24286ec1bd55efbf21d05758465f4af87ee
* RebaseCommand: fix stopping on root commit conflictsThomas Wolf2024-01-281-0/+34
| | | | | | | | | If rebasing runs into a conflict when applying a root commit from an independent branch, there is no parent commit. Write an empty patch file in that case like C git does. Bug: jgit-6 Change-Id: I315313673d2abf29639d7d96c958d599961ba276 Signed-off-by: Thomas Wolf <twolf@apache.org>
* CherryPick: add ability to customise cherry-picked commit messageDmitrii Naumenko2024-01-281-0/+185
| | | | | | | | | | | | | | | | | Originally I wanted to support a feature similar to `-x` options from https://git-scm.com/docs/git-cherry-pick#_options. The idea was to append original commit hash in this format: ``` my original commit message (cherry picked from commit 75355897dc28e9975afed028c1a6d8c6b97b2a3c) ``` This can be useful information in some integrations. I decided to make it in a more generic way and pass custom `CherryPickCommitMessageProvider` implementation. One of the two default implementations can append original commit hash Change-Id: Id664e8438b0b76c5cb9b58113887eec04aa6f611
* Fix branch ref exist checkflorian.signoret2023-11-181-0/+15
| | | | | | | | | When a tag with the same name as the branch exists, the branch creation process should work too. We should detect that the branch already exists, and allow to force create it when the force option is used. Bug: 582538 Change-Id: I3b350d03be8edcde10e97b2318343240ca896cb0
* RebaseCommand: return correct status on stash apply conflictsThomas Wolf2023-10-131-1/+52
| | | | | | | | Ensure that also the fast-forward cases return status STASH_APPLY_CONFLICTS when applying the stash produces conflicts. Bug: 582526 Change-Id: Ib989ff431dca6e301eb05156ca054a7115fa6ad5 Signed-off-by: Thomas Wolf <twolf@apache.org>
* RevertCommand: support for inserting a Gerrit change IDThomas Wolf2023-09-081-0/+37
| | | | | | | Add a setter for the flag to be passed through to the CommitCommand. Bug: 342790 Change-Id: I87548d7c2742af8af5ef6105115e3ab9c58d1d9f Signed-off-by: Thomas Wolf <twolf@apache.org>
* Remove unnecessary @SuppressWarnings("serial")Matthias Sohn2023-07-161-1/+1
| | | | Change-Id: Ib07fd89541dbd4b5095d49b2696429cbacc5bb4c
* Fix all Javadoc warnings and fail on themAntoine Musso2023-06-161-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes all the javadoc warnings, stops ignoring doclint 'missing' category and fails the build on javadoc warnings for public and protected classes and class members. Since javadoc doesn't allow access specifiers when specifying doclint configuration we cannot set `-Xdoclint:all,-missing/private` hence there is no simple way to skip private elements from doclint. Therefore we check javadoc using the Eclipse Java compiler (which is used by default) and javadoc configuration in `.settings/org.eclipse.jdt.core.prefs` files. This allows more fine grained configuration. We can reconsider this when javadoc starts supporting access specifiers in the doclint configuration. Below are detailled explanations for most modifications. @inheritDoc =========== doclint complains about explicits `{@inheritDoc}` when the parent does not have any documentation. As far as I can tell, javadoc defaults to inherit comments and should only be used when one wants to append extra documentation from the parent. Given the parent has no documentation, remove those usages which doclint complains about. In some case I have moved up the documentation from the concrete class up to the abstract class. Remove `{@inheritDoc}` on overriden methods which don't add additional documentation since javadoc defaults to inherit javadoc of overridden methods. @value to @link =============== In PackConfig, DEFAULT_SEARCH_FOR_REUSE_TIMEOUT and similar are forged from Integer.MAX_VALUE and are thus not considered constants (I guess cause the value would depends on the platform). Replace it with a link to `Integer.MAX_VALUE`. In `StringUtils.toBoolean`, @value was used to refer to the `stringValue` parameter. I have replaced it with `{@code stringValue}`. {@link <url>} to <a> ==================== @link does not support being given an external URL. Replaces them with HTML `<a>`. @since: being invalid ===================== org.eclipse.jgit/src/org/eclipse/jgit/util/Equality.java has an invalid tag `@since: ` due to the extra `:`. Javadoc does not complain about it with version 11.0.18+10 but does with 11.0.19.7. It is invalid regardless. invalid HTML syntax =================== - javadoc doesn't allow <br/>, <p/> and </p> anymore, use <br> and <p> instead - replace <tt>code</tt> by {@code code} - <table> tags don't allow summary attribute, specify caption as <caption>caption</caption> to fix this doclint visibility issue ======================== In the private abstract classes `BaseDirCacheEditor` and `BasePackConnection` links to other methods in the abstract class are inherited in the public subclasses but doclint gets confused and considers them unreachable. The HTML documentation for the sub classes shows the relative links in the sub classes, so it is all correct. It must be a bug somewhere in javadoc. Mute those warnings with: @SuppressWarnings("doclint:missing") Misc ==== Replace `<` and `>` with HTML encoded entities (`&lt; and `&gt;`). In `SshConstants` I went enclosing a serie of -> arrows in @literal. Additional tags =============== Configure maven-javad0c-plugin to allow the following additional tags defined in https://openjdk.org/jeps/8068562: - apiNote - implSpec - implNote Missing javadoc =============== Add missing @params and descriptions Change-Id: I840056389aa59135cfb360da0d5e40463ce35bd0 Also-By: Matthias Sohn <matthias.sohn@sap.com>
* Bump bazel vesion to 6.2.0David Ostrovsky2023-05-291-6/+2
| | | | | | | | | | | | Also demote severity level for bug pattern: PreferredInterfaceType, aka MutableConstantField: [1] from error to warning. Also fix DoubleBraceInitialization error prone bug pattern [2]. [1] https://errorprone.info/bugpattern/PreferredInterfaceType [2] https://errorprone.info/bugpattern/DoubleBraceInitialization Change-Id: I04b7d0792e67cbc51e3939bd47c2ea13a685cf0d
* Support rebasing independent branchesThomas Wolf2023-04-291-0/+141
| | | | | | | | | With completely independent branches, there is no merge base. In this case, the list of commits must include the root commit of the branch to be rebased. Bug: 581832 Change-Id: I0f5bdf179d5b07ff09f1a274d61c7a0b1c0011c6 Signed-off-by: Thomas Wolf <twolf@apache.org>
* Support cherry-picking a root commitThomas Wolf2023-04-291-35/+67
| | | | | | | | | | | | | Handle the case of the commit to be picked not having any parents. Since JGit implements cherry-pick as a 3-way-merge between the commit to be picked and the target commit, using the parent of the picked commit as merge base, this is super simple: just don't set a base tree. The merger will not find any merge base and will supply an empty tree iterator for the base. Bug: 581832 Change-Id: I88985f1b1723db5b35ce58bf228bc48d23d6fca3 Signed-off-by: Thomas Wolf <twolf@apache.org>
* AddCommand: ability to switch off renormalizationThomas Wolf2023-04-281-1/+71
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | JGit's AddCommand always renormalizes tracked files. C git does so only on git add --renormalize. Especially for git add . and the JGit equivalent git.add().addFilepattern(".").call() this can make a big difference if there are many files, or large files. Add a "renormalize" option to AddCommand. To maintain compatibility with existing uses, this option is "true" by default, and the behavior of AddCommand is as it has always been in JGit. If set to "false", use an IndexDiffFilter (in addition to a path filter, if any). This skips any unchanged files (that are not racily clean) from content checks. Note that changes in CRLF settings or in filters will be ignored for such files if renormalize == false. Add the "--renormalize" option to the Add command in the JGit command line program. For the command-line program, the default is as in C git: renormalize is off by default and enabled only if the option is given. Note that --renormalize implies --update in the command line program, as in C git. In AddCommand, the two settings are independent. Additionally, avoid opening input streams unnecessarily in WorkingTreeIterator.getEntryContentLength() and fix some bogus indentation. Add a simple test that adds 1000 files of 10kB in 10 directories twice and that fails if the second invocation (without any changes) with renormalize=false is not significantly faster. Locally, I observe for that second invocation * git.add().addFilepattern(".").call() ~660ms * git.add().addFilepattern(".").setRenormalize(false).call() ~16ms Bug: 494323 Change-Id: I30f9d518563fa55d7058a48c27c425f3b60aeb4c Signed-off-by: Thomas Wolf <twolf@apache.org>
* Merge branch 'stable-6.5'Matthias Sohn2023-04-281-0/+15
|\ | | | | | | | | | | | | | | | | | | | | | | | | | | * stable-6.5: [bazel] Move ToolTestCase to src folder (6.2) GcConcurrentTest: @Ignore flaky testInterruptGc Fix CommitTemplateConfigTest Fix after_open config and Snapshotting RefDir tests to work with bazel [bazel] Skip ConfigTest#testCommitTemplatePathInHomeDirecory Demote severity of some error prone bug patterns to warnings Parse pull.rebase=preserve as alias for pull.rebase=merges UploadPack: Fix NPE when traversing a tag chain Change-Id: I16e8553d187a8ef541f578291f47fc39c3da4ac0
| * Parse pull.rebase=preserve as alias for pull.rebase=mergesMatthias Sohn2023-04-221-0/+15
| | | | | | | | | | | | | | This ensures backwards compatibility to the old config value which was removed in git 2.34 which JGit followed in Ic07ff954e2. Change-Id: I2b4e27fd71898b6e0e227e406c40682bd9786cd4
* | ListTagCommand: implement git tag --containsMatthias Sohn2023-04-121-0/+44
|/ | | | Change-Id: I07e57ba098eace9656393837fad4cb3590f31b22
* Change config pull.rebase=preserve to pull.rebase=mergesPavel Salamon2023-02-281-12/+12
| | | | | | | | | | | | | | | The native git option to preserve merge commits during rebase has been changed from pull.rebase=preserve to pull.rebase=merges. This changeset in jgit makes the same config change. The old "preserve" option is no longer recognized and is replaced by new option called "merges". This makes jgit's rebase configuration compatible with native git versions 2.34 and newer where the old "preserve" option has been removed. Change-Id: Ic07ff954e258115e76465a1593ef3259f4c418a3
* I/O redirection for the pre-push hookThomas Wolf2022-10-201-1/+52
| | | | | | | | | | | Fix and complete the implementation of calling the pre-push hook. Add the missing error stream redirect, and add the missing setters in Transport and in PushCommand. In Transport, delay setting up a PrePushHook such that it happens only on a push. Previously, the hook was set up also for fetches. Bug: 549246 Change-Id: I64a576dfc6b139426f05d9ea6654027ab805734e Signed-off-by: Thomas Wolf <twolf@apache.org>
* CloneCommand: set HEAD also when not checking outThomas Wolf2022-09-181-4/+31
| | | | | | | CloneCommand, when setNoCheckout(true) was set, did not set HEAD. With C git, "git clone --no-checkout" does. Change-Id: Ief3df7e904ce90829a6345a6c3e9ee6a68486ab0 Signed-off-by: Thomas Wolf <twolf@apache.org>
* Merge "Split out ApplyCommand logic to PatchApplier class"Han-Wen NIenhuys2022-09-151-386/+0
|\
| * Split out ApplyCommand logic to PatchApplier classNitzan Gur-Furman2022-09-151-386/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | PatchApplier now routes updates through the index. This has two results: * we can now execute patches in-memory. * the JGit apply command will now always update the index to match the working tree. Change-Id: Id60a88232f05d0367787d038d2518c670cdb543f Co-authored-by: Han-Wen Nienhuys <hanwen@google.com> Co-authored-by: Nitzan Gur-Furman <nitzan@google.com>
* | Revert "Option to pass start RevCommit to be blamed on to theMatthias Sohn2022-09-061-303/+26
|/ | | | | | | | | | | | BlameGenerator." This reverts commit 5747bba48b22a11beba8ebe0caf13a53d4ca96f2. This is done as a quick fix for the failure of egit tests caused by the introduction of FilteredRevCommit. Bug: 580690 Change-Id: Ia0178bc2de4fc825a81207bbd7979bf3a386c955
* ApplyCommand: fix ApplyResult#updatedFilesHan-Wen Nienhuys2022-08-231-7/+7
| | | | | | | | On executing a copy, mark the destination as updated. On executing a rename, mark both source and destination as updated. Change-Id: Ied5b9b0e5a14eac59a06cdd0961e25e143f50ff0
* Option to pass start RevCommit to be blamed on to the BlameGenerator.Ronald Bhuleskar2022-08-171-26/+303
| | | | | | | | | This can allow passing a FilteredRevCommit which is the filtered list of commit graph making it easier for Blame to work on. This can significantly improve blame performance since blame can skip expensive RevWalk. Change-Id: Ie127cb710d004079e9f53a5802130afdb49a7de1
* Fix adding symlinks to the index when core.symlinks=falseThomas Wolf2022-08-131-0/+41
| | | | | | | | | | With core.symlinks=false, symlinks are checked out as plain files. When such a file is re-added to the index, and the index already contains a symlink there, add the file as a symlink. Previous code changed the index entry to a regular file. Bug: 580412 Change-Id: I5497bedc3da89c8b10120b8077c56bc5b67cb791 Signed-off-by: Thomas Wolf <twolf@apache.org>
* Merge "Revert "Option to pass start RevCommit to be blamed on to the ↵Terry Parker2022-08-031-303/+26
|\ | | | | | | BlameGenerator.""
| * Revert "Option to pass start RevCommit to be blamed on to the BlameGenerator."Ronald Bhuleskar2022-08-031-303/+26
| | | | | | | | | | | | | | | | | | | | This reverts commit 59e8bec6e7705a89b5d0b9c6ac004b323ffa16b0. Reason for revert: The change in https://git.eclipse.org/r/c/jgit/jgit/+/194354 broke the egit test [1]. Calling c.getShortMessage() causes an NPE. [1] https://ci.eclipse.org/egit/job/egit.gerrit/2711/ Change-Id: Iaf5feb35f4bb4c3487b04be15d1fe11376975523
* | Merge "Revert "Adds FilteredRevCommit that can overwrites its parents in the ↵Terry Parker2022-08-031-7/+0
|\ \ | | | | | | | | | DAG.""