#176: Multiple SCM support (Open)

Apr 25 2007 * 04:52
Reported by:   Assigned to: dim 
Priority: Enhancement  Milestone: 1.x 
Release:    Component:  Changesets & Revisions 

– mercurial – darcs – bzr

Ideally, retrospectiva would support multiple SCM backends, as well as multiple repos per project.

Changelog:

Modified by – Apr 25 2007 * 08:06

  • Assigned user set to dim

True, I’d like to support (at least) bzr in the future, but I don’t think any bindings are currently available for Ruby.

Modified by – Apr 25 2007 * 08:09

  • Milestone set to 1.x

Modified by – Apr 26 2007 * 02:00

Could probably just use the command line. Would it be possible to abstract the VCS interface to a third-party library, like rscm, then use the command line programatically through the library?

Modified by – Apr 26 2007 * 07:56

How about implementing VCS into rscm? rscm seems to be very promising, I will definitely have a closer look to check its potential for Retrospectiva.

Modified by brett – May 01 2007 * 05:53

rscm is mostly dead, but it’s a good idea. At least supporting the same ones as capistrano is a good start (svn,cvs,mercurial,darcs)

Modified by – Oct 05 2007 * 16:17

Actually Capistrano will also support Git in version 2.1 (and is my preference).

Modified by Anton Ageev – Jan 10 2008 * 02:42

+1 for Git

Modified by – Jan 11 2008 * 11:11

+0.51 for git, +0.49 for hg

Modified by – Jan 13 2008 * 20:28

Does anybody know if there are any bindings for GIT or Mercurial available?

I’d personally love to implement those two, but it is relatively difficult to use just the console output (not many functions could be implemented).

Dimitrij

Modified by – Jan 23 2008 * 21:21

https://rubyforge.org/projects/grit/—Git Ruby bindings (7 Jan 2008)

Can’t see ones for Mercurial, so maybe a command line wrapper is the best option there.

Looking in Capistrano’s (MIT-licensed) 2.1.0 gem I see:

lib/capistrano/recipes/deploy/scm/darcs.rb lib/capistrano/recipes/deploy/scm/mercurial.rb lib/capistrano/recipes/deploy/scm/bzr.rb lib/capistrano/recipes/deploy/scm/cvs.rb lib/capistrano/recipes/deploy/scm/git.rb lib/capistrano/recipes/deploy/scm/subversion.rb lib/capistrano/recipes/deploy/scm/accurev.rb lib/capistrano/recipes/deploy/scm/perforce.rb

Dunno if it will give you workable performance, but might be worth trying?

—Thomas.

Modified by – Jan 27 2008 * 21:19

[r426] – Structural changes – preparation for the upcoming GIT adapter integration

Modified by – Feb 12 2008 * 12:12

If my half-vote for git and for hg haven’t been counted yet—please could I retract them and instead vote

bzr +1

?

It is an awesome tool, and speed problems seem to be history.

—Thomas.

Modified by – Feb 24 2008 * 23:17

In [r478], I’ve committed a first draft of the GIT adapter. Currently it just performs the basic browsing through the master branch (not much but it is a start). I’d really appreciate if somebody could help me out and spend some time improving it.

Link to the code: http://retrospectiva.org/browse/adapters

Thanks Dimitrij

PS: Just tell me if you have any questions or need any changes to the core

Modified by – May 05 2008 * 03:29

how exactly did you configure your setup?

I installed the git extension, and when I add the repository it says it added properly, but inside the project I was not sure what information I should put there, so I left it blank.

I can’t seem to browse any thing, and changesets weren’t working so I looked into the code and saw the sync info wasn’t built out yet.

