Ruby/Rugged How can I save change after a git fetch? - ruby

So, I wanted to perform a git pull with rugged, so I make a fetch and merge like this:
require 'rugged'
certificat = Rugged::Credentials::SshKey.new({username: 'git', privatekey: 'path/to/privatekey', publickey: 'path/to/publickey' })
repo = Rugged::Repository.new("/tmp/git")
repo.checkout('master')
# git fetch
remote = repo.remotes['origin']
remote.fetch(credentials: certificat)
remote.save # save new data
# git merge
commit = repo.branches['origin/master'].target
repo.references.update(repo.head, commit.oid)
But I have this error with the save method:
undefined method `save' for #<Rugged::Remote:0x0000000135d6e8> (NoMethodError)
I don't understand why especially that the save method is in the Rugged doc (here)
Somebody know why ?
EDIT: Ok, so this documentation is outdated, the method save doesn't exist anymore. I think my merge is imcomplete, somebody know ?
EDIT2: I just add this line at the end of this code and it's work !
repo.checkout_head({strategy: :force})

Related

How to pull git repository using Rugged ruby gem

How do I pull changes from remote repo using Rugged ruby gem. Most of question on this topic are outdated as api has changed. I am using a simple repo with nothing complex. I found below code on one of the stackoverflow question but unfortunately its outdated
remote = repo.remotes['origin']
remote.fetch(credentials: credentials)
remote.save
Also remote.fetch gives {:total_objects=>0, :indexed_objects=>0, :received_objects=>0, :local_objects=>0, :total_deltas=>0, :indexed_deltas=>0, :received_bytes=>0} and no changes are pulled
The docs have this example:
remote = Rugged::Remote.lookup(#repo, 'origin')
remote.fetch({
transfer_progress: lambda { |total_objects, indexed_objects, received_objects, local_objects, total_deltas, indexed_deltas, received_bytes|
# ...
}
})

Rugged - fetch, pull rebase possible?

Using rugged how do you perform the following operations: fetch, pull and rebase?
I am using the development branch and after reviewing its documentation found here as a guide to the Remote class.
EDIT: Since git pull is just a shorthand for git fetch and git merge FETCH_HEAD the better question is how to perform git fetch, git merge and git rebase.
git fetch:
remote = Rugged::Remote.lookup(repo, "origin")
remote.connect(:fetch) do |r|
r.download
r.update_tips!
end
git merge:
merge_index = repo.merge_commits(
Rugged::Branches.lookup(repo, "master").tip,
Rugged::Branches.lookup(repo, "origin/master").tip
)
raise "Conflict detected!" if merge_index.conflicts?
merge_commit = Rugged::Commit.create(repo, {
parents: [
Rugged::Branches.lookup(repo, "master").tip,
Rugged::Branches.lookup(repo, "origin/master").tip
],
tree: merge_index.write_tree(repo),
message: 'Merged `origin/master` into `master`',
author: { name: "User", email: "example#test.com" },
committer: { name: "User", email: "example#test.com" },
update_ref: 'master'
})
git rebase:
Rebasing was not implemented yet in libgit2, and thus is not available in Rugged.
In general, your use case sounds very high level, while the rugged API is currently a bit more focused on low-level git repository access and modification. Eventually, we'll also have many higher-level helpers (like a more simple/correct pull) in the future, but we're not there yet.
The answer above seems to be outdated. The syntax has changed. I need to implement a pull action which i am trying to do by a fetch and then a merge and commit. For fetching i use the fetch method like this
repo.fetch('origin', [repo.head.name], credentials: credits)
And it seems to actually get something since the returned hash is full with information about what has been fetched. However, it is not written to disk. I would expect the branch to be behind several commits when i do git status in the command line but it is not. If i fetch a second time with the same command above then nothing is fetched. This is probably because it has already been fetched the first time but then i dont see where the fetch is.
Now if i go ahead and do the fetch manually in the command line and then try to merge the local copy of the remote branch and the local branch (local changes are already committed) using the following code
ref_name = repo.head.name # refs/heads/branchname
branch_name = ref_name.sub(/^refs\/heads\//, '') # branchname
remote_name = "#{remote}/#{branch_name}" # origin/branchname
remote_ref = "refs/heads/#{remote_name}" # refs/heads/origin/branchname
local_branch = repository.branches[branch_name]
remote_branch = repository.branches[remote_name]
index = repo.merge_commits(local_branch.target, remote_branch.target)
options = {
author: { time: Time.now }.merge(author),
committer: { time: Time.now }.merge(committer),
message: 'merged',
parents: [
local_branch.target,
remote_branch.target
],
tree: index.write_tree(repository),
update_ref: 'HEAD'
}
Rugged::Commit.create repo, options
It creates the commit as expected. The commit is also written to disk and is visible in the fistory. But for some reason the branch has now uncommitted changes. The local file contents have not changed. I would expect them to have the contents of the fetched commit.
Can anyone please provide a working example for a fetch, merge, commit? The version of rugged at time of writing this is 0.22.0b3
Update 1
This will bring my working tree to the wanted state
repo.checkout ref_name, strategy: :force
Update2
I found out how to fetch and save the state to disk
r = repo.remotes[remote]
r.fetch(credentials: git_credentials)
r.save

Can't push to beanstalk

I'm trying to use php git deploy for AWS Beanstalk
I got python, ruby etc installed. I setup the repository, did a git aws.config which went well. Then whenever I try to run git aws.push I get this error.
./.git/AWSDevTools/aws/dev_tools.rb:53:in `host': private method `split' called for nil:NilClass (NoMethodError)
from ./.git/AWSDevTools/aws/dev_tools.rb:112:in `signed_uri'
from .git/AWSDevTools/aws.elasticbeanstalk.push:86
Don't know much about ruby, but from what I gather it looks like it's missing a dependency maybe? I guess I'm not sure what's wrong, any help would really be appreciated.
I had this same problem, and I tracked it to a missing appRoot/.elasticbeanstalk/config file.
I added the file with the following content. Note: substitute your actual app/environment where appropriate.
.elasticbeanstalk/config >>
[global]
ApplicationName=your-application-name-east
DevToolsEndpoint=git.elasticbeanstalk.us-east-1.amazonaws.com
EnvironmentName=your-environment-name
Region=us-east-1
Ok so I did some digging through the source files. Turns out there was a permissions issue in a config file so it was creating a null class, and thus you can't string split a null.

Creating tags with Grit

I'm trying to create a tag in my git repository via Grit, but I'm not sure that the library supports referenced tags. It's easy to create a tag like this:
Grit::Tag.create_tag_object(repo, params, actor)
But that will only create a lightweight tag. To have a referenced tag I need to create a ref to the tag also, but the implementation of update_ref looks like this:
def update_ref(head, commit_sha)
return nil if !commit_sha || (commit_sha.size != 40)
self.git.fs_write("refs/heads/#{head}", commit_sha)
commit_sha
end
... which means that I can only create head refs, not a tag ref. There is nothing in the Ref or Tag classes that does anything.
Does anyone have an idea on how to create a reference to a commit via Grit?
I've created a new Tag linking to a commit as follows:
log = #repo.git.tag( { 'f' => true }, tag_name, commit_sha )
And got:
Updated tag 'new_tag' (was 0000000)
$ git tag
...
new_tag
...
$ git show new_tag
commit e74b99a0ff706993e200939ee00079182f75ec29
...
I don't know much about grit (actually nothing). I would make a tag in regular git. Then find where it lives in the .git folder. Now search the grit source code for uses of that path. It should lead you to what you can use in grit.

Determine which git files have changed using Ruby?

I've got a Rails app with blog entries that I want to update from a separate Blog.git repo.
I envision my workflow as something like:
Write new blog entry
Push to remote Git repo
Call cap deploy:update, which will invoke a Rake task to update the database with any changed or new entries
The hitch here is finding which files have changed. I'd like to harness Git for this, and I know I could do some awk or Perl scripting on git diff.
But is there a better way? I've briefly looked at Grit but can't find a good solution.
Update: It turns out Grit is the best solution to this problem, at least as far as I can tell. Here's what I used to solve the problem:
desc 'Posts all entries to database'
task :post_all do
Dir.chdir REPO do
Grit::Repo.new('.').tree.contents.each do |file|
# post_entry cleans up my blog entries and posts them via Post.create()
post_entry(file.data, :text) unless file.basename =~ /\.gitignore/
end
end
end
desc 'Posts all new or changed entries to database'
task :post_new do
Dir.chdir REPO do
Grit::Repo.new('.').head.commit.diffs.each do |diff|
post_entry diff.b_blob.data, :text
end
end
end
desc 'Deletes entries from database'
task :remove_all do
Post.destroy_all
end
desc 'Synchronizes the remote blog repo and the database'
task :sync => [ :remove_all, :post_all ]
is a database really necessary? check out the jekyll gem. hundreds (if not thousands) of simple blogs use it, including two of mine.
http://github.com/mojombo/jekyll
otherwise, grit is a good solution. i've used it for a few things and it works well.

Resources