Giter VIP home page Giter VIP logo

grgit's Introduction

grgit

CI

NOTE: As of 5.0.0, grgit is published to Maven Central

Project Status

My opinion is that grgit no longer serves a useful purpose in the Gradle ecosystem, given the evolution towards Kotlin DSL and the stronger preference to move build logic into plugins.

However, I understand the backwards compatibility need, so I'm not immediately stopping maintenance. I do consider the plugin feature frozen, and don't anticipate doing any work outside of updating dependencies and limited work to maintain compatibility with new versions of Gradle.

For my own sake, I've already decoupled reckon (which I don't plan to deprecate/archive) from grgit. I anticipate doing the same with gradle-git-publish, but I haven't had the time yet.

For more background on this see my Don't commit to grgit blog post.

Getting Help or Contributing

IMPORANT: I consider this plugin feature complete and don't spend a lot of time on maintenance due to other time commitments. While, I will eventually get to issues or PRs raised, do not expect a timely response. I'm not trying to be rude or dismissive, I only get back to this project periodically (on the order of months, in many cases). Please set your expectations appropriately as you file issues or open PRs.

Please use the repo's issues for all questions, bug reports, and feature requests.

Why do you care?

JGit provides a powerful Java API for interacting with Git repositories. However, in a Groovy context it feels very cumbersome, making it harder to express the operations you want to perform without being surrounded by a lot of cruft.

What is it?

Grgit is a wrapper over JGit that provides a fluent API for interacting with Git repositories in Groovy-based tooling.

"porcelain" commands are the primary scope of what is included. Features that require more user interaction (such as resolving merge conflicts) are intentionally excluded.

It also provides a Gradle plugin to easily get a Grgit instance for the build's repository.

Documentation

NOTE: grgit is available from Maven Central or the Gradle Plugin Portal

Simple Usage in Gradle

Apply the org.ajoberstar.grgit plugin in any project that needs to access a Grgit instance.

NOTE: This plugin eagerly opens a Grgit instance, which may not be needed depending on the tasks you want to run. If this is not desired, see the next section.

plugins {
  id 'org.ajoberstar.grgit' version '<version>'
}

// adds a grgit property to the project (will silently be null if there's no git repo)
tasks.register("describe") {
  doFirst {
    println grgit.describe()
  }
}

More Performant Usage in Gradle

Apply the org.ajoberstar.grgit.service plugin instead of org.ajoberstar.grgit to avoid eagerly resolving the Grgit instance. This works best with custom tasks that accept a Property<GrgitService>.

This approach ensures you only open a Grgit instance when a task is run that uses it.

import org.ajoberstar.grgit.gradle.GrgitService

plugins {
  id 'org.ajoberstar.grgit.service' version '<version>'
}

tasks.register("describe", DescribeTask, grgitService.service)

class DescribeTask extends DefaultTask {
    private final Provider<GrgitService> service

    @Inject
    DescribeTask(Provider<GrgitService> service) {
        this.service = service
        usesService(service)
    }

    @TaskAction
    void execute() {
        println service.get().grgit.describe()
    }
}

Custom Gradle Plugins

If you are writing a custom Gradle plugin, you'll want to use one or both of the following approaches:

  • If you need a Grgit instance representing the repository the project is in, use org.ajoberstar.grgit.service and use the GrgitServiceExtension to access the shared GrgitService. Wire this into any tasks or whatever needs to use the service via Property<GrgitService> for full lazy evaluation benefits.

  • If you need a Grgit instance that's separate from the project's repository, declare your own GrgitService naming it something not prefixed with grgit*.

    Provider<GrgitService> serviceProvider = project.getGradle().getSharedServices().registerIfAbsent("grgit", GrgitService.class, spec -> {
        // use getCurrentDirectory() if you need to search upwards from the provided directory
        spec.getParameters().getCurrentDirectory().set(project.getLayout().getProjectDirectory());
        // or use getDirectory() if you want to specify a specific directory and not search
        spec.getParameters().getDirectory().set(project.getLayout().getBuildDirectory().dir("my-custom-repo"));
        // generally, this should be false, unless you're using getDirectory() choose to have the repo initialized if the directory does not exist
        spec.getParameters().getInitIfNotExists().set(false);
        // I recommend setting this to 1 unless you know better, this will avoid multiple parallel tasks editing the repo at the same time
        // This should be coupled with tasks that use the service calling "usesService()" to register their usage of the service
        spec.getMaxParallelUsages().set(1);
      });
    

Finding versions of grgit

Newest versions are on Maven Central

As of 4.1.1, grgit is published to Maven Central and the Gradle Plugin Portal.

As of 5.0.0, this project is no longer directly published to the Gradle Plugin Portal, but since the portal proxies Maven Central you can still access it through the portal. The only side effect is that the portal will no longer list the latest version. Use this repo or search.maven.org to find the latest version.

Old versions from Bintray/JCenter

This project was previously uploaded to JCenter, which was deprecated in 2021.

In the event that JCenter is unavailable and acess to past versions (4.1.0 and earlier) is needed, I've made a Maven repo available in bintray-backup. Add the following to your repositories to use it.

