I have been trying to get git comit log for a specific file in git repo, but after multiple attempts I am failing to identify the source of the problem.
Here is the link to my github code.
PS: The files Folder needs to be deleted everytime the app needs to start again. Any tips on that would be also helpful.
To put it in short, I tried the below piece of code to get the commit log, but I am getting a null RevCommit.
Repository repository = git.getRepository();
//Approach 1
RevCommit commits = git.log().addPath("D:/Code_downloads/fileaccess/files/dev/Doc2.csv").call().iterator().next();
//Approach 2
RevWalk revWalk = new RevWalk( repository );
revWalk.markStart( revWalk.parseCommit( repository.resolve( Constants.HEAD ) ) );
revWalk.setTreeFilter(PathFilter.create( "D:/Code_downloads/fileaccess/files/dev/Doc2.csv" ) );
revWalk.sort( RevSort.COMMIT_TIME_DESC );
revWalk.sort( RevSort.REVERSE, true );
RevCommit commit = revWalk.next();
Referred multiple documentations and stackoverflow posts. no luck.
https://archive.eclipse.org/jgit/site/4.5.0.201609210915-r/apidocs/org/eclipse/jgit/api/LogCommand.html
Any help will be appreciated.
It should work to use addPath() and then iterate over the RevCommits.
But you should not use the "absoulte path" to the file, but rather only the relative path inside your repository.
E.g.
Iterable<RevCommit logs = git.log().addPath("README.md").call();
for (RevCommit rev : logs) {
System.out.println("Commit: " + rev + ", name: " + rev.getName() + ", id: " + rev.getId().getName());
}
There is a ready-to-run snippet in the jgit-cookbook which shows a few more ways to iterate commits.
I am trying to create a remote branch with jgit, which executes exactly the following git commands:
git clone git#gitlab.com:my-project/test.git
git checkout -b superBranch
git push --set-upstream origin superBranch
After these executions, I can change and push the files of the branch without merge request.
jGit:
Unfortunately jgit does not know the command "push -u" (Upstream). So I found some maybe solution. But all solutions does not work really.
First in StackOverflow:
// git clone done, than:
git.branchCreate()
.setName("superBranch")
.setForce(true)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.setStartPoint("origin/superBranch").call(); // <-- Ref not found
RefSpec refSpec = new RefSpec().setSourceDestination("superBranch", "superBranch");
git.push()
.setRefSpecs(refSpec)
.setCredentialsProvider(provider).call();
git.checkout().setName("superBranch").call();
Exception:
org.eclipse.jgit.api.errors.RefNotFoundException: Ref origin/superBranch cannot be resolved
Another solution I found here Eclipse Forum:
git.branchCreate().setName("superBranch").call();
git.push()
.setRemote("origin")
.setRefSpecs(new RefSpec("superBranch" + ":" + "superBranch")) //<-- Ref not found
.setCredentialsProvider(provider).call();
git.branchCreate()
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.SET_UPSTREAM)
.setStartPoint("origin/" + "superBranch")
.setForce(true).call();
git.checkout().setName("superBranch").call();
Exception:
org.eclipse.jgit.api.errors.InvalidRefNameException: Branch name <null> is not allowed
Does anyone know how can I create a remote and local branch, without call an api or make a merge request like my git example on the top?
Following code works for me:
Git git = Git.cloneRepository()
.setURI("https://gitlab.com/my-project/test.git")
.setDirectory(new File("scratch/test"))
.setCloneAllBranches(true)
.setCredentialsProvider(provider).call();
git.checkout()
.setCreateBranch(true)
.setName(BRANCH).call();
git.push()
.setRemote("origin")
.setRefSpecs(new RefSpec(BRANCH + ":" + BRANCH))
.setCredentialsProvider(provider).call();
So I clone the repository, checkout the branch or create the branch if not exits, then I push the new branch to the remote repository.
Finally, I tried this, that works for me.
git.branchCreate().setName(localBranchName).call();
git.push().setRemote("origin")
.setCredentialsProvider(createCredential(name, password))
.setRefSpecs(new RefSpec(localBranchName + ":" + localBranchName)).call();
//delete is necessary
git.branchDelete().setBranchNames(localBranchName).call();
git.checkout().setCreateBranch(true).setName(localBranchName)
.setUpstreamMode(CreateBranchCommand.SetupUpstreamMode.TRACK)
.setStartPoint("origin/" + localBranchName)
.call();
If I had 20 directories under trunk/ with lots of files in each and only needed 3 of those directories, would it be possible to do a Subversion checkout with only those 3 directories under trunk?
Indeed, thanks to the comments to my post here, it looks like sparse directories are the way to go. I believe the following should do it:
svn checkout --depth empty http://svnserver/trunk/proj
svn update --set-depth infinity proj/foo
svn update --set-depth infinity proj/bar
svn update --set-depth infinity proj/baz
Alternatively, --depth immediates instead of empty checks out files and directories in trunk/proj without their contents. That way you can see which directories exist in the repository.
As mentioned in #zigdon's answer, you can also do a non-recursive checkout. This is an older and less flexible way to achieve a similar effect:
svn checkout --non-recursive http://svnserver/trunk/proj
svn update trunk/foo
svn update trunk/bar
svn update trunk/baz
Subversion 1.5 introduces sparse checkouts which may be something you might find useful. From the documentation:
... sparse directories (or shallow checkouts) ... allows you to easily check out a working copy—or a portion of a working copy—more shallowly than full recursion, with the freedom to bring in previously ignored files and subdirectories at a later time.
I wrote a script to automate complex sparse checkouts.
#!/usr/bin/env python
'''
This script makes a sparse checkout of an SVN tree in the current working directory.
Given a list of paths in an SVN repository, it will:
1. Checkout the common root directory
2. Update with depth=empty for intermediate directories
3. Update with depth=infinity for the leaf directories
'''
import os
import getpass
import pysvn
__author__ = "Karl Ostmo"
__date__ = "July 13, 2011"
# =============================================================================
# XXX The os.path.commonprefix() function does not behave as expected!
# See here: http://mail.python.org/pipermail/python-dev/2002-December/030947.html
# and here: http://nedbatchelder.com/blog/201003/whats_the_point_of_ospathcommonprefix.html
# and here (what ever happened?): http://bugs.python.org/issue400788
from itertools import takewhile
def allnamesequal(name):
return all(n==name[0] for n in name[1:])
def commonprefix(paths, sep='/'):
bydirectorylevels = zip(*[p.split(sep) for p in paths])
return sep.join(x[0] for x in takewhile(allnamesequal, bydirectorylevels))
# =============================================================================
def getSvnClient(options):
password = options.svn_password
if not password:
password = getpass.getpass('Enter SVN password for user "%s": ' % options.svn_username)
client = pysvn.Client()
client.callback_get_login = lambda realm, username, may_save: (True, options.svn_username, password, True)
return client
# =============================================================================
def sparse_update_with_feedback(client, new_update_path):
revision_list = client.update(new_update_path, depth=pysvn.depth.empty)
# =============================================================================
def sparse_checkout(options, client, repo_url, sparse_path, local_checkout_root):
path_segments = sparse_path.split(os.sep)
path_segments.reverse()
# Update the middle path segments
new_update_path = local_checkout_root
while len(path_segments) > 1:
path_segment = path_segments.pop()
new_update_path = os.path.join(new_update_path, path_segment)
sparse_update_with_feedback(client, new_update_path)
if options.verbose:
print "Added internal node:", path_segment
# Update the leaf path segment, fully-recursive
leaf_segment = path_segments.pop()
new_update_path = os.path.join(new_update_path, leaf_segment)
if options.verbose:
print "Will now update with 'recursive':", new_update_path
update_revision_list = client.update(new_update_path)
if options.verbose:
for revision in update_revision_list:
print "- Finished updating %s to revision: %d" % (new_update_path, revision.number)
# =============================================================================
def group_sparse_checkout(options, client, repo_url, sparse_path_list, local_checkout_root):
if not sparse_path_list:
print "Nothing to do!"
return
checkout_path = None
if len(sparse_path_list) > 1:
checkout_path = commonprefix(sparse_path_list)
else:
checkout_path = sparse_path_list[0].split(os.sep)[0]
root_checkout_url = os.path.join(repo_url, checkout_path).replace("\\", "/")
revision = client.checkout(root_checkout_url, local_checkout_root, depth=pysvn.depth.empty)
checkout_path_segments = checkout_path.split(os.sep)
for sparse_path in sparse_path_list:
# Remove the leading path segments
path_segments = sparse_path.split(os.sep)
start_segment_index = 0
for i, segment in enumerate(checkout_path_segments):
if segment == path_segments[i]:
start_segment_index += 1
else:
break
pruned_path = os.sep.join(path_segments[start_segment_index:])
sparse_checkout(options, client, repo_url, pruned_path, local_checkout_root)
# =============================================================================
if __name__ == "__main__":
from optparse import OptionParser
usage = """%prog [path2] [more paths...]"""
default_repo_url = "http://svn.example.com/MyRepository"
default_checkout_path = "sparse_trunk"
parser = OptionParser(usage)
parser.add_option("-r", "--repo_url", type="str", default=default_repo_url, dest="repo_url", help='Repository URL (default: "%s")' % default_repo_url)
parser.add_option("-l", "--local_path", type="str", default=default_checkout_path, dest="local_path", help='Local checkout path (default: "%s")' % default_checkout_path)
default_username = getpass.getuser()
parser.add_option("-u", "--username", type="str", default=default_username, dest="svn_username", help='SVN login username (default: "%s")' % default_username)
parser.add_option("-p", "--password", type="str", dest="svn_password", help="SVN login password")
parser.add_option("-v", "--verbose", action="store_true", default=False, dest="verbose", help="Verbose output")
(options, args) = parser.parse_args()
client = getSvnClient(options)
group_sparse_checkout(
options,
client,
options.repo_url,
map(os.path.relpath, args),
options.local_path)
Or do a non-recursive checkout of /trunk, then just do a manual update on the 3 directories you need.
If you already have the full local copy, you can remove unwanted sub folders by using --set-depth command.
svn update --set-depth=exclude www
See: http://blogs.collab.net/subversion/sparse-directories-now-with-exclusion
The set-depth command support multipile paths.
Updating the root local copy will not change the depth of the modified folder.
To restore the folder to being recusively checkingout, you could use --set-depth again with infinity param.
svn update --set-depth=infinity www
I'm adding this information for those using the TortoiseSvn tool: to obtain the OP same functionality, you can use the Choose items... button in the Checkout Depth section of the Checkout function, as shown in the following screenshot:
Sort of. As Bobby says:
svn co file:///.../trunk/foo file:///.../trunk/bar file:///.../trunk/hum
will get the folders, but you will get separate folders from a subversion perspective. You will have to go separate commits and updates on each subfolder.
I don't believe you can checkout a partial tree and then work with the partial tree as a single entity.
Not in any especially useful way, no. You can check out subtrees (as in Bobby Jack's suggestion), but then you lose the ability to update/commit them atomically; to do that, they need to be placed under their common parent, and as soon as you check out the common parent, you'll download everything under that parent. Non-recursive isn't a good option, because you want updates and commits to be recursive.
I have a problem where i cannot create local branch.
Error: org.eclipse.jgit.api.errors.RefNotFoundException: Ref origin/sideMerge cannot be resolved
I have checked the following topics and some others in Stackoverflow but it seems something fishy going on or something i don't understand yet.
Can someone point me to a direction what i don't understand regarding the Ref ?
As far as i know the local refs starts from origin/"other_branch"
Code snippet:
Git git;
CreateBranchCommand tmpCreateBranch;
git = new Git(existingRepo);
tmpCreateBranch = git.branchCreate();
try {
tmpCreateBranch.setName(tmpBranchName).setStartPoint("origin/" + tmpBranchName).setForce(true).call();
} catch (Exception e) {
System.out.println("Error in Branch creation");
System.out.println(e);
}
According to Git manual, you can create a branch using the following syntax. It creates a new branch head named <branchname> which points to the current HEAD, or <start-point> if given:
git branch [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
Therefore, you can create a local branch "topic" by following the similar syntax in JGit (see next code-block). In this case, you didn't configure the start-point explicitly. JGit will use HEAD as start-point. So everything works fine:
git.branchCreate().setName("topic").call();
However, if you create a local branch with start-point origin/topic, JGit will try to find this reference in Git References. In this context, origin is the name of the remote, and topic is the name of the branch. If not found, it raises an exception:
git.branchCreate().setName("topic").setStartPoint("origin/topic").call();
You also need to be aware that:
setForce(true) will reset the target branch name to start-point if branch name exists already. Without -f,--force git branch refuses to change an existing branch.
Szilágyi István, I create the branch as follows:
try (Git git = new Git(repository)) {
Ref ref = git.branchCreate().setName("Name_Branch").setStartPoint("origin/develop").call();
git.checkout().setName(branch).call();
git.push().setCredentialsProvider(userService.getCredencialsProvider()).call();
logger.info("Branch created: " + ref + " - " + ref.getName() + " - " + ref.getObjectId().getName());
}
Total newbie to java/groovy/grails/shiro/you-name-it, so bear with me. I have exhausted tutorials and all the "Shiro LDAP" searches available and still cannot get my project working.
I am running all of this on GGTS with jdk1.7.0_80, Grails 2.3.0, and Shiro 1.2.1.
I have a working project and have successfully ran quick-start-shiro,which built the domains ShiroRole and ShiroUser, the controller authController, the view login.gsp, and the relam ShiroDbRealm. I created a faux user in BootStrap with
def user = new ShiroUser(username: "user123", passwordHash: new Sha256Hash("password").toHex())
user.addToPermissions("*:*")
user.save()
and can successfully log into my homepage, and for all intents and purposes, that is as far as I have gotten. I cannot find a top-down tutorial of how to now log in with my username and password (authenticated through a LDAP server that I have available). From what I understand, I need to create a shiro.ini file and include something along the lines of
[main]
ldapRealm = org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm
ldapRealm.url = ldap://MYURLHERE/
However I don't even know where to put this shiro.ini file. I've seen /src/main/resources, but there is no such directory. Do I manually create this or is it some script creation?
The next step seems to be creating the SecurityManager which reads the shiro.ini somehow with code along the lines of
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory("actived.ini");
// Setting up the SecurityManager...
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);
However this always appears in some Java file in tutorials, but my project is a Groovy project inside of GGTS. Do I need to create a Java file and put it in src/java or something like that?
I've recently found that I may need a ShiroLdapRealm file (similar to ShiroDbRealm) with information like
def appConfig = grailsApplication.config
def ldapUrls = appConfig.ldap.server.url ?: [ "ldap://MYURLHERE/" ]
def searchBase = appConfig.ldap.search.base ?: ""
def searchUser = appConfig.ldap.search.user ?: ""
def searchPass = appConfig.ldap.search.pass ?: ""
def usernameAttribute = appConfig.ldap.username.attribute ?: "uid"
def skipAuthc = appConfig.ldap.skip.authentication ?: false
def skipCredChk = appConfig.ldap.skip.credentialsCheck ?: false
def allowEmptyPass = appConfig.ldap.allowEmptyPasswords != [:] ? appConfig.ldap.allowEmptyPasswords : true
and the corresponding info in Config along the lines of
ldap.server.url = ["ldap://MYRULHERE/"]
ldap.search.base = 'dc=COMPANYNAME,dc=com'
ldap.search.user = '' // if empty or null --> anonymous user lookup
ldap.search.pass = 'password' // only used with non-anonymous lookup
ldap.username.attribute = 'AccountName'
ldap.referral = "follow"
ldap.skip.credentialsCheck = false
ldap.allowEmptyPasswords = false
ldap.skip.authentication = false
But putting all these pieces together hasn't gotten me anywhere! Am I at least on the right track? Any help would be greatly appreciated!
For /src/main/resources it will automatically created for you if you used maven for your project. Moreover, you can also create that directory manually.