Anonymous avatar Anonymous committed 58ad0e8

Fixed an issue with how repositories were picked. Each repository type was allowed to search upwards, so a .git repo inside a .hg repo would be ignored since the .hg repo would be picked up first. Also added some data for full-repo git tests.

Comments (0)

Files changed (7)

 site/build/*
 site/src/doc*
 ext/amp/bz2/mkmf.log
+test/git_tests/fullrepo_tests/temporary-git-repo/*
 syntax: regexp
 \.DS_Store
 .rbc$
+

lib/amp/repository/git/repo_format/staging_area.rb

+##################################################################
+#                  Licensing Information                         #
+#                                                                #
+#  The following code is licensed, as standalone code, under     #
+#  the Ruby License, unless otherwise directed within the code.  #
+#                                                                #
+#  For information on the license of this code when distributed  #
+#  with and used in conjunction with the other modules in the    #
+#  Amp project, please see the root-level LICENSE file.          #
+#                                                                #
+#  © Michael J. Edgar and Ari Brown, 2009-2010                   #
+#                                                                #
+##################################################################
+
+# This was produced primarily by running "git add" and "git reset"
+# over and over and seeing how the index file changes.  No git
+# source code was consulted at any time.
+
+module Amp
+  module Repositories    
+    module Git
+      ##
+      # = Index
+      #
+      # The Index is essentially a cache of the working directory. It tracks
+      # which files have been added to the staging area and which have not, and
+      # can be used to check if a file has been modified or not. It is a relatively
+      # complex binary format and there are two versions of it we also have to
+      # support.
+      class StagingArea < Amp::Repositories::AbstractStagingArea
+        attr_reader :index, :repo
+        
+        def initialize(repo)
+          @repo = repo
+          @index = Index.parse("index", repo.git_opener)
+        end
+        
+        ##
+        # Marks a file to be added to the repository upon the next commit.
+        # 
+        # @param [[String]] filenames a list of files to add in the next commit
+        # @return [Boolean] true for success, false for failure
+        def add(*filenames)
+          filenames.each do |file|
+            @index.add file, repo.file_opener
+          end
+        end
+
+        ##
+        # Marks a file to be removed from the repository upon the next commit. Last argument
+        # can be a hash, which can take an :unlink key, specifying whether the files should actually
+        # be removed or not.
+        # 
+        # @param [[String]] filenames a list of files to remove in the next commit
+        # @return [Boolean] true for success, false for failure
+        def remove(*filenames)
+          if filenames.last == :unlink
+            unlink = true
+            filenames = filenames[0..-2]
+          end
+          filenames.each do |file|
+            @index.remove file
+          end          
+          filenames.each do |file|
+            File.rm_rf(repo.file_opener.join(file))
+          end if unlink
+        end
+
+        ##
+        # Set +file+ as normal and clean. Un-removes any files marked as removed, and
+        # un-adds any files marked as added.
+        # 
+        # @param  [Array<String>] files the name of the files to mark as normal
+        # @return [Boolean] success marker
+        def normal(*files)
+          raise NotImplementedError.new("normal() must be implemented by subclasses of AbstractStagingArea.")
+        end
+
+        ##
+        # Mark the files as untracked.
+        # 
+        # @param  [Array<String>] files the name of the files to mark as untracked
+        # @return [Boolean] success marker
+        def forget(*files)
+          raise NotImplementedError.new("forget() must be implemented by subclasses of AbstractStagingArea.")
+        end
+
+        ##
+        # Marks a file to be copied from the +from+ location to the +to+ location
+        # in the next commit, while retaining history.
+        # 
+        # @param [String] from the source of the file copy
+        # @param [String] to the destination of the file copy
+        # @return [Boolean] true for success, false for failure
+        def copy(from, to)
+          @index.add_with_source from, to, repo.file_opener
+        end
+
+        ##
+        # Marks a file to be moved from the +from+ location to the +to+ location
+        # in the next commit, while retaining history.
+        # 
+        # @param [String] from the source of the file move
+        # @param [String] to the destination of the file move
+        # @return [Boolean] true for success, false for failure
+        def move(from, to)
+          raise NotImplementedError.new("move() must be implemented by subclasses of AbstractStagingArea.")
+        end
+
+        ##
+        # Marks a modified file to be included in the next commit.
+        # If your VCS does this implicitly, this should be defined as a no-op.
+        # 
+        # @param [[String]] filenames a list of files to include for committing
+        # @return [Boolean] true for success, false for failure
+        def include(*filenames)
+          raise NotImplementedError.new("include() must be implemented by subclasses of AbstractStagingArea.")
+        end
+        alias_method :stage, :include
+
+        ##
+        # Mark a modified file to not be included in the next commit.
+        # If your VCS does not include this idea because staging a file is implicit, this should
+        # be defined as a no-op.
+        # 
+        # @param [[String]] filenames a list of files to remove from the staging area for committing
+        # @return [Boolean] true for success, false for failure
+        def exclude(*filenames)
+          raise NotImplementedError.new("exclude() must be implemented by subclasses of AbstractStagingArea.")
+        end
+        alias_method :unstage, :exclude
+
+        ##
+        # Returns a Symbol.
+        # Possible results:
+        # :added (subset of :included)
+        # :removed
+        # :untracked
+        # :included
+        # :normal
+        #
+        def file_status(filename)
+          raise NotImplementedError.new("file_status() must be implemented by subclasses of AbstractStagingArea.")
+        end
+
+        ##
+        # The directory used by the VCS to store magical information (.hg, .git, etc.).
+        #
+        # @api
+        # @return [String] relative to root
+        def vcs_dir
+          ".git"
+        end
+
+        ##
+        # Saves the staging area's state.  Any added files, removed files, "normalized" files
+        # will have that status saved here.
+        def save
+          @index.write "index", repo.git_opener
+        end
+
+        ##
+        # Returns all files tracked by the repository *for the working directory* - not
+        # to be confused with the most recent changeset.
+        #
+        # @api
+        # @return [Array<String>] all files tracked by the repository at this moment in
+        #   time, including just-added files (for example) that haven't been committed yet.
+        def all_files
+          index.all_filenames
+        end
+        
+      end
+    end
+  end
+end

lib/amp/repository/git/repository.rb

         
         def self.repo_in_dir?(path)
           return true if path[0, 4] == "http"
-          until File.directory? File.join(path, ".git")
-            old_path, path = path, File.dirname(path)
-            if path == old_path
-              return false
-            end
-          end
-          true
+          File.directory? File.join(path, ".git")
         end
         
         ################################

lib/amp/repository/mercurial/repository.rb

         
         def self.repo_in_dir?(path)
           return true if path[0, 4] == "http"
-          until File.directory? File.join(path, ".hg")
-            old_path, path = path, File.dirname(path)
-            if path == old_path
-              return false
-            end
-          end
-          true
+          File.directory? File.join(path, ".hg")
         end
         
         ################################

lib/amp/repository/repository.rb

     # Note: this does NOT handle when there are two types of repositories in
     # a given directory.
     def self.pick(config, path='', create=false)
-      GenericRepoPicker.each do |picker|
-        return picker.pick(config, path, create) if picker.repo_in_dir?(path)
-      end
+      begin
+        GenericRepoPicker.each do |picker|
+          return picker.pick(config, path, create) if picker.repo_in_dir?(path)
+        end
+        path, old_path = File.dirname(path), path
+      end until path == old_path
       
       # We have found... nothing
       nil
Add a comment to this file

test/git_tests/fullrepo_tests/temporary-git-repo.tar.gz

Binary file added.

test/git_tests/fullrepo_tests/test_local_repo.rb

+##################################################################
+#                  Licensing Information                         #
+#                                                                #
+#  The following code is licensed, as standalone code, under     #
+#  the Ruby License, unless otherwise directed within the code.  #
+#                                                                #
+#  For information on the license of this code when distributed  #
+#  with and used in conjunction with the other modules in the    #
+#  Amp project, please see the root-level LICENSE file.          #
+#                                                                #
+#  © Michael J. Edgar and Ari Brown, 2009-2010                   #
+#                                                                #
+##################################################################
+
+require File.expand_path(File.join(File.dirname(__FILE__), '../../testutilities'))
+require File.expand_path(File.join(File.dirname(__FILE__), "../../../lib/amp"))
+
+class TestGitLocalRepo < AmpTestCase
+  include Amp::Repositories::Git
+  SOURCE_TAR = File.expand_path(File.join(File.dirname(__FILE__), "temporary-git-repo.tar.gz"))
+  TARGET_DIR = File.expand_path(File.join(File.dirname(__FILE__), "temporary-git-repo"))
+  
+  def setup
+    FileUtils.rm_rf(TARGET_DIR)
+    Dir.chdir(File.dirname(__FILE__)) do
+      %x(tar -xzf #{SOURCE_TAR})
+    end
+    @repo = Amp::Repositories.pick(Amp::AmpConfig.new, TARGET_DIR)
+  end
+  
+  def test_repo_recognized
+    assert_not_nil @repo
+  end
+  
+  def test_repo_is_git
+    assert_kind_of LocalRepository, @repo
+  end
+  
+end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.