diff --git a/app/models/site/repository.rb b/app/models/site/repository.rb index d63e331c..7cc64352 100644 --- a/app/models/site/repository.rb +++ b/app/models/site/repository.rb @@ -14,8 +14,26 @@ class Site @changes = 0 end - def remote - @remote ||= rugged.remotes.first + # Obtiene la rama por defecto a partir de la referencia actual + # + # Por ejemplo "refs/heads/no-master" => "no-master" + # + # XXX: No memoizamos para obtener siempre el nombre de la rama + # actual, aunque por ahora asumimos que siempre estamos en la misma, + # internamente (ej. vía shell) podríamos cambiarla. + # + # @return [String] + def default_branch + rugged.head.canonical_name.split('/', 3).last + end + + # Obtiene el origin + # + # @return [Rugged::Remote] + def origin + @origin ||= rugged.remotes.find do |remote| + remote.name == 'origin' + end end # Trae los cambios del repositorio de origen sin aplicarlos y @@ -24,8 +42,8 @@ class Site # XXX: Prestar atención a la velocidad de respuesta cuando tengamos # repositorios remotos. def fetch - if remote.check_connection :fetch - @changes = rugged.fetch(remote)[:received_objects] + if origin.check_connection :fetch + @changes = rugged.fetch(origin)[:received_objects] else 0 end @@ -34,7 +52,7 @@ class Site # Incorpora los cambios en el repositorio actual # def merge(usuarie) - merge = rugged.merge_commits(master, origin_master) + merge = rugged.merge_commits(head_commit, remote_head_commit) # No hacemos nada si hay conflictos, pero notificarnos begin @@ -46,7 +64,7 @@ class Site commit = Rugged::Commit .create(rugged, update_ref: 'HEAD', - parents: [master, origin_master], + parents: [head_commit, remote_head_commit], tree: merge.write_tree(rugged), message: I18n.t('sites.fetch.merge.message'), author: author(usuarie), committer: committer) @@ -57,12 +75,20 @@ class Site commit end - def master - rugged.branches['master'].target + # El último commit + # + # @return [Rugged::Commit] + def head_commit + rugged.branches[default_branch].target end - def origin_master - rugged.branches['origin/master'].target + # El último commit del repositorio remoto + # + # XXX: Realmente no recuerdo por qué esto era necesario ~f + # + # @return [Rugged::Commit] + def remote_head_commit + rugged.branches["origin/#{default_branch}"].target end # Compara los commits entre el repositorio remoto y el actual para @@ -72,10 +98,8 @@ class Site # Obtenemos todos los commits que existen en origin/master que no # están en la rama master local - # - # XXX: monitorear esto por performance - walker.push 'refs/remotes/origin/master' - walker.hide 'refs/heads/master' + walker.push "refs/remotes/origin/#{default_branch}" + walker.hide "refs/heads/#{default_branch}" walker.each.to_a end diff --git a/test/models/site/repository_test.rb b/test/models/site/repository_test.rb index 39da8696..52f7c798 100644 --- a/test/models/site/repository_test.rb +++ b/test/models/site/repository_test.rb @@ -18,6 +18,28 @@ class RepositoryTest < ActiveSupport::TestCase @site.destroy end + test 'se puede obtener la rama por defecto' do + assert_equal 'master', @site.repository.default_branch + + random_branch = SecureRandom.hex + + Dir.chdir(@site.path) do + `git checkout -b #{random_branch} >/dev/null 2>&1` + end + + assert_equal random_branch, @site.repository.default_branch + end + + test 'los nombres de las ramas pueden tener /' do + random_branch = ([SecureRandom.hex] * 2).join('/') + + Dir.chdir(@site.path) do + `git checkout -b #{random_branch} >/dev/null 2>&1` + end + + assert_equal random_branch, @site.repository.default_branch + end + test 'se pueden traer cambios' do assert @site.repository.fetch.is_a?(Integer) end @@ -28,8 +50,7 @@ class RepositoryTest < ActiveSupport::TestCase assert @site.repository.commits.empty? assert_equal @usuarie.name, - @site.repository.rugged - .branches['master'].target.author[:name] + @site.repository.rugged.branches[@site.repository.default_branch].target.author[:name] Dir.chdir(@site.path) do FileUtils.rm 'migration.csv'