Giter VIP home page Giter VIP logo

ruby-git's Introduction

The Git Gem

Gem Version Documentation Change Log Build Status Code Climate

Summary

The git gem provides an API that can be used to create, read, and manipulate Git repositories by wrapping system calls to the git command line. The API can be used for working with Git in complex interactions including branching and merging, object inspection and manipulation, history, patch generation and more.

Get started by obtaining a repository object by:

  • opening an existing working copy with Git.open
  • initializing a new repository with Git.init
  • cloning a repository with Git.clone

Methods that can be called on a repository object are documented in Git::Base

v2.x Release

git 2.0.0 has recently been released. Please give it a try.

If you have problems with the 2.x release, open an issue and use the 1.9.1 version instead. We will do our best to fix your issues in a timely fashion.

JRuby on Windows is not yet supported by the 2.x release line. Users running JRuby on Windows should continue to use the 1.x release line.

The changes in this major release include:

  • Added a dependency on the activesupport gem to use the deprecation functionality
  • Create a policy of supported Ruby versions to support only non-EOL Ruby versions
  • Create a policy of supported Git CLI versions (released 2020-12-25)
  • Update the required Ruby version to at least 3.0 (released 2020-07-27)
  • Update the required Git command line version to at least 2.28
  • Update how CLI commands are called to use the process_executer gem which is built on top of Kernel.spawn. See PR #684 for more details on the motivation for this implementation.

The master branch will be used for 2.x development. If needed, fixes for 1.x version will be done on the v1 branch.

Install

Install the gem and add to the application's Gemfile by executing:

bundle add git

to install version 1.x:

bundle add git --version "~> 1.19"

If bundler is not being used to manage dependencies, install the gem by executing:

gem install git

to install version 1.x:

gem install git --version "~> 1.19"

Major Objects

Git::Base - The object returned from a Git.open or Git.clone. Most major actions are called from this object.

Git::Object - The base object for your tree, blob and commit objects, returned from @git.gtree or @git.object calls. the Git::AbstractObject will have most of the calls in common for all those objects.

Git::Diff - returns from a @git.diff command. It is an Enumerable that returns Git::Diff:DiffFile objects from which you can get per file patches and insertion/deletion statistics. You can also get total statistics from the Git::Diff object directly.

Git::Status - returns from a @git.status command. It is an Enumerable that returns Git:Status::StatusFile objects for each object in git, which includes files in the working directory, in the index and in the repository. Similar to running 'git status' on the command line to determine untracked and changed files.

Git::Branches - Enumerable object that holds Git::Branch objects. You can call .local or .remote on it to filter to just your local or remote branches.

Git::Remote- A reference to a remote repository that is tracked by this repository.

Git::Log - An Enumerable object that references all the Git::Object::Commit objects that encompass your log query, which can be constructed through methods on the Git::Log object, like:

@git.log(20).object("some_file").since("2 weeks ago").between('v2.6', 'v2.7').each { |commit| [block] }

Pass the --all option to git log as follows:

@git.log.all.each { |commit| [block] }

Git::Worktrees - Enumerable object that holds Git::Worktree objects.

Errors Raised By This Gem

The git gem will only raise an ArgumentError or an error that is a subclass of Git::Error. It does not explicitly raise any other types of errors.

It is recommended to rescue Git::Error to catch any runtime error raised by this gem unless you need more specific error handling.

begin
  # some git operation
rescue Git::Error => e
  puts "An error occurred: #{e.message}"
end

See Git::Error for more information.

Specifying And Handling Timeouts

The timeout feature was added in git gem version 2.0.0.

A timeout for git command line operations can be set either globally or for specific method calls that accept a :timeout parameter.

The timeout value must be a real, non-negative Numeric value that specifies a number of seconds a git command will be given to complete before being sent a KILL signal. This library may hang if the git command does not terminate after receiving the KILL signal.

When a command times out, it is killed by sending it the SIGKILL signal and a Git::TimeoutError is raised. This error derives from the Git::SignaledError and Git::Error.

If the timeout value is 0 or nil, no timeout will be enforced.

If a method accepts a :timeout parameter and a receives a non-nil value, the value of this parameter will override the global timeout value. In this context, a value of nil (which is usually the default) will use the global timeout value and a value of 0 will turn off timeout enforcement for that method call no matter what the global value is.

To set a global timeout, use the Git.config object:

Git.config.timeout = nil # a value of nil or 0 means no timeout is enforced
Git.config.timeout = 1.5 # can be any real, non-negative Numeric interpreted as number of seconds

The global timeout can be overridden for a specific method if the method accepts a :timeout parameter:

repo_url = 'https://github.com/ruby-git/ruby-git.git'
Git.clone(repo_url) # Use the global timeout value
Git.clone(repo_url, timeout: nil) # Also uses the global timeout value
Git.clone(repo_url, timeout: 0) # Do not enforce a timeout
Git.clone(repo_url, timeout: 10.5)  # Timeout after 10.5 seconds raising Git::SignaledError

If the command takes too long, a Git::TimeoutError will be raised:

begin
  Git.clone(repo_url, timeout: 10)
rescue Git::TimeoutError => e
  e.result.tap do |r|
    r.class #=> Git::CommandLineResult
    r.status #=> #<Process::Status: pid 62173 SIGKILL (signal 9)>
    r.status.timeout? #=> true
    r.git_cmd # The git command ran as an array of strings
    r.stdout # The command's output to stdout until it was terminated
    r.stderr # The command's output to stderr until it was terminated
  end
end

Examples

Here are a bunch of examples of how to use the Ruby/Git package.

Require the 'git' gem.

require 'git'

Git env config

Git.configure do |config|
  # If you want to use a custom git binary
  config.binary_path = '/git/bin/path'

  # If you need to use a custom SSH script
  config.git_ssh = '/path/to/ssh/script'
end

NOTE: Another way to specify where is the git binary is through the environment variable GIT_PATH

Here are the operations that need read permission only.

g = Git.open(working_dir, :log => Logger.new(STDOUT))

g.index
g.index.readable?
g.index.writable?
g.repo
g.dir

# log - returns a Git::Log object, which is an Enumerator of Git::Commit objects
# default configuration returns a max of 30 commits
g.log
g.log(200) # 200 most recent commits
g.log.since('2 weeks ago') # default count of commits since 2 weeks ago.
g.log(200).since('2 weeks ago') # commits since 2 weeks ago, limited to 200.
g.log.between('v2.5', 'v2.6')
g.log.each {|l| puts l.sha }
g.gblob('v2.5:Makefile').log.since('2 weeks ago')

g.object('HEAD^').to_s  # git show / git rev-parse
g.object('HEAD^').contents
g.object('v2.5:Makefile').size
g.object('v2.5:Makefile').sha

g.gtree(treeish)
g.gblob(treeish)
g.gcommit(treeish)


commit = g.gcommit('1cc8667014381')

commit.gtree
commit.parent.sha
commit.parents.size
commit.author.name
commit.author.email
commit.author.date.strftime("%m-%d-%y")
commit.committer.name
commit.date.strftime("%m-%d-%y")
commit.message

tree = g.gtree("HEAD^{tree}")

tree.blobs
tree.subtrees
tree.children # blobs and subtrees

g.revparse('v2.5:Makefile')

g.branches # returns Git::Branch objects
g.branches.local
g.current_branch
g.branches.remote
g.branches[:master].gcommit
g.branches['origin/master'].gcommit

g.grep('hello')  # implies HEAD
g.blob('v2.5:Makefile').grep('hello')
g.tag('v2.5').grep('hello', 'docs/')
g.describe()
g.describe('0djf2aa')
g.describe('HEAD', {:all => true, :tags => true})

g.diff(commit1, commit2).size
g.diff(commit1, commit2).stats
g.diff(commit1, commit2).name_status
g.gtree('v2.5').diff('v2.6').insertions
g.diff('gitsearch1', 'v2.5').path('lib/')
g.diff('gitsearch1', @git.gtree('v2.5'))
g.diff('gitsearch1', 'v2.5').path('docs/').patch
g.gtree('v2.5').diff('v2.6').patch

g.gtree('v2.5').diff('v2.6').each do |file_diff|
  puts file_diff.path
  puts file_diff.patch
  puts file_diff.blob(:src).contents
end

g.worktrees # returns Git::Worktree objects
g.worktrees.count
g.worktrees.each do |worktree|
  worktree.dir
  worktree.gcommit
  worktree.to_s
end

g.config('user.name')  # returns 'Scott Chacon'
g.config # returns whole config hash

# Configuration can be set when cloning using the :config option.
# This option can be an single configuration String or an Array
# if multiple config items need to be set.
#
g = Git.clone(
  git_uri, destination_path,
  :config => [
    'core.sshCommand=ssh -i /home/user/.ssh/id_rsa',
    'submodule.recurse=true'
  ]
)

g.tags # returns array of Git::Tag objects

g.show()
g.show('HEAD')
g.show('v2.8', 'README.md')

Git.ls_remote('https://github.com/ruby-git/ruby-git.git') # returns a hash containing the available references of the repo.
Git.ls_remote('/path/to/local/repo')
Git.ls_remote() # same as Git.ls_remote('.')

Git.default_branch('https://github.com/ruby-git/ruby-git') #=> 'master'

And here are the operations that will need to write to your git repository.

g = Git.init
  Git.init('project')
  Git.init('/home/schacon/proj',
  { :repository => '/opt/git/proj.git',
      :index => '/tmp/index'} )

# Clone from a git url
git_url = 'https://github.com/ruby-git/ruby-git.git'
# Clone into the ruby-git directory
g = Git.clone(git_url)

# Clone into /tmp/clone/ruby-git-clean
name = 'ruby-git-clean'
path = '/tmp/clone'
g = Git.clone(git_url, name, :path => path)
g.dir #=> /tmp/clone/ruby-git-clean

g.config('user.name', 'Scott Chacon')
g.config('user.email', '[email protected]')