maven {
  name = 'ajoberstar-backup'
  url = 'https://ajoberstar.org/bintray-backup/'
}

Made possible by lacasseio/bintray-helper in case you have a similar need to pull your old Bintray artifacts.

Acknowledgements

Thanks to everyone who has contributed to the library.

grgit's People

Contributors

adamdubiel avatar afzalive avatar ajoberstar avatar criztovyl avatar donalhenry avatar fvgh avatar helpermethod avatar itoed avatar jblack10101 avatar jbrachtl avatar jlleitschuh avatar jzwolak avatar kamilpabin avatar koncha avatar lbergelson avatar lucas3oo avatar marcinczapla avatar miguelaferreira avatar mithomas avatar odinodin avatar pwielgolaski avatar quentinbrun avatar runningcode avatar sschuberth avatar stebbi avatar supercilex avatar szpak avatar tlinkowski avatar vampire avatar waffle-iron avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grgit's Issues

Status is always returning linux unchanged linux sym links as unstaged modified files

When I run status().isClean() on my repository, it always returns false because I have a symlink in it.

billmag:~/code/github/android-sdk$ git status
On branch feature/release-script
nothing to commit, working directory clean'

The value of Grgit.open('.').status() is:

org.ajoberstar.grgit.Status(staged:org.ajoberstar.grgit.Status$Changes(added:[], modified:[], removed:[]), unstaged:org.ajoberstar.grgit.Status$Changes(added:[], modified:[android-sdk-base/src], removed:[]))

It is a symlink, to elsewhere in the repository, but it's certainly unchanged and I can confirm it works in a fresh checkout:

billmag:~/code/github/android-sdk$ ls -la android-sdk-base/src
lrwxr-xr-x  1 billmag  staff  28 May 19 19:32 android-sdk-base/src -> android-sdk-base-private/src

git describe

There doesn't seem to be a way to access git describe, e.g.:
git describe --tags --always --abbrev=7

This is super-useful for projects that use git tags for their versioning.

Unsupported major.minor version

I'm trying to just open the repo and I get the error. Are there certain requirements on the repo? Here is the code in build.gradle.

import org.ajoberstar.grgit.*
ext.repo = Grgit.open(project.file('.'))

Error:Cause: org/ajoberstar/grgit/Grgit : Unsupported major.minor version 51.0

Deleting the folder of a cloned repository after closing Grgit does not work on Windows

If you clone a local repository via Grgit.clone() and try to delete the repository folder after closing Grgit, the folder isn't deleted as .git/objects/pack/* files still seem to be locked (only on Windows of course).

Here is a small snippet to reproduce the problem:

package org.ajoberstar.grgit

import java.nio.file.Files
import java.nio.file.Path

def Path tempDir = Files.createTempDirectory 'tempfiles'
def File remoteRepo = Files.createTempDirectory(tempDir, 'remoteRepo').toFile() 
def File localRepo = Files.createTempDirectory(tempDir, 'localRepo').toFile()

// Create the remote repository
def Grgit grgitRemote = Grgit.init(dir: remoteRepo)
new File(remoteRepo, 'test.txt') << UUID.randomUUID().toString() + File.separator
grgitRemote.add(patterns: ['test.txt'])
grgitRemote.commit(message: 'Initial commit')

// Create local repository by cloning the 'remote' repository
def Grgit grgitLocal = Grgit.clone(dir: localRepo, uri: remoteRepo)

// Close local repo
grgitLocal.close()

// Close remote repo
grgitRemote.close()

assert(remoteRepo.deleteDir() && !remoteRepo.isDirectory())
assert(localRepo.deleteDir() && !localRepo.isDirectory())

Add Rebase operation

Support rebase similarly to merge, such that any merge conflicts result in an execution failure.

Ranges in log - Can they be one-sided?

I've got a question about the ranges in grgit.log.
I know that I can use the command-line git to do something like

git log v0.0.1 --oneline

to get all the commits from the very beginning to the tag "v0.0.1"

I tried to get the same working with grgit, but I can't figure out how!
Can one of the ranges of grgit.log be skipped (if so, how)?

JgitUtil.resolveTag doesn't account for tags that point to other tags

