Class: Tetra::Git
- Inherits:
-
Object
- Object
- Tetra::Git
- Includes:
- Logging, ProcessRunner
- Defined in:
- lib/tetra/facades/git.rb
Overview
facade to git, currently implemented with calls to the git command
Instance Method Summary collapse
-
#archive(directory, id, destination_path) ⇒ Object
archives version id of directory in destination_path.
-
#changed_files(directory, id) ⇒ Object
returns the list of files changed from since_id including changes in the working tree and staging area.
-
#commit_directories(directories, message) ⇒ Object
adds all files in the specified directories, removes all files not in the specified directories, commits with message.
-
#commit_file(path, message) ⇒ Object
commits one single file.
-
#disable_special_files(path) ⇒ Object
renames git special files to ‘disable’ them.
-
#format_patch(directory, from_id, destination_path) ⇒ Object
generates patch files to changes to directory in destination_path since from_id.
-
#init ⇒ Object
inits a repo.
-
#initialize(directory) ⇒ Git
constructor
inits a new git manager object pointing to the specified directory.
-
#latest_comment(comment_prefix) ⇒ Object
returns the comment of the most recent commit that has the specified comment prefix in its message returns nil if such commit does not exist.
-
#latest_id(comment_prefix) ⇒ Object
returns the id of the most recent commit that has the specified comment prefix in its message returns nil if such commit does not exist.
-
#merge_with_id(path, new_path, id) ⇒ Object
3-way merges the git file at path with the one in new_path assuming they have a common ancestor at the specified id returns the conflict count.
-
#revert_directories(directories, id) ⇒ Object
reverts multiple directories’ contents as per specified id.
-
#undo_last_commit ⇒ Object
reverts the whole repo to the last commit while leaving changes in the working directory.
Methods included from ProcessRunner
Methods included from Logging
Constructor Details
#initialize(directory) ⇒ Git
inits a new git manager object pointing to the specified directory
11 12 13 |
# File 'lib/tetra/facades/git.rb', line 11 def initialize(directory) @directory = directory end |
Instance Method Details
#archive(directory, id, destination_path) ⇒ Object
archives version id of directory in destination_path
152 153 154 155 156 157 158 |
# File 'lib/tetra/facades/git.rb', line 152 def archive(directory, id, destination_path) Dir.chdir(@directory) do FileUtils.mkdir_p(File.dirname(destination_path)) run("git archive --format=tar #{id} -- #{directory} | xz -9e > #{destination_path}") end destination_path end |
#changed_files(directory, id) ⇒ Object
returns the list of files changed from since_id including changes in the working tree and staging area
137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/tetra/facades/git.rb', line 137 def changed_files(directory, id) Dir.chdir(@directory) do tracked_files = [] begin tracked_files += run("git diff-index --name-only #{id} -- #{directory}").split rescue ExecutionFailed => e raise e if e.status != 1 # status 1 is normal end untracked_files = run("git ls-files --exclude-standard --others -- #{directory}").split tracked_files + untracked_files end end |
#commit_directories(directories, message) ⇒ Object
adds all files in the specified directories, removes all files not in the specified directories, commits with message
49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/tetra/facades/git.rb', line 49 def commit_directories(directories, ) log.debug "committing with message: #{message}" Dir.chdir(@directory) do directories.each do |directory| run("git rm -r --cached --ignore-unmatch #{directory}") run("git add #{directory}") end run("git commit --allow-empty -F -", false, ) end end |
#commit_file(path, message) ⇒ Object
commits one single file
62 63 64 65 66 67 68 |
# File 'lib/tetra/facades/git.rb', line 62 def commit_file(path, ) Dir.chdir(@directory) do log.debug "committing path #{path} with message: #{message}" run("git add #{path}") run("git commit --allow-empty -F -", false, ) end end |
#disable_special_files(path) ⇒ Object
renames git special files to ‘disable’ them
99 100 101 102 103 104 105 106 107 |
# File 'lib/tetra/facades/git.rb', line 99 def disable_special_files(path) Dir.chdir(File.join(@directory, path)) do Find.find(".") do |file| next unless file =~ /\.git(ignore)?$/ FileUtils.mv(file, "#{file}_disabled_by_tetra") end end end |
#format_patch(directory, from_id, destination_path) ⇒ Object
generates patch files to changes to directory in destination_path since from_id
162 163 164 165 166 |
# File 'lib/tetra/facades/git.rb', line 162 def format_patch(directory, from_id, destination_path) Dir.chdir(@directory) do run("git format-patch -o #{destination_path} --no-numbered #{from_id} -- #{directory}").split end end |
#init ⇒ Object
inits a repo
16 17 18 19 20 21 22 23 24 |
# File 'lib/tetra/facades/git.rb', line 16 def init Dir.chdir(@directory) do if Dir.exist?(".git") == false run("git init") else fail GitAlreadyInitedError end end end |
#latest_comment(comment_prefix) ⇒ Object
returns the comment of the most recent commit that has the specified comment prefix in its message returns nil if such commit does not exist
39 40 41 42 43 44 |
# File 'lib/tetra/facades/git.rb', line 39 def latest_comment(comment_prefix) Dir.chdir(@directory) do id = latest_id(comment_prefix) run("git rev-list --max-count=1 --format=%B #{id}") unless id.nil? end end |
#latest_id(comment_prefix) ⇒ Object
returns the id of the most recent commit that has the specified comment prefix in its message returns nil if such commit does not exist
29 30 31 32 33 34 |
# File 'lib/tetra/facades/git.rb', line 29 def latest_id(comment_prefix) Dir.chdir(@directory) do result = run("git rev-list --max-count=1 --grep=\"#{comment_prefix}\" --fixed-strings HEAD") result.strip if result != "" end end |
#merge_with_id(path, new_path, id) ⇒ Object
3-way merges the git file at path with the one in new_path assuming they have a common ancestor at the specified id returns the conflict count
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/tetra/facades/git.rb', line 112 def merge_with_id(path, new_path, id) Dir.chdir(@directory) do run("git show #{id}:#{path} > #{path}.old_version") conflict_count = 0 begin run("git merge-file #{path} #{path}.old_version #{new_path} \ -L \"newly generated\" \ -L \"previously generated\" \ -L \"user edited\"") rescue ExecutionFailed => e if e.status > 0 conflict_count = e.status else raise e end end File.delete("#{path}.old_version") conflict_count end end |
#revert_directories(directories, id) ⇒ Object
reverts multiple directories’ contents as per specified id
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/tetra/facades/git.rb', line 71 def revert_directories(directories, id) Dir.chdir(@directory) do directories.each do |directory| # reverts added and modified files, both in index and working tree run("git checkout -f #{id} -- #{directory}") # compute the list of deleted files files_in_commit = run("git ls-tree --name-only -r #{id} -- #{directory}").split("\n") files_in_head = run("git ls-tree --name-only -r HEAD -- #{directory}").split("\n") files_added_after_head = run("git ls-files -o -- #{directory}").split("\n") files_to_delete = files_in_head - files_in_commit + files_added_after_head files_to_delete.each do |file| FileUtils.rm_rf(file) end end end end |
#undo_last_commit ⇒ Object
reverts the whole repo to the last commit while leaving changes in the working directory
92 93 94 95 96 |
# File 'lib/tetra/facades/git.rb', line 92 def undo_last_commit Dir.chdir(@directory) do run("git reset HEAD~") end end |