# Clone can take a filter to tell the serve to send a partial clone
g = Git.clone(git_url, name, :path => path, :filter => 'tree:0')

# Clone can take an optional logger
logger = Logger.new
g = Git.clone(git_url, NAME, :log => logger)

g.add                                   # git add -- "."
g.add(:all=>true)                       # git add --all -- "."
g.add('file_path')                      # git add -- "file_path"
g.add(['file_path_1', 'file_path_2'])   # git add -- "file_path_1" "file_path_2"

g.remove()                                # git rm -f -- "."
g.remove('file.txt')                      # git rm -f -- "file.txt"
g.remove(['file.txt', 'file2.txt'])       # git rm -f -- "file.txt" "file2.txt"
g.remove('file.txt', :recursive => true)  # git rm -f -r -- "file.txt"
g.remove('file.txt', :cached => true)     # git rm -f --cached -- "file.txt"

g.commit('message')
g.commit_all('message')

# Sign a commit using the gpg key configured in the user.signingkey config setting
g.config('user.signingkey', '0A46826A')
g.commit('message', gpg_sign: true)

# Sign a commit using a specified gpg key
key_id = '0A46826A'
g.commit('message', gpg_sign: key_id)

# Skip signing a commit (overriding any global gpgsign setting)
g.commit('message', no_gpg_sign: true)

g = Git.clone(repo, 'myrepo')
g.chdir do
new_file('test-file', 'blahblahblah')
g.status.changed.each do |file|
  puts file.blob(:index).contents
end
end

g.reset # defaults to HEAD
g.reset_hard(Git::Commit)

g.branch('new_branch') # creates new or fetches existing
g.branch('new_branch').checkout
g.branch('new_branch').delete
g.branch('existing_branch').checkout
g.branch('master').contains?('existing_branch')

# delete remote branch
g.push('origin', 'remote_branch_name', force: true, delete: true)

g.checkout('new_branch')
g.checkout('new_branch', new_branch: true, start_point: 'master')
g.checkout(g.branch('new_branch'))

g.branch(name).merge(branch2)
g.branch(branch2).merge  # merges HEAD with branch2