Here is what all I wrote. Just so you know I am using mojombo-grit because its the new version of the ‘grit’ gem. The one on rubyforge is their old version of it, they moved it to github’s rubygem repo for some reason.

  def sync_changesets
    latest_changeset = changesets.find(:first, :select => 'revision', :order => 'revised_at DESC')
    last = latest_changeset ? latest_changeset : repo.commits.last
    current = repo.commits.first

    return if current == last

    new_commits = repo.commits_between(last, current)

    begin      
      Changeset.transaction do
        log :debug, 'SYNC', "Revisions: #{current} - #{last}" 
        newest = new_commits.pop 
        new_commits.each do |rev|
          log :debug, 'SYNC', "Git Revision: #{rev.id}" 
          # Mojombo-Grit (techncially the newer version of the generic Grit) 
          # has the ability to call the git command directly, in the format of
          # repo.git.'gitcommand'(*args), So using diff_tree, one should be
          # able to generate the diff between two versions, it just puts it
          # in a funny format that I am trying to parse, numstat seems to output
          # the result in a more 'machine friendly' manner.
          # http://www.kernel.org/pub/software/scm/git/docs/git-diff-tree.html
          # example output: 
          # 1\t2\tREADME\n
          # 3\t1\tarch/{i386 => x86}/Makefile\n
          # In the order:
          # 1. the number of added lines;
          # 2. a tab;
          # 3. the number of deleted lines;
          # 4. a tab;
          # 5. pathname (possibly with rename/copy information);
          # 6. a newline.
          repo_diff = repo.git.diff_tree({:numstat => true}, rev, newest).split("\n")

          repo_diff.each do |t|
          end

          # Filled out basic changeset details

          changeset = Changeset.new(:revision => rev.to_s, :repository => self)
          changeset.author = rev.committer.name
          changeset.log = rev.message
          changeset.revised_at = rev.committed_date

          changeset.save!
          log :info, 'SYNC', "Added revision #{rev}" 
        end
      end # end transaction
    rescue ActiveRecord::RecordInvalid => ex
      log :error, 'SYNC', "Revision already exists!" 
    rescue => other
      log :error, 'SYNC', other.message
    end
  end

Modified by – May 05 2008 * 07:57

Um… I realized that some of my code wasn’t functioning properly.

here is another modified part, I am still working on the changes between revisions, but I just wanted to post the this correction.

  # Working on this...
  def sync_changesets
    latest_changeset = changesets.find(:first, :select => 'revision', :order => 'revised_at DESC')
    last = latest_changeset ? repo.commit(latest_changeset.revision) : repo.commits.last
    current = repo.commits.first

    return if current == last

    commits_between = repo.commits_between(last, current)
    # Add the last repo because it is skipped otherwise.  
    commits_between << last
    begin      
      Changeset.transaction do
        log :debug, 'SYNC', "Revisions size: #{commits_between.size} from: #{commits_between.first} :to #{commits_between.last}" 
        commits_between.each do |rev|
          next if rev.id == last
          log :debug, 'SYNC', "Git Revision: #{rev.id}" 

          changeset = Changeset.new(:revision => rev.to_s, :repository => self)
          changeset.author = rev.committer.name
          changeset.log = rev.message
          changeset.revised_at = rev.committed_date

          changeset.save!
          log :info, 'SYNC', "Added revision #{rev}" 
        end
      end # end transaction
    rescue ActiveRecord::RecordInvalid => ex
      log :error, 'SYNC', "Revision already exists!" 
    rescue => other
      log :error, 'SYNC', other.message
    end
  end

Modified by – Jun 07 2008 * 13:15

This is very cool, I’ll integrate that into the trunk. Many thanks!

Modified by – Jun 11 2008 * 14:32

  • Attachment added git.zip [application/zip]

I have done some more work with this.

I messed up the browser source but now it reads commits better, it recognizes when things are deleted, moved, etc, and all that.

You’ll have to make a modification to your DB table to allow a MD5 has in the revisions table:

class ModifyChanges < ActiveRecord::Migration def self.up change_column :changes, :revision, :string, :limit => 40 end end

def self.down
  change_column :changes, :revision, :integer
end

Is the migration i used.

Here is a more up to date version of it. The only functionality I think that doesn’t work for Git is browsing the source. I’ll get around to fixing that eventually…

Here is a zip of the git extension.

Modified by – Jun 11 2008 * 14:51

Well, apparently I am not fully awake right now….

Thats the changes table not revisions table, its the revisions column and I seem to have messed up the code snippet, here it is, without getting messed up.

class ModifyChanges < ActiveRecord::Migration
  def self.up
    change_column :changes, :revision, :string, :limit => 40
  end

  def self.down
    change_column :changes, :revision, :integer
  end
end

Modified by Anonymous – Nov 13 2008 * 07:06

log :debug, ‘SYNC’, “Git Revision: #{rev.id}” # Mojombo-Grit (techncially the newer [http://www.nikeshoeswholesale.com version] of the generic Grit) # has the ability to call the git command directly, in the format of # repo.git.’gitcommand’(*args), So using diff_tree, one [http://www.nike-trainer.com should] be # able to generate the diff between two versions, it just puts it # in a funny format that I am trying to parse, numstat seems to output

Add comment and/or change ticket properties




Status: Assigned to:
Priority: Milestone:
Release:    Component: