lib/rim/sync_helper.rb in esr-rim-1.4.0 vs lib/rim/sync_helper.rb in esr-rim-1.4.2
- old
+ new
@@ -1,150 +1,150 @@
-require 'rim/command_helper'
-require 'rim/sync_module_helper'
-require 'rim/status_builder'
-require 'tempfile'
-require 'fileutils'
-
-module RIM
-
-class SyncHelper < CommandHelper
-
- def initialize(workspace_root, logger, module_infos = nil)
- @module_infos = []
- super(workspace_root, logger, module_infos)
- end
-
- # called to add a module info
- def add_module_info(module_info)
- @module_infos.push(module_info)
- end
-
- # sync all module changes into rim branch
- def sync(message = nil, rebase = nil, split = true)
- # get the name of the current workspace branch
- RIM::git_session(@ws_root) do |s|
- branch = s.current_branch || ''
- rim_branch = "rim/" + branch
- branch_sha1 = nil
- changed_modules = nil
- if branch.empty?
- raise RimException.new("Not on a git branch.")
- elsif branch.start_with?("rim/")
- raise RimException.new("The current git branch '#{branch}' is a rim integration branch. Please switch to a non rim branch to proceed.")
- else
- branch = "refs/heads/#{branch}"
- branch_sha1 = s.rev_sha1(rim_branch)
- remote_rev = get_latest_remote_revision(s, branch)
- rev = get_latest_clean_path_revision(s, branch, remote_rev)
- if !s.has_branch?(rim_branch) || has_ancestor?(s, branch, s.rev_sha1(rim_branch)) || !has_ancestor?(s, rim_branch, remote_rev)
- s.execute("git branch -f #{rim_branch} #{rev}")
- branch_sha1 = s.rev_sha1(rim_branch)
- end
- remote_url = "file://" + @ws_root
- @logger.debug("Folder for temporary git repositories: #{@rim_path}")
- tmpdir = clone_or_fetch_repository(remote_url, module_tmp_git_path(".ws"), "Cloning workspace git...")
- RIM::git_session(tmpdir) do |tmp_session|
- tmp_session.execute("git reset --hard")
- tmp_session.execute("git clean -xdf")
- # use -f here to prevent git checkout from checking for untracked files which might be overwritten.
- # this is safe since we removed any untracked files before.
- # this is a workaround for a name case problem on windows:
- # if a file's name changes case between the current head and the checkout target,
- # git checkout will report the file with the new name as untracked and will fail
- tmp_session.execute("git checkout -B #{rim_branch} -f remotes/origin/#{rim_branch}")
- changed_modules = sync_modules(tmp_session, message)
- if !split
- tmp_session.execute("git reset --soft #{branch_sha1}")
- commit(tmp_session, message ? message : get_commit_message(changed_modules)) if tmp_session.uncommited_changes?
- end
- tmp_session.execute("git push #{remote_url} #{rim_branch}:#{rim_branch}")
- end
- end
- if !changed_modules.empty?
- if rebase
- s.execute("git rebase #{rim_branch}")
- @logger.info("Changes have been commited to branch #{rim_branch} and workspace has been rebased successfully.")
- else
- @logger.info("Changes have been commited to branch #{rim_branch}. Rebase to apply changes to workspace.")
- end
- else
- @logger.info("No changes.")
- end
- end
- end
-
-private
- # sync all modules
- def sync_modules(session, message)
- module_helpers = []
- @module_infos.each do |module_info|
- module_helpers.push(SyncModuleHelper.new(session.execute_dir, @ws_root, module_info, @logger))
- end
- changed_modules = []
- module_helpers.each do |m|
- @logger.info("Synchronizing #{m.module_info.local_path}...")
- if m.sync(message)
- changed_modules << m.module_info
- end
- end
- changed_modules
- end
-
- # get latest revision from which all parent revisions are clean
- def get_latest_clean_path_revision(session, rev, remote_rev)
- # make sure we deal only with sha1s
- rev = session.rev_sha1(rev)
- # get history status (up to last remote revision)
- status = StatusBuilder.new().rev_history_status(session, rev, :fast => true)
- clean_rev = rev;
- while status
- dirty = status.dirty?
- status = !status.parents.empty? ? status.parents[0] : nil
- clean_rev = status ? status.git_rev : remote_rev if dirty
- end
- clean_rev
- end
-
- # get latest remote revision
- def get_latest_remote_revision(session, rev)
- # remote revs are where we stop traversal
- non_remote_revs = {}
- session.all_reachable_non_remote_revs(rev).each do |r|
- non_remote_revs[r] = true
- end
- # make sure we deal only with sha1s
- rev = session.rev_sha1(rev)
- start_rev = rev;
- while rev && non_remote_revs[rev]
- rev = get_parent(session, rev)
- end
- rev
- end
-
- # check whether revision has a given ancestor
- def has_ancestor?(session, rev, ancestor)
- # make sure we deal only with sha1s
- rev = session.rev_sha1(rev)
- return rev == ancestor || session.is_ancestor?(ancestor, rev)
- end
-
- # get first parent node
- def get_parent(session, rev)
- parents = session.parent_revs(rev)
- !parents.empty? ? parents.first : nil
- end
-
- #create default commit message from array of changed modules
- def get_commit_message(changed_modules)
- StringIO.open do |s|
- s.puts "rim sync."
- s.puts
- changed_modules.each do |m|
- s.puts m.local_path
- end
- s.string
- end
- end
-
-end
-
-end
+require 'rim/command_helper'
+require 'rim/sync_module_helper'
+require 'rim/status_builder'
+require 'tempfile'
+require 'fileutils'
+
+module RIM
+
+class SyncHelper < CommandHelper
+
+ def initialize(workspace_root, logger, module_infos = nil)
+ @module_infos = []
+ super(workspace_root, logger, module_infos)
+ end
+
+ # called to add a module info
+ def add_module_info(module_info)
+ @module_infos.push(module_info)
+ end
+
+ # sync all module changes into rim branch
+ def sync(message = nil, rebase = nil, split = true)
+ # get the name of the current workspace branch
+ RIM::git_session(@ws_root) do |s|
+ branch = s.current_branch || ''
+ rim_branch = "rim/" + branch
+ branch_sha1 = nil
+ changed_modules = nil
+ if branch.empty?
+ raise RimException.new("Not on a git branch.")
+ elsif branch.start_with?("rim/")
+ raise RimException.new("The current git branch '#{branch}' is a rim integration branch. Please switch to a non rim branch to proceed.")
+ else
+ branch = "refs/heads/#{branch}"
+ branch_sha1 = s.rev_sha1(rim_branch)
+ remote_rev = get_latest_remote_revision(s, branch)
+ rev = get_latest_clean_path_revision(s, branch, remote_rev)
+ if !s.has_branch?(rim_branch) || has_ancestor?(s, branch, s.rev_sha1(rim_branch)) || !has_ancestor?(s, rim_branch, remote_rev)
+ s.execute("git branch -f #{rim_branch} #{rev}")
+ branch_sha1 = s.rev_sha1(rim_branch)
+ end
+ remote_url = "file://" + @ws_root
+ @logger.debug("Folder for temporary git repositories: #{@rim_path}")
+ tmpdir = clone_or_fetch_repository(remote_url, module_tmp_git_path(".ws"), "Cloning workspace git...")
+ RIM::git_session(tmpdir) do |tmp_session|
+ tmp_session.execute("git reset --hard")
+ tmp_session.execute("git clean -xdf")
+ # use -f here to prevent git checkout from checking for untracked files which might be overwritten.
+ # this is safe since we removed any untracked files before.
+ # this is a workaround for a name case problem on windows:
+ # if a file's name changes case between the current head and the checkout target,
+ # git checkout will report the file with the new name as untracked and will fail
+ tmp_session.execute("git checkout -B #{rim_branch} -f remotes/origin/#{rim_branch}")
+ changed_modules = sync_modules(tmp_session, message)
+ if !split
+ tmp_session.execute("git reset --soft #{branch_sha1}")
+ commit(tmp_session, message ? message : get_commit_message(changed_modules)) if tmp_session.uncommited_changes?
+ end
+ tmp_session.execute("git push #{remote_url} #{rim_branch}:#{rim_branch}")
+ end
+ end
+ if !changed_modules.empty?
+ if rebase
+ s.execute("git rebase #{rim_branch}")
+ @logger.info("Changes have been commited to branch #{rim_branch} and workspace has been rebased successfully.")
+ else
+ @logger.info("Changes have been commited to branch #{rim_branch}. Rebase to apply changes to workspace.")
+ end
+ else
+ @logger.info("No changes.")
+ end
+ end
+ end
+
+private
+ # sync all modules
+ def sync_modules(session, message)
+ module_helpers = []
+ @module_infos.each do |module_info|
+ module_helpers.push(SyncModuleHelper.new(session.execute_dir, @ws_root, module_info, @logger))
+ end
+ changed_modules = []
+ module_helpers.each do |m|
+ @logger.info("Synchronizing #{m.module_info.local_path}...")
+ if m.sync(message)
+ changed_modules << m.module_info
+ end
+ end
+ changed_modules
+ end
+
+ # get latest revision from which all parent revisions are clean
+ def get_latest_clean_path_revision(session, rev, remote_rev)
+ # make sure we deal only with sha1s
+ rev = session.rev_sha1(rev)
+ # get history status (up to last remote revision)
+ status = StatusBuilder.new().rev_history_status(session, rev, :fast => true)
+ clean_rev = rev;
+ while status
+ dirty = status.dirty?
+ status = !status.parents.empty? ? status.parents[0] : nil
+ clean_rev = status ? status.git_rev : remote_rev if dirty
+ end
+ clean_rev
+ end
+
+ # get latest remote revision
+ def get_latest_remote_revision(session, rev)
+ # remote revs are where we stop traversal
+ non_remote_revs = {}
+ session.all_reachable_non_remote_revs(rev).each do |r|
+ non_remote_revs[r] = true
+ end
+ # make sure we deal only with sha1s
+ rev = session.rev_sha1(rev)
+ start_rev = rev;
+ while rev && non_remote_revs[rev]
+ rev = get_parent(session, rev)
+ end
+ rev
+ end
+
+ # check whether revision has a given ancestor
+ def has_ancestor?(session, rev, ancestor)
+ # make sure we deal only with sha1s
+ rev = session.rev_sha1(rev)
+ return rev == ancestor || session.is_ancestor?(ancestor, rev)
+ end
+
+ # get first parent node
+ def get_parent(session, rev)
+ parents = session.parent_revs(rev)
+ !parents.empty? ? parents.first : nil
+ end
+
+ #create default commit message from array of changed modules
+ def get_commit_message(changed_modules)
+ StringIO.open do |s|
+ s.puts "rim sync."
+ s.puts
+ changed_modules.each do |m|
+ s.puts m.local_path
+ end
+ s.string
+ end
+ end
+
+end
+
+end