error   05-May-2015 15:23:28    Caused by: groovy.lang.MissingMethodException: No signature of method: static org.ajoberstar.grgit.util.JGitUtil.convertCommit() is applicable for argument types: (org.eclipse.jgit.revwalk.RevTag) values: [tag 1eca2359f0969e94e04c281666590400aa315508 -----p]
error   05-May-2015 15:23:28    Possible solutions: convertCommit(org.eclipse.jgit.revwalk.RevCommit)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.util.JGitUtil$convertCommit$0.callStatic(Unknown Source)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.util.JGitUtil.resolveTag(JGitUtil.groovy:163)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.util.JGitUtil$resolveTag.call(Unknown Source)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.operation.TagListOp$_call_closure1.doCall(TagListOp.groovy:54)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.operation.TagListOp.call(TagListOp.groovy:53)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.operation.TagListOp.call(TagListOp.groovy)
error   05-May-2015 15:23:28        at java_util_concurrent_Callable$call$0.call(Unknown Source)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.util.OpSyntaxUtil.tryOp(OpSyntaxUtil.groovy:45)
error   05-May-2015 15:23:28        at org.ajoberstar.grgit.service.TagService.methodMissing(TagService.groovy:52)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.infrastructure.git.GitRepository.currentPosition(GitRepository.groovy:144)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.scm.ScmRepository$currentPosition$0.call(Unknown Source)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionResolver.resolveVersion(VersionResolver.groovy:19)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionResolver$resolveVersion.call(Unknown Source)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionService.currentDecoratedVersion(VersionService.groovy:34)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionService$currentDecoratedVersion.call(Unknown Source)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionConfig.getVersion(VersionConfig.groovy:82)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionConfig_Decorated.getVersion(Unknown Source)
error   05-May-2015 15:23:28        at org.gradle.api.internal.BeanDynamicObject$MetaClassAdapter.getProperty(BeanDynamicObject.java:153)
error   05-May-2015 15:23:28        at org.gradle.api.internal.BeanDynamicObject.getProperty(BeanDynamicObject.java:107)
error   05-May-2015 15:23:28        at org.gradle.api.internal.CompositeDynamicObject.getProperty(CompositeDynamicObject.java:78)
error   05-May-2015 15:23:28        at pl.allegro.tech.build.axion.release.domain.VersionConfig_Decorated.getProperty(Unknown Source)

Support for rm -r

Recursive deletion is important to mimic add --all as specified in #53, however it is also useful for re-applying a .gitignore file.

Feedback after successful operation

Some operations (like push) generate feedback which in some cases could useful to get know (here that remote branch was updated and a few (and which) tags were pushed on --follow-tags). That could be especially helpful when tracking down problems with Git operations running on CI server in the Continuous Delivery process.

jgit returns those structures (like PushResult), but it would be probably time consuming to map it into some GrGit structures, so maybe there could be added verbose or verboseResults switch to display on a console toString from that results (in case of push Collection<RemoteRefUpdate>). WDYT?

git branch name

There doesn't seem to be a way to access the current branch name, e.g.:
git rev-parse --abbrev-ref HEAD

This is super-useful for projects that include the branch-name in their versioning.

Support for add --all

One of the most important features I use in git is add --all, which removes files that have been deleted from the index. This can technically be simulated with remove --cached -r . followed by add, but running one operation is better than two.

access JGit

For features that grgit doesn't have, it might be useful to be able to access the underlying JGit implementation. Something like Grgit.open('path/to/my/repo').getJGit()

Could not find property MergeOp

Hi,

I'm encountering this error:

* What went wrong:
Execution failed for task ':onlyFFmerge'.
> Could not find property 'MergeOp' on task ':onlyFFmerge'.

This is my script:

buildscript {
    repositories { mavenCentral() }
    dependencies { classpath "org.ajoberstar:grgit:0.2.2" }
}
import org.ajoberstar.grgit.*

task onlyFFmerge(){
    doLast{
      def repo = Grgit.open(".")
      repo.merge(mode: MergeOp.Mode.ONLY_FF)
      // This works fine:
      // repo.merge(head: "myBranch")
    }
}

Is this a bug or am I missing something?

Thanks.

Support for passing username/password in URL for HTTPS connections

Git itself supports passing username or/and password in HTTPS connection URL, e.g.

https://user@pass:host.xz/path/to/repo.git/

That mechanism is used for example when pushing to GitHub from CI server with security tokens.

There is a simple workaround - passing username/password in Credential object, but it could be hard to apply/not supported when GrGit is used through the 3rd tools. Therefore it would be good to support also credentials encoded in the URL.

Can GrGit do this: git tag --points-at HEAD

Hi, sorry I contact you like this, I couldn't find a better way. I can do this:

def repo = Grgit.open(project.baseDir)
def tags = repo.tag.list()
println tags

but I would need to get the tag on HEAD, just like git tag --points-at HEAD. Is that possible?

Add orphan option in checkout

I would like to perform a git checkout --orphan <new_branch> from a Gradle build script. Would this be feasible to implement?

Thanks for grgit!

Add support for tree in Commit

We would need to get the info about the tree in git since we use gerrit/zuul which merges and the tree is the only unique identifier.

git cat-file -p HEAD
shows the tree info among other information.

My usecase is:
grgit.head().tree

Remote and branch options for pull

Git supports pulling from a non-origin remote with pull and a different branch, can this be added?

Example of git command: git pull upstream feature/not-master

Support authentication in url

I am still much confused by the authentication. I want to push to a remote, and I have the username and password contained in the remote URL, like https://<username>:<password>@github.com/xxx/xxx.git, but it only works on my console. Every time I run the groovy script repo.push(), there's a window asking about username and password. So is there a way to make it use the password in the URL? Thanks!

git rev-list

A common practice with Android projects is to derive the version code from the rev-list, e.g.
git rev-list HEAD --first-parent --count

grgit should have some way to access the rev-list, or as least a convenience method that gets the count.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.