g.branch(name).in_branch(message) { # add files }  # auto-commits
g.merge('new_branch')
g.merge('new_branch', 'merge commit message', no_ff: true)
g.merge('origin/remote_branch')
g.merge(g.branch('master'))
g.merge([branch1, branch2])

g.merge_base('branch1', 'branch2')

r = g.add_remote(name, uri)  # Git::Remote
r = g.add_remote(name, Git::Base)  # Git::Remote

g.remotes  # array of Git::Remotes
g.remote(name).fetch
g.remote(name).remove
g.remote(name).merge
g.remote(name).merge(branch)

g.fetch
g.fetch(g.remotes.first)
g.fetch('origin', {:ref => 'some/ref/head'} )
g.fetch(all: true, force: true, depth: 2)
g.fetch('origin', {:'update-head-ok' => true})

g.pull
g.pull(Git::Repo, Git::Branch) # fetch and a merge

g.add_tag('tag_name') # returns Git::Tag
g.add_tag('tag_name', 'object_reference')
g.add_tag('tag_name', 'object_reference', {:options => 'here'})
g.add_tag('tag_name', {:options => 'here'})

Options:
  :a | :annotate
  :d
  :f
  :m | :message
  :s

g.delete_tag('tag_name')

g.repack

g.push
g.push(g.remote('name'))

# delete remote branch
g.push('origin', 'remote_branch_name', force: true, delete: true)

# push all branches to remote at one time
g.push('origin', all: true)

g.worktree('/tmp/new_worktree').add
g.worktree('/tmp/new_worktree', 'branch1').add
g.worktree('/tmp/new_worktree').remove
g.worktrees.prune

Some examples of more low-level index and tree operations

g.with_temp_index do

  g.read_tree(tree3) # calls self.index.read_tree
  g.read_tree(tree1, :prefix => 'hi/')

  c = g.commit_tree('message')
  # or #
  t = g.write_tree
  c = g.commit_tree(t, :message => 'message', :parents => [sha1, sha2])

  g.branch('branch_name').update_ref(c)
  g.update_ref(branch, c)

  g.with_temp_working do # new blank working directory
    g.checkout
    g.checkout(another_index)
    g.commit # commits to temp_index
  end
end

g.set_index('/path/to/index')


g.with_index(path) do
  # calls set_index, then switches back after
end

g.with_working(dir) do
# calls set_working, then switches back after
end

g.with_temp_working(dir) do
  g.checkout_index(:prefix => dir, :path_limiter => path)
  # do file work
  g.commit # commits to index
end

Ruby version support policy

This gem will be expected to function correctly on:

  • All non-EOL versions of the MRI Ruby on Mac, Linux, and Windows
  • The latest version of JRuby on Linux
  • The latest version of Truffle Ruby on Linus

It is this project's intent to support the latest version of JRuby on Windows once the following JRuby bug is fixed:

jruby/jruby#7515

License

Licensed under MIT License Copyright (c) 2008 Scott Chacon. See LICENSE for further details.

ruby-git's People

Contributors

amayer5125 avatar andyobtiva avatar cwalsh avatar elliottcable avatar ericgoodwin avatar fxposter avatar gf3 avatar hatkyinc2 avatar hotchpotch avatar jamesarosen avatar jcouball avatar jdufresne avatar joemoore avatar koke avatar kpd200081 avatar mikemallete avatar nishidayuya avatar ohtake avatar othmane399 avatar perlun avatar peterkovacs avatar robertodecurnex avatar schacon avatar taquitos avatar tarcinil avatar technicalpickles avatar tit avatar titanous avatar yancyribbens avatar yuta1024 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ruby-git's Issues

Tests randomly fail when trying to create a new tmp repo

Seems like the repo path is not random enough so some times we end up trying to create/clone a new repository into an already taken path.

==============================================================================

Error: test_git_init_remote_git(TestInit)

Errno::EEXIST: File exists - /tmp/git_test1365775072186

/home/travis/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/fileutils.rb:243:in `mkdir'

/home/travis/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/fileutils.rb:243:in `fu_mkdir'

/home/travis/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/fileutils.rb:172:in `mkdir'

/home/travis/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/fileutils.rb:171:in `each'

/home/travis/.rvm/rubies/ruby-1.8.7-p371/lib/ruby/1.8/fileutils.rb:171:in `mkdir'

/home/travis/build/robertodecurnex/ruby-git/tests/units/../test_helper.rb:48:in `in_temp_dir'

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_init.rb:42:in `test_git_init_remote_git'

39: end

40:

41: def test_git_init_remote_git

=> 42: in_temp_dir do |dir|

43: assert(!File.exists?(File.join(dir, 'config')))

44:

45: in_temp_dir do |path|

==============================================================================

get first commit from git log?

I'm unclear what the equivalent command to

git log --reverse "filename"

would be, and how to get the timestamp of the first commit to that file (as would be returned in that log). e.g. without the reverse, I see I can get the most recent commit timestamp with

g = Git.open("path/to/repo")
g.log(1).object("filename").first.date

(Or perhaps there is a better way to get the first/oldest timestamp of a commit to a file using the gem?)

TypeError: can't convert Hash into String

I'm using ruby-1.9.2-p136 and irb:

g = Git.clone("https://github.com/opsb/ruby-git.git", :name => 'name', :path => '/tmp/checkout1')
TypeError: can't convert Hash into String
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/git-1.2.5/lib/git/base.rb:56:in `join'
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/git-1.2.5/lib/git/base.rb:56:in `initialize'
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/git-1.2.5/lib/git/base.rb:51:in `new'
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/git-1.2.5/lib/git/base.rb:51:in `clone'
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/git-1.2.5/lib/git.rb:97:in `clone'
from (irb):7
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/commands/console.rb:44:in `start'
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/commands/console.rb:8:in `start'
from /Users/guillaumeh/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.3/lib/rails/commands.rb:23:in `<top (required)>'
from ./script/rails:6:in `require'
from ./script/rails:6:in `<main>'

Add git show <ref>:<filename>

When having done a clone of a repository as bare with a depth of 1, in order to access a file ruby-git should implement a show method that will return the file content for given ref and file path.

add --no-color option to commands like git log

I get following errors on linux with git version 1.7.4.1 and ruby-git gem version 1.2.5 when color ui is set to always.

require 'git'; git = Git.open('.'); git.log(1).inspect
NoMethodError: undefined method `[]=' for nil:NilClass
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/lib.rb:153:in `block in process_commit_data'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/lib.rb:135:in `each'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/lib.rb:135:in `process_commit_data'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/lib.rb:93:in `full_log_commits'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/log.rb:108:in `run_log'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/log.rb:101:in `check_log'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/log.rb:84:in `each'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/log.rb:72:in `map'
    from /home/konrad/.rvm/gems/ruby-1.9.2-p180@example_gemset/gems/git-1.2.5/lib/git/log.rb:72:in `to_s'
    from (irb):4:in `inspect'
    from (irb):4
    from /home/konrad/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `<main>'

Solution is to add --no-color option to git commands like git log or git diff, so that color tags like '\e[43m' are not included in data being processed.

ruby-git status and command line git status differ

I'm attempting to check for git changes in a current directory after I re-write a file. For some reason @git.status.changed always shows that the file has been changed, even though command line git status shows no diff, as it should. Is there a way around this. I'm attempting to decide whether to update a field in the file if it has been changed before pushing to git.

    # Check the if the contents of a directory in git
    def dir_has_changes? dir
        intersection = dir.split('/') - @top_level.split('/')
        intersection = intersection.join('/')
        has_changes = false
        @git.status.changed.each do |file|
            if file[0] =~ /#{intersection}/
                has_changes = true
            end
        end
        return has_changes
    end

Configure git user for Travis CI

Travis fails because there's no git user configured in the environment.

 Git::GitExecuteError: git commit "-m" "test" "-a" 2>&1:

*** Please tell me who you are.

Run

git config --global user.email "[email protected]"

git config --global user.name "Your Name"

to set your account's default identity.

Omit --global to set the identity only in this repository.

g.pull() tries to merge unexistent branch

I'm trying to use your ruby-git gem to write some helper scripts for my own use but
+g.pull(remote, branch) doesn't have the expected behavior.

I want to process a pull request, so I extract the git url and the branch name from
+the mail and call:

g.pull(url, branch)

the problem is both on fetch and merge.

If I pass a branch to be pulled, you should probably go and fetch only that branch,
+but currently you only fetch the current checked out HEAD (which is master most of
+the times).

Also, you always overwrite the cool git message "merge branch of into
+" with "origin pull" which isn't really useful.

Then you try to merge an unexistent branch. What you should, probably, do is something
+like:

def pull(remote = 'origin', branch = 'master', message = nil)
fetch(remote, branch)
merge('FETCH_HEAD', message)
end

Here's the output of my script:

I, [2010-04-27T09:58:39.566725 #3309] INFO -- : Starting Git
I, [2010-04-27T09:58:39.570332 #3309] INFO -- : git branch newbranch-1272284431 2>&1
I, [2010-04-27T09:58:40.233505 #3309] INFO -- : git checkout newbranch-1272284431 2>&1
I, [2010-04-27T09:58:40.630576 #3309] INFO -- : git reset --hard origin/master 2>&1
D, [2010-04-27T09:58:40.630677 #3309] DEBUG -- : HEAD is now at bf4f324 Merge branch 'testing' into master
I, [2010-04-27T09:58:40.945683 #3309] INFO -- : git fetch git://mydomain.com/tree.githttp://mydomain.com/tree.git 2>&1
D, [2010-04-27T09:58:40.945802 #3309] DEBUG -- : From git://mydomain.com/treehttp://mydomain.com/tree

  • branch HEAD -> FETCH_HEAD
    I, [2010-04-27T09:58:40.968073 #3309] INFO -- : git merge -m 'origin pull' branch 2>&1
    D, [2010-04-27T09:58:40.968177 #3309] DEBUG -- : fatal: branch - not something we can merge
    /usr/lib/ruby/1.8/git/lib.rb:643:in command': git merge -m 'origin pull' branch +2>&1:fatal: branch - not something we can merge (Git::GitExecuteError) from /usr/lib/ruby/1.8/git/lib.rb:467:inmerge'
    from /usr/lib/ruby/1.8/git/base.rb:304:in merge' from /usr/lib/ruby/1.8/git/base.rb:317:inpull'
    from ./test.rb:37
    from ./test.rb:28:in `each_line'
    from ./test.rb:28

I changed the branch names and tree addresses, of course.

possible memory leak when calling status

I've been trying to find a memory leak in a rails app that I'm making. A particular request is increasing the apps memory usage with each request. I stripped everything out of the controller and view for that request and observed that the apps memory usage was now static when it was called. Then line by line I added the controller and view code back in.
The point at which the memory usage started increasing again was a call to a method which in turn called .status on a repo. With everything removed except the call to repo.status the memory usage was still increasing. Without out the call to repo.status the memory usage stayed constant.

I did a simple test in a fresh irb. Connected to a repo and called status and observed the consoles memory usage.

git = Git.open(<path_to_repo>)
git.status

each time I called git.status I could see the consoles mem usage increase by around 80kb. If I stopped calling git.status the mem usage stayed constant.
I found this to be the case on both Linux and Windows dev machines.

I'm sorry if I'm barking up the wrong tree with this, I hope I'm not wasting your time!

Improve temp path generation

Right now we use TempFile to create temp paths.

It was not working for JRUBY so a little hack was applied to go over it [https://github.com//issues/72].

Also, creating a file, to be deleted right after that just to get a random temp path does not seems right.

Example (with the JRUBY workaround):

if RUBY_PLATFORM == 'java'
  temp_path = "/tmp/temp-index-#{(0...15).map{ ('a'..'z').to_a[rand(26)] }.join}"
else
  tempfile = Tempfile.new('temp-index')
  temp_path = tempfile.path
  tempfile.close
  tempfile.unlink
end

`require 'git'` fails with `'gem_original_require': no such file to load -- git`

I've just tried this gem for the first time, and have not had any luck getting it to load. To be fair, I have installed ruby 2 on my Mac OS X Mountain Lion system using homebrew. But this doesn't seem to have caused me any similar problems with the many other rubygems I'm using.

Here I reproduce the problem with an interactive interpreter, using the default ruby that ships with Mac OS X 10.8:

aoide:kaelin.github.io kaelin$ env PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin ruby --version
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
aoide:kaelin.github.io kaelin$ env PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/opt/X11/bin ruby
require 'rubygems'
require 'git'

/Library/Ruby/Site/1.8/rubygems/core_ext/kernel_require.rb:45:in `gem_original_require': no such file to load -- git (LoadError)
    from /Library/Ruby/Site/1.8/rubygems/core_ext/kernel_require.rb:45:in `require'
    from -:2

status out of sync?

Hi!

It happens from time to time that the status returned from the git gem is incorrect. I have no idea why it happens sometimes and not others. For example today:

$ ruby -rubygems -e 'require "git"; p Git.open(".").status.changed'
[["vendor/mead/etc/enidf", #<Git::Status::StatusFile:0x1021849f0 @mode_repo="100644", @base=#<Git::Base:0x1022e4f70 @logger=nil, @lib=#<Git::Lib:0x1022e4cc8 @logger=nil, @git_index_file="/Users/mal/project/.git/index", @path=nil, @git_dir="/Users/mal/project/.git", @git_work_dir="/Users/mal/project">, @index=#<Git::Index:0x1022e4d90 @path="/Users/mal/project/.git/index">, @working_directory=#<Git::WorkingDirectory:0x1022e4e08 @path="/Users/mal/project">, @repository=#<Git::Repository:0x1022e4de0 @path="/Users/mal/project/.git">>, @untracked=nil, @type="M", @path="vendor/mead/etc/enidf", @mode_index="100644", @sha_repo="b63bbe70c7afcb44ddacc6de272351febd171207", @stage="0", @sha_index="0000000000000000000000000000000000000000">]]
$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)


$ ruby -v
ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0]
$ gem which git
/Library/Ruby/Gems/1.8/gems/git-1.2.5/lib/git.rb
$ git --version
git version 1.7.0.3

A git reset HEAD --hard won't fix it, so I delete the files first, then check them out and now the status is ok (ie. [])

grabbing name and e-mail from gitconfig includes extra quotes

When name and e-mail are quoted in ~/.gitconfig, such as:
[user]
name = "Mister Dude"
email = "[email protected]"

the Rakefile that Jeweler generates for a new project double quotes author and email:
Jeweler::Tasks.new do |gem|
gem.name = "the-perfect-gem"
gem.summary = %Q{TODO}
gem.email = ""[email protected]""
gem.homepage = "http://github.com/foo/the-perfect-gem"
gem.authors = [""Mister Dude""]
end

This is because ruby-git parses ~/.gitconfig directly instead of using the system commands.

status ignores dotfiles

When calling git.status files and directories starting with dot (.) are ignored. git status, on the other hand, does list such files and directories.

Pull doesn't work

g = Git.open "repo"
g.pull
# "Already up-to-date."
g.lib.send(:command, 'pull')
# "Updating 6d57a5a..0bbe197\nFast-forward\n file.rb |    6 +-----\n 1 files changed, 1 insertions(+), 5 deletions(-)"

It looks like internally Git::Base#pull doesn't use git pull at all, but fetches and merges. Why does it not use git pull as expected? Currently it just reports it's already up to date.

Ruby 2.0.0 - #in_temp_dir is not creating a given directory

This was working before #66
The error cause is not obvious and its clearly related with the Ruby 2.0.0 internals.

===============================================================================

Error: test_conflicts(TestEachConflict)

Errno::ENOENT: No such file or directory - /tmp/YOUR-example.txt20130412-1113-1rren04

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_each_conflict.rb:39:in `read'

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_each_conflict.rb:39:in `block (3 levels) in test_conflicts'

/home/travis/build/robertodecurnex/ruby-git/lib/git/lib.rb:525:in `block in conflicts'

/home/travis/build/robertodecurnex/ruby-git/lib/git/lib.rb:519:in `each'

/home/travis/build/robertodecurnex/ruby-git/lib/git/lib.rb:519:in `conflicts'

/home/travis/build/robertodecurnex/ruby-git/lib/git/base.rb:319:in `each_conflict'

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_each_conflict.rb:37:in `block (2 levels) in test_conflicts'

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_each_conflict.rb:16:in `chdir'

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_each_conflict.rb:16:in `block in test_conflicts'

/home/travis/build/robertodecurnex/ruby-git/tests/test_helper.rb:53:in `block in in_temp_dir'

/home/travis/build/robertodecurnex/ruby-git/tests/test_helper.rb:52:in `chdir'

/home/travis/build/robertodecurnex/ruby-git/tests/test_helper.rb:52:in `in_temp_dir'

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_each_conflict.rb:14:in `test_conflicts'

11: end

12:

13: def test_conflicts

=> 14: in_temp_dir do |path|

15: g = Git.clone(@wbare, 'branch_merge_test')

16: Dir.chdir('branch_merge_test') do

17:

===============================================================================

Multiline commits are not parsed correctly

Given a commit like this:

commit 4431b6b764e80d1db038857dbb699948268d1f84
Author: Brian xxxxx [email protected]
Date: Mon Nov 28 13:14:57 2011 -0500

Adding a modified post-receive script for extensibility

The post-recieve script should allow for adding multiple
sub-scripts as necessary though iteritive invocation.

o = repo.object('4431b6b764e80d1db038857dbb699948268d1f84')
o.message
=> "Adding a modified post-receive script for extensibility"

The problem is in lib.rb#process_commit_data. The assumption in the current code is if line.empty? then this should mark the beginning or ending of processing of the commit message. I tried patching it, but even without my code changes tests are not passing on trunk. My changes make the tests break more, so it's not solid, but here's a start:

https://gist.github.com/1412804

No options for push

Any reason you do not have ",opts = {}" as a "def push" parameter in base.rb?

I am trying to do git push -u and found only "tags".

Is there another way to do "-u" instead of changing the code?

Thanks.

Git.clone does not allow passing in a logger

Maybe I'm missing something, but it seems like Git.clone should act like Git.open:

g = Git.clone (url, name, :log => Logger.new(STDOUT))

vs.

g = Git.open (working_dir, :log => Logger.new(STDOUT))

But it doesn't

Pass options through to command.

The current implementation of the methods in lib.rb accepts options, but only passes a select subset of those options through to #command. It you want to do something like
--amend a commit you cannot use the commit method, and have to send('command') with the appropriate options.

Can the structure be changed to pass through the options to the command method to support all git options for these commands?

No way to update bare repositories from remote repository

Hello,
First, I'm sorry if there's a way to do it but I've searched, tried and even asked but I couldn't find a way so I decided to submit this as a new issue.

Let's assume I'm cloning a remote repository into a bare repository on my local machine. I can't do "g.pull" as this is just a bare repository so I can only use "g.fetch" which gets the newest updates but using "g.log" doesn't give me latest commits. It instead gives commits at the time of cloning. If I try to merge, it says that merging needs a working tree so I can't find any way to get updates to a bare repository to be just as if the repository was cloned at that time.

Thanks.

Git log should support the --decorate option

I'm trying to build a tool that allows people to enter a SHA and see all refs that point to that SHA, but can't do it with ruby-git because the git log command does not support annotate.

Feature request: Support for git object alternates

When performing a local git clone, the newly cloned git repository can use the objects stored in the original git repository by use of '.git/objects/info/alternatives' instead of copying objects. In cases where a large number of clones of the same git repository are being done, this can speed up clone operations by a significant amount and deduplicate git objects.

To add this functionality, the following changes would need to be made.

Git::Lib#clone would need to support a :reference or :shared option to use the alternates object directory on initial clone.

A new class like Git::Object::Alternate or Git::Alternate should be added to represent an entry in the alternates file. A member object should be able to generate a new Git::Base object for the referenced repository.

Git::Base should define a method like #alternates or something equivalent that would list the entries in .git/objects/info/alternates. It would return an array of zero or more Git::Alternate entries.

I would be very happy to help out with the implementation of this feature, and I would be fine to implement the entire thing myself. I'm opting to file this feature request so that I can figure out the best way to make this change before I start submitting pull requests.

As a reference, I'm currently implementing this functionality at https://github.com/adrienthebo/r10k/blob/master/lib/r10k/git/working_dir.rb#L79 by directly invoking git clone --reference, but I would rather move to ruby-git for this behavior instead of reinventing the wheel.

Thank you for your time!

Feature request: Support option `--follow` for logging

The native git command has the --follow option to see logs of files that are moved / renamed.

Could you please take a look and support an option for the .log operation, for example

$repo.object($object).log(10, true)
#10: number of log entriess
# true: continue listing the history of a file beyond renames

Thank you

Crash when parsing commit message

Here is the stack :

/usr/lib/ruby/1.8/git/lib.rb:148:in process_commit_data': undefined method<<' for nil:NilClass (NoMethodError)
from /usr/lib/ruby/1.8/git/lib.rb:135:in each' from /usr/lib/ruby/1.8/git/lib.rb:135:inprocess_commit_data'
from /usr/lib/ruby/1.8/git/lib.rb:123:in commit_data' from /usr/lib/ruby/1.8/git/object.rb:230:incheck_commit'
from /usr/lib/ruby/1.8/git/object.rb:197:in committer' from /usr/lib/ruby/1.8/git/object.rb:202:incommitter_date'
from /home/djdeath/bin/confront_patch_list.rb:32
from /home/djdeath/bin/confront_patch_list.rb:27:in `each_key'
from /home/djdeath/bin/confront_patch_list.rb:27

It happens when I call the committer_date method with something like this :

repo = Git::Base.open("#{ENV['PWD']}")
ob = Git::Object::Commit.new(repo, "whatevercommithash")
puts ob.committer_date

The problem is in the process_commit_data method in lib.rb because this method expects the commit's metadatas to be separated from the commit's comment by an empty line. But it does not expect the commit to contain a empty line too.

Here is what the commit triggering this crash looks like :

$ git cat-file commit a693b0cdba94f60f7ed43754d2c34151cdd11da5
tree 99cbf46748dfa4f35acc1d63ae51817f3e17ec9d
parent 484ab62c5ee805c2bdc405a85a4e64da2722690f
author Mauro Carvalho Chehab [email protected] 1228161854 -0200
committer Mauro Carvalho Chehab [email protected] 1228161854 -0200

em28xx: remove backward compat macro added on a previous fix

commit 50f3beb50abe0cc0228363af804e50e710b3e5b0 fixed em28xx-alsa
locking schema. However, a backport macro was kept.

This patch removes the macro, since it is not needed for the module
compilation against upstream.

Signed-off-by: Mauro Carvalho Chehab [email protected]

So the fix is pretty easy, on lib.rb line 137 you have :

    if line == ''

Replace it by :

    if line == '' and not in_message                                       

Regards,

Lionel Landwerlin

Git::Lib#escape does not work, escapes incorrectly

The escape mechanism for handling filenames with single quotes in them is repeating text, not escaping at all.

s = "it's"
# Original
escaped = s.to_s.gsub('\'', '\'\\\'\'') # => "it's's"
%Q{"#{escaped}"} #=> "\"it's's\""

# Patched
%Q{"#{s.to_s.gsub("'") { "\\'" }}"} # => "\"it\\'s\""

Looks like gsub placeholders are kicking in accidentally.

Doesn't works with Ruby 1.9.1

/opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/lib.rb:345:in chdir': wrong number of arguments (1 for 0) (ArgumentError) from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/lib.rb:345:inconfig_list'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/lib.rb:315:in config_remote' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/remote.rb:8:ininitialize'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/base.rb:330:in new' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/base.rb:330:inblock in remotes'
from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/base.rb:330:in map' from /opt/local/lib/ruby1.9/gems/1.9.1/gems/schacon-git-1.2.2/lib/git/base.rb:330:inremotes'

Readme file contains a non-working example

g = Git.clone(URI, :name => 'name', :path => '/tmp/checkout') 
TypeError: can't convert Hash into String                                                                                                  

should be
g = Git.clone(URI, 'name', :path => '/tmp/checkout')

remote remove doesn't work

r.remove
Git::GitExecuteError: git remote "rm" "--" "staging"  2>&1:usage: git remote rm <name>

If I do the following I can get it to work

git.lib.send(:command, 'remote', ['rm', 'staging'])

It seems git doesn't like the '--'

I am on git 1.7.7.3

I will try updating to the latest git and trying again.

git.status.push_delivered_in_percent

Hey,

im currently writing a script which is pushing git commits to the server..
Sometimes they are really big and need some minutes to transfer.. and there is no chance to get out how many percent of the transmission is already finished..

could you implement something like

Tread.new { g.push }

10.times do
g.status.push_delivered_in_percent
end
=> 10 %, 20 %,...

Thank you!
If you have any other suggestions, please feel free to tell me!

Clone no-checkout (-n)

From the documentation for git-clone(1):

--no-checkout
-n

No checkout of HEAD is performed after the clone is complete.

This feature is useful if you're updating a repository from some other source. In my case I have a script run by a cron job that grabs the latest copy of source from a central place that is out of my control, and then updates my local git repo by doing, basically:

git clone -n ...
git checkout .gitignore
extract_from_remote
git commit/push ...

I'm planning to port this script to ruby-git and this issue blocks.

Untracked files in Status but nothing to commit

I don't know if it is a bug, but "git status" reports nothing to commit whereas the Git::Status contains a list of untracked files. They are untracked because the are in a repository in repository (no the best idea, I know..).

How can I ignore the nested repos?

JRuby - Fails when trying to rise ArgumentError

Looks like the way that the ArgumentError exception is rised in not compatible with JRuby.

===============================================================================

Failure:

test_initialize_with_bad_path_and_check_path(TestGitPath)

/home/travis/build/robertodecurnex/ruby-git/tests/units/test_git_path.rb:18:in `test_initialize_with_bad_path_and_check_path'

15: end

16:

17: def test_initialize_with_bad_path_and_check_path

=> 18: assert_raises ArgumentError do

19: Git::Path.new('/this path does not exist', true)

20: end

21: end

<ArgumentError> expected but was

<TypeError(<backtrace must be Array of String>)>

Crash if log contains foreign characters(?)

Hi!

I'm running version 1.2.5 of the gem and 1.9.2 (p290) of ruby.
The following code crashes if the log contains a foreign character in the git log:

require 'git'

# Init git and get log
g = Git.init
log = g.log

changelog = "My changes: \n"

# Now create changelog (and crash)
log.each {|l| 
   changelog += "- " + l.message + "\n")
}

Stack trace:

[...]/gems/git-1.2.5/lib/git/lib.rb:672:in `split': invalid byte sequence in US-ASCII (ArgumentError)
   from [...]/gems/git-1.2.5/lib/git/lib.rb:672:in `command_lines'
   from [...]/gems/git-1.2.5/lib/git/lib.rb:92:in `full_log_commits'
   from [...]/gems/git-1.2.5/lib/git/log.rb:108:in `run_log'
   from [...]/gems/git-1.2.5/lib/git/log.rb:101:in `check_log'
   from [...]/gems/git-1.2.5/lib/git/log.rb:84:in `each'
   from gittest:10:in `<main>'

Any ideas?

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.