Committing and Pushing to GitHub using JGit - Bare Repo? - java

Today I signed up for github, and converted an existing filesystem into a git repo using the technique described here:
http://crashingdaily.wordpress.com/2009/09/02/initing-a-new-remote-git-repository-with-existing-files/
Most importantly (I think) it involved this line:
git --bare init
I then followed the rest of github.com's setup tutorials (this was part of that) and was done. The existing filesystem was within Dropbox, so I performed the same setup on the two other machines that use the filesystem (now a git repo).
Tonight I tried to get JGit to add a file, commit it and then push it. Here's the gist of the code up until the point it breaks:
FileRepositoryBuilder builder = new FileRepositoryBuilder();
Repository repository = builder.setGitDir(new File("path/to/my/repo"))
.readEnvironment() // scan environment GIT_* variables
.findGitDir() // scan up the file system tree
.build();
Git git = new Git(repository);
AddCommand add = git.add();
try{
add.addFilepattern("PlayState.as").call();`
This is basically taken verbatim from a JGit tutorial, incidentally. It throws an exception at that last quoted line and states:
org.eclipse.jgit.errors.NoWorkTreeException: Bare Repository has neither a working tree, nor an index
at org.eclipse.jgit.lib.Repository.getIndexFile(Repository.java:838)
at org.eclipse.jgit.lib.Repository.lockDirCache(Repository.java:886)
at org.eclipse.jgit.api.AddCommand.call(AddCommand.java:136)
at flipa.FLIPAGame.writeToFlixel(FLIPAGame.java:77)
at flipa.FLIPAGame.main(FLIPAGame.java:58)
Now, I'm not saying it's unreasonable to claim that, because truth be told I am not the best friend of version control. I get that a bare repo is one with just git in and no other files, but it seems to me that now it has files in it. I've already manually added, committed and pushed to github using git from Terminal. So I can't immediately see why it won't even recognise the repo.
Any takers?
EDIT - For clarification, killing off this repo is no big deal if someone can propose another solution. I want a git repo to use the filesystem in my dropbox, and be able to commit to github via Java.

For your code, I would say the options setGitdir() and findGitDir() are not supposed to be used at the same time.
To retrieve an existing repository, I use findGitDir(new File("path/to/my/repo") and it is enough.

This sounds like you've added the files to a bare repository. A bare repository should not be touched, except through git push and pull commands (or git commands in general). As a guide, I don't ever look in my bare repositories.
It should be used as a central location. Once you've created the git bare repo, you should clone it and then work on it from the clone, pushing and pulling from the clone.
$ cd /dropbox/repo
$ git init --bare
$ cd /workdir
$ git clone file:///dropbox/repo
$ add files in here
$ git add .
$ git commit -m "initial version"
$ git push origin master
$ more changes here
$ git add etc.
The difference between this and github is the git clone, which then comes from a different place. To be quite honest, unless you've got a really good reason to have a local copy, I'd just forget about the dropbox repo and just use github.

Your third line of code, right after .build(); should be:
repository.create();
This is the equivalent of the "git init" command.

In your case since you are working in an existing directory, you may find more convenient using Git.open().
Git git = Git.open(new File(".git"));
System.out.println("Repository: " + git.getRepository().toString());
//Do some git action for instance:
RevCommit rev = git.commit().setAmend(true)
.setAuthor("me", "me#mail.com")
.setMessage("Testing commit from jGit").call();
git.close();
Source: Article written by RĂ¼diger Herrmann available in Code Affine.

Related

JGit - Checkout to specific remote commit ID hash

I'm trying to access specific commitId files using the JGit library.
Using Git command this would look like : git checkout [COMMIT_ID], then my folder would checkout to the specific commit and get any file from it.
Now using JGit, I'm calling the Git.cloneRepository() function to get my repository (can't clone from a specific commitId here I think sadly). Then I'm trying to checkout using this : gitRepo.checkout().setName(gitCommitId).call()
But this is getting me the folliwing error : Remote origin did not advertise Ref for branch COMMIT_ID. This Ref may not exist in the remote or may be hidden by permission settings.
Which is odd because the CLI git command does work.
Maybe it is not something feasible through this lib but I didn't find anything else on the web yet.
setName(String name) is more for branch name, not for commit ID.
setStartPoint(RevCommit startCommit) does use a commit ID.
As seen here, git.checkout().setAllPaths(true).setStartPoint(gitCommitId).call(); would work better after your clone.

Git merging two local branches and pushing one of that local branch to upstream remote 'origin' branch

I am having an issue of my git HEAD going backwards by certain days length when I do the following
Complete my changes in my Sprint1.4Branch and add all files, then commit my files to local branch of Sprint1.4Branch ($git commit -m "message")
Then check out to "LifeGoals" local branch($ git checkout LifeGoals). LifeGoals is the branch(created by cloning from the git repository) from which I created my local Sprint1.4Branch to do my sprint specific user story coding.
Merge Sprint1.4Branch in to local LifeGoals ( $ git merge Sprint1.4Branch)
Push local LifeGoals branch to remote 'origin' ($git push origin LifeGoals) Note: Only LifeGoals has upstream connection to remote origin. Sprint1.4Branch is purely local branch alone.
Check out to local branch of 'Sprint1.4Branch' to get back in to local branch to make further changes. ($git checkout Sprint1.4Branch)
I see that some of the files in my IDE are moved to a status which is few days back wards.
What is the mistake I am doing ?
At least I have my commits to go back to, I believe.

Jenkins execute shell on job's executor during CONFIGURATION time (and access workspace)

I would like to create a simple Jenkins plugin.
Basically it is a custom build step (Builder extension) with a dropdown list. The trick is that I want to fill this dropdown list from the result of a shell script/command executed during configuration time.
Here is my method stub.
public ListBoxModel doFill...Items(#AncestorInPath AbstractProject project) {
// determine workspace
// project.getSomeWorkspace() or project.getSomeWorkspace().getRemote()
...
// invoke some shell commands
String[] results = ...
ListBoxModel items = new ListBoxModel();
for (String item : results) {
items.add(item);
}
return items;
}
My questions are the following:
If there are slaves too, does Jenkins maintain 2 workspaces (so the freshest source code will exist both locations?
My understanding is that (after the first build) there are always two workspaces: on the master there are meta informations (and source code too?), on the slave there are the source code and the build intermediates, information, artifacts. (unless we extract artifacts or use the copy-to-slave-plugin)
Where will be the workspace what I get with the project.getSomeWorkspace() or project.getSomeWorkspace().getRemote()? (master/slave?)
How can I invoke a shell command on the machine that WILL execute the build? Or at least is there a way to choose the master / one of the slaves particularly? (Suppose that I already configured a label on which group of machines I want to run the job.)
I don't have access to AbstractBuild, BuildListener and Launcher (since they don't exist yet...)
How can I find out which properties can I get with #AncestorInPath.
I understand that this is a shorthand, an injection from the StaplerRequest invoked by Jenkins? How can I see the request?
It is important where the execution of the shell command takes place, even if there are two identical workspaces on master and slave. In my case there may be a Windows master (in the future) and an OSX slave. I do need the OSX to run my commands. (Currently there is only a master on OSX.)
EDIT:
Here is an example, part of what I am trying to do. I created a simple Xcode project in Swift (JenkinsSwift). In terminal from the project's directory I can issue the following command:
xcodebuild -project JenkinsSwift.xcodeproj -list
And get the following response:
Targets:
JenkinsSwift
JenkinsSwiftTests
Build Configurations:
Debug
Release
If no build configuration is specified and -scheme is not passed then "Release" is used.
Schemes:
JenkinsSwift
During configuration time I want to navigate to the project workspace on an OS X machine I want to issue the previous command. This way I could parse this response and allow the users to choose a Target / Configuration / Scheme during configuration. (Of course this can be done manually from with bash scripts, but I wanted to make it easier.)
This works differently, there is no workspace for a job by default. One is allocated as soon as build is run on the build machine (be it master or a slave). There can be any number of workspaces for a given job based on where and how many times the job run. Though, there is no guarantee there will be some on master. Do not confuse terms workspace (living on build machine) and build result directory on master.
Project#getSomeWorkspace(), gives you a workspace used by some past build. Note, this is done on purely best effort bases as there might be none.
There is no way to know where the build will run at the configuration time unless you tie the job to one particular machine. See hudson.model.Node#createLauncher(TaskListener) on how to run processes in Jenkins grid.
#AncestorInPath allows you to inject some of the domain object that ware traversed by stapler during URL binding. You should not try to inject anything that might not be part of the url. There is no way known to me for you to inject the request, stapler uses the one that initiated the action method invocation.
The bottom line is that what you try sounds highly unusual. Perhaps there is an easier way to solve your original problem.

How to install delete-project plugin in gerrit?

I want to install delete-project plugin to my gerrit server.
As per the latest version, I should clone it from google source and use buck build.
I cloned it and my buck is also ready.
What are the steps to be followed to build the delete project plugin and add it to my gerrit server.
I tried
buck build .
in the cloned source of delete-project. But, I am getting the following error
Traceback (most recent call last):
File "/home/gerrit/buck/src/com/facebook/buck/parser/buck.py", line 872, in <module>
main()
File "/home/gerrit/buck/src/com/facebook/buck/parser/buck.py", line 867, in main
buildFileProcessor.process(build_file.rstrip())
File "/home/gerrit/buck/src/com/facebook/buck/parser/buck.py", line 800, in process
build_env['BUILD_FILE_SYMBOL_TABLE'])
File "/home/gerrit/delete-project/././BUCK", line 1, in <module>
gerrit_plugin(
NameError: name 'gerrit_plugin' is not defined
BUILD FAILED: Parse error for BUCK file ././BUCK: End of input at line 1 column 1
Please help
I managed to install delete-project plugin after following this thread:
https://groups.google.com/forum/#!topic/repo-discuss/hbBc2TUhl7s
and then install according to:
https://gerrit-review.googlesource.com/Documentation/cmd-plugin-install.html
P.S. I build the jar following the below steps:
git clone --recursive https://gerrit.googlesource.com/gerrit
cd gerrit
git clone --recursive https://gerrit.googlesource.com/plugins/delete-project
buck build delete-project:delete-project
You should then find the delete-project.jar in buck-out/gen/delete-project/delete-project.jar
Download the delete-project.jar from the build that matches your Gerrit version on https://gerrit-ci.gerritforge.com
Copy it to gerrit/plugins directory.
Restart Gerrit.
I managed to successfully build delete-project plugin with a slight modification on #DavidCheung answer:
git clone https://gerrit.googlesource.com/gerrit
cd gerrit/plugins
git clone https://gerrit.googlesource.com/plugins/delete-project
buck build delete-project:delete-project
You should then find the delete-project.jar in ../buck-out/gen/delete-project/delete-project.jar
I struggled with the answers above, maybe due to having a new version of Gerrit (2.11.2). The steps in this document all worked for me, with one addition - you need to add the --recursive flag when you clone the Gerrit source code so that it includes the source for the standard plugins:
git clone --recursive https://gerrit.googlesource.com/gerrit
Also, make sure to check out the correct Git branch for your Gerrit version,e.g.
git fetch origin stable-2.11:stable-2.11
git checkout stable-2.11
This is how to build a delete-project.jar for gerrit 3.x.
Install bazel.
Download gerrit source code with git clone --recursive https://gerrit.googlesource.com/gerrit
cd gerrit
bazel build plugins/delete-project:delete-project
The last step will generate bazel-bin/plugins/delete-project/delete-project.jar which then can be installed as described in the official documentation.

How to access ChangeSets in Eclipse (Mylyn/Team)?

I want to access the ChangeSets of SVN, CVS and Git programatically via Java. I.e. I want the data which is shown in the "Synchronize"-view.
I tried several approaches to find the correct usage in the code, and here's the few documentation I could find (but without success):
I managed to access the Synchronize-View via TeamUI.getSynchronizeManager(), but not the changesets.
An other thing I tried was to get the cangesets via FocusedTeamUiPlugin.getDefault().getContextChangeSetManagers() (got the manager and then the ChangeSetProvider where I tried to get the ChangeSets) - but they always are empty (because they are created when I first call it).
So, how can I access ChangeSets (with Java) in Eclipse (Mylyn)? In the end, I need the number of commits and code churn (loC added/removed/edited). Or is there probably an other, better approach?
Any help is appreciated really much!
I don't think Eclipse has implemented this feature as a public API yet. However, these links may help:
Internal changeset class and other API: http://www.cct.lsu.edu/~rguidry/ecl31docs/api/index.html?org/eclipse/team/internal/core/subscribers/ChangeSet.html
A feature enhancement request where they talk about why they haven't implemented it yet (but it's dated 2008, however the bug is still open?) https://bugs.eclipse.org/bugs/show_bug.cgi?id=116084
Sorry I couldn't be of more help! Maybe this will help you in the right direction...
You could perhaps go around Eclipse:
Apply rsync to get the CVS "*,v" files from the CVS server. It works for me.
Apply cvs2svn's "cvs2git" command to the CVS repos. It works for me.
Apply "git svn clone" (documented under "git-svn") to the SVN repos. I have not tried it.
Finally, use JGit's API to get the changesets from all of the repos, which at this point are all git repos. I think you'll particularly need these:
class Git
class FileResolver
class BaseConnection
interface Repository
class CheckoutCommand
class LogCommand
class RevCommit
class DiffCommand
class DiffEntry
class DiffFormatter
I've looking for this for 1 month now.
I tried to programm a plugin for eclipse, which is able to read the changeset of a Project ("working copy" of the repository).
What I've done now is an ugly work-around.
I used Runtime.exec() to run a cmd-command / Shell- command.
If you install a svn-commandline Client, you can type svn status -v -u
It gives you a list of all files of the working copy with the changeset info.
Then you can parse through the list to find all lines which start with "M" - for "modified" to get the Path of the changed file.

Categories

Resources