eac_git 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/eac_git/local.rb +9 -1
- data/lib/eac_git/local/commit.rb +53 -0
- data/lib/eac_git/local/commit/changed_file.rb +46 -0
- data/lib/eac_git/local/commit/diff_tree_line.rb +32 -0
- data/lib/eac_git/local/dirty_files.rb +37 -0
- data/lib/eac_git/rspec.rb +6 -1
- data/lib/eac_git/rspec/stubbed_git_local_repo.rb +60 -0
- data/lib/eac_git/version.rb +1 -1
- data/vendor/git-subrepo/lib/git-subrepo +9 -7
- data/vendor/git-subrepo/lib/git-subrepo.d/bash+.bash +1 -1
- metadata +22 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14b3b82000cc1112a35348248ab9f5ef618269fb62060ff30bf77ca7d2d82108
|
4
|
+
data.tar.gz: 0b2eb750b057130123101dca10c4fd2c099695c40978c8243cbf3939f7484eda
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d21e1d293366d2bbae49c13b263558a896f169983505ab855bddb4a4556ec271a9c3d9f819e9a441a76b830c172d6615eb20b1c353c7029266425213c24183be
|
7
|
+
data.tar.gz: 1c0071afbc32ed6c1e2b1b712caf2b3583dd597fd544a2324d099a552fa61b5feacfbade6ecb21d13e432819556fcd6e4d72da9bd052f72cd7429652103e5e36
|
data/lib/eac_git/local.rb
CHANGED
@@ -6,12 +6,16 @@ require 'eac_ruby_utils/core_ext'
|
|
6
6
|
module EacGit
|
7
7
|
# A Git repository in local filesystem.
|
8
8
|
class Local
|
9
|
-
require_sub __FILE__
|
9
|
+
require_sub __FILE__, include_modules: true
|
10
10
|
|
11
11
|
common_constructor :root_path do
|
12
12
|
self.root_path = root_path.to_pathname
|
13
13
|
end
|
14
14
|
|
15
|
+
def commit(ref, required = false)
|
16
|
+
rev_parse(ref, required).if_present { |v| ::EacGit::Local::Commit.new(self, v) }
|
17
|
+
end
|
18
|
+
|
15
19
|
def descendant?(descendant, ancestor)
|
16
20
|
base = merge_base(descendant, ancestor)
|
17
21
|
return false if base.blank?
|
@@ -48,6 +52,10 @@ module EacGit
|
|
48
52
|
::EacGit::Local::Subrepo.new(self, subpath)
|
49
53
|
end
|
50
54
|
|
55
|
+
def to_s
|
56
|
+
"#{self.class}[#{root_path}]"
|
57
|
+
end
|
58
|
+
|
51
59
|
private
|
52
60
|
|
53
61
|
def merge_base_pair(commit1, commit2)
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
|
5
|
+
module EacGit
|
6
|
+
class Local
|
7
|
+
class Commit
|
8
|
+
require_sub __FILE__, include_modules: true
|
9
|
+
enable_simple_cache
|
10
|
+
|
11
|
+
FIELDS = {
|
12
|
+
author_name: '%an', author_email: '%ae', author_date: '%ai',
|
13
|
+
subject: '%s',
|
14
|
+
author_all: '%an <%ae>, %ai',
|
15
|
+
commiter_name: '%cn', commiter_email: '%ce', commiter_date: '%ci',
|
16
|
+
commiter_all: '%cn <%ce>, %ci'
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
common_constructor :repo, :hash
|
20
|
+
|
21
|
+
def format(format)
|
22
|
+
repo.command('--no-pager', 'log', '-1', "--pretty=format:#{format}", hash).execute!.strip
|
23
|
+
end
|
24
|
+
|
25
|
+
FIELDS.each do |field, format|
|
26
|
+
define_method(field) { format(format) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def changed_files_uncached
|
30
|
+
diff_tree_execute.each_line.map do |line|
|
31
|
+
::EacGit::Local::Commit::ChangedFile.new(self, line)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def changed_files_size_uncached
|
36
|
+
changed_files.inject(0) { |a, e| a + e.dst_size }
|
37
|
+
end
|
38
|
+
|
39
|
+
def root_child?
|
40
|
+
format('%P').blank?
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def diff_tree_execute
|
46
|
+
args = []
|
47
|
+
args << '--root' if root_child?
|
48
|
+
args << hash
|
49
|
+
repo.command(*::EacGit::Local::Commit::DiffTreeLine::GIT_COMMAND_ARGS, *args).execute!
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'eac_git/local/commit/diff_tree_line'
|
5
|
+
|
6
|
+
module EacGit
|
7
|
+
class Local
|
8
|
+
class Commit
|
9
|
+
class ChangedFile
|
10
|
+
enable_simple_cache
|
11
|
+
|
12
|
+
attr_reader :commit, :diff_tree
|
13
|
+
|
14
|
+
# @param commit [EacGit::Local::Commit]
|
15
|
+
# @param diff_tree_line [String] A line from command "repo diff-tree --no-commit-id -r
|
16
|
+
# --full-index"'s output.
|
17
|
+
def initialize(commit, diff_tree_line)
|
18
|
+
@commit = commit
|
19
|
+
@diff_tree = ::EacGit::Local::Commit::DiffTreeLine.new(diff_tree_line)
|
20
|
+
end
|
21
|
+
|
22
|
+
delegate(*::EacGit::Local::Commit::DiffTreeLine::FIELDS, to: :diff_tree)
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"#{path}|#{status}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def src_size_uncached
|
29
|
+
size(src_sha1)
|
30
|
+
end
|
31
|
+
|
32
|
+
def dst_size_uncached
|
33
|
+
size(dst_sha1)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def size(id)
|
39
|
+
return 0 if /\A0+\z/.match(id)
|
40
|
+
|
41
|
+
commit.repo.command('cat-file', '-s', id).execute!.strip.to_i
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module EacGit
|
4
|
+
class Local
|
5
|
+
class Commit
|
6
|
+
class DiffTreeLine
|
7
|
+
DIFF_TREE_PATTERN = /\A:(\d{6}) (\d{6}) (\S+) (\S+) (\S+)\t(\S.*)\z/.freeze
|
8
|
+
FIELDS = %w[src_mode dst_mode src_sha1 dst_sha1 status path].freeze
|
9
|
+
GIT_COMMAND_ARGS = %w[-c core.quotepath=off diff-tree --no-commit-id -r --full-index].freeze
|
10
|
+
|
11
|
+
attr_reader(*FIELDS)
|
12
|
+
|
13
|
+
# line: a line of command "git [GIT_COMMAND_ARGS]"'s output.
|
14
|
+
# Reference: https://git-scm.com/docs/git-diff-tree
|
15
|
+
def initialize(line)
|
16
|
+
m = DIFF_TREE_PATTERN.match(line.strip)
|
17
|
+
raise "\"#{line}\" did not match pattern" unless m
|
18
|
+
|
19
|
+
FIELDS.count.times { |i| send("#{FIELDS[i]}=", m[i + 1]) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def fields
|
23
|
+
FIELDS.map { |field| [field, send(field)] }.to_h
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_writer(*FIELDS)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_ruby_utils/core_ext'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
module EacGit
|
7
|
+
class Local
|
8
|
+
module DirtyFiles
|
9
|
+
STATUS_LINE_PATTERN = /\A(.)(.)\s(.+)\z/.freeze
|
10
|
+
|
11
|
+
def dirty?
|
12
|
+
dirty_files.any?
|
13
|
+
end
|
14
|
+
|
15
|
+
def dirty_file?(path)
|
16
|
+
absolute_path = path.to_pathname.expand_path(root_path)
|
17
|
+
dirty_files.any? do |df|
|
18
|
+
df.absolute_path == absolute_path
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def dirty_files
|
23
|
+
command('status', '--porcelain=v1', '--untracked-files', '--no-renames')
|
24
|
+
.execute!.each_line.map { |line| parse_status_line(line.gsub(/\n\z/, '')) }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def parse_status_line(line)
|
30
|
+
STATUS_LINE_PATTERN.if_match(line) do |m|
|
31
|
+
::OpenStruct.new(index: m[1], worktree: m[2], path: m[3].to_pathname,
|
32
|
+
absolute_path: m[3].to_pathname.expand_path(root_path))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/eac_git/rspec.rb
CHANGED
@@ -5,12 +5,17 @@ require 'eac_git/executables'
|
|
5
5
|
|
6
6
|
module EacGit
|
7
7
|
module Rspec
|
8
|
+
require_sub __FILE__
|
9
|
+
|
8
10
|
class << self
|
9
11
|
def configure
|
10
12
|
::EacRubyUtils::Rspec::Conditional.default.add(:git) do
|
11
13
|
::EacGit::Executables.git.validate
|
12
14
|
end
|
13
|
-
RSpec.configure
|
15
|
+
RSpec.configure do |config|
|
16
|
+
::EacRubyUtils::Rspec::Conditional.default.configure(config)
|
17
|
+
config.include ::EacGit::Rspec::StubbedGitLocalRepo
|
18
|
+
end
|
14
19
|
end
|
15
20
|
end
|
16
21
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'eac_git/local'
|
4
|
+
require 'eac_ruby_utils/envs'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'tmpdir'
|
7
|
+
|
8
|
+
module EacGit
|
9
|
+
module Rspec
|
10
|
+
module StubbedGitLocalRepo
|
11
|
+
def stubbed_git_local_repo(bare = false)
|
12
|
+
path = ::Dir.mktmpdir
|
13
|
+
::EacRubyUtils::Envs.local.command(stubbed_git_local_repo_args(path, bare)).execute!
|
14
|
+
repo = StubbedGitRepository.new(path)
|
15
|
+
repo.command('config', 'user.email', 'theuser@example.net').execute!
|
16
|
+
repo.command('config', 'user.name', 'The User').execute!
|
17
|
+
repo
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def stubbed_git_local_repo_args(path, bare)
|
23
|
+
r = %w[git init]
|
24
|
+
r << '--bare' if bare
|
25
|
+
r + [path]
|
26
|
+
end
|
27
|
+
|
28
|
+
class StubbedGitRepository < ::EacGit::Local
|
29
|
+
def file(*subpath)
|
30
|
+
StubbedGitRepositoryFile.new(self, subpath)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class StubbedGitRepositoryFile
|
35
|
+
attr_reader :git, :subpath
|
36
|
+
|
37
|
+
def initialize(git, subpath)
|
38
|
+
@git = git
|
39
|
+
@subpath = subpath
|
40
|
+
end
|
41
|
+
|
42
|
+
def path
|
43
|
+
git.root_path.join(*subpath)
|
44
|
+
end
|
45
|
+
|
46
|
+
def touch
|
47
|
+
path.touch
|
48
|
+
end
|
49
|
+
|
50
|
+
def delete
|
51
|
+
path.unlink
|
52
|
+
end
|
53
|
+
|
54
|
+
def write(content)
|
55
|
+
path.write(content)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/eac_git/version.rb
CHANGED
@@ -8,6 +8,8 @@
|
|
8
8
|
# Exit on any errors:
|
9
9
|
set -e
|
10
10
|
|
11
|
+
export FILTER_BRANCH_SQUELCH_WARNING=1
|
12
|
+
|
11
13
|
# Import Bash+ helper functions:
|
12
14
|
SOURCE="$BASH_SOURCE"
|
13
15
|
while [[ -h $SOURCE ]]; do
|
@@ -549,7 +551,7 @@ subrepo:pull() {
|
|
549
551
|
fi
|
550
552
|
else
|
551
553
|
o "Merge in changes from $refs_subrepo_fetch"
|
552
|
-
FAIL=false
|
554
|
+
FAIL=false RUN git merge "$refs_subrepo_fetch"
|
553
555
|
if ! OK; then
|
554
556
|
say "The \"git merge\" command failed:"
|
555
557
|
say
|
@@ -765,8 +767,8 @@ subrepo:branch() {
|
|
765
767
|
o "Create with content"
|
766
768
|
local PREVIOUS_IFS=$IFS
|
767
769
|
IFS=$'\n'
|
768
|
-
local author_info=( $(git log -1 --format=%ad%n%ae%n%an "$commit") )
|
769
|
-
local commiter_info=( $(git log -1 --format=%cd%n%ce%n%cn "$commit") )
|
770
|
+
local author_info=( $(git log -1 --date=default --format=%ad%n%ae%n%an "$commit") )
|
771
|
+
local commiter_info=( $(git log -1 --date=default --format=%cd%n%ce%n%cn "$commit") )
|
770
772
|
IFS=$PREVIOUS_IFS
|
771
773
|
|
772
774
|
# When we create new commits we leave the author information unchanged
|
@@ -774,7 +776,7 @@ subrepo:branch() {
|
|
774
776
|
# This should be analog how cherrypicking is handled allowing git
|
775
777
|
# to store both the original author but also the responsible committer
|
776
778
|
# that created the local version of the commit and pushed it.
|
777
|
-
prev_commit=$(git log -n 1 --format=%B "$commit" |
|
779
|
+
prev_commit=$(git log -n 1 --date=default --format=%B "$commit" |
|
778
780
|
GIT_AUTHOR_DATE="${author_info[0]}" \
|
779
781
|
GIT_AUTHOR_EMAIL="${author_info[1]}" \
|
780
782
|
GIT_AUTHOR_NAME="${author_info[2]}" \
|
@@ -959,7 +961,7 @@ subrepo:clean() {
|
|
959
961
|
|
960
962
|
o "Clean $subdir"
|
961
963
|
git:remove-worktree
|
962
|
-
if
|
964
|
+
if git:branch-exists "$branch"; then
|
963
965
|
o "Remove branch '$branch'."
|
964
966
|
RUN git update-ref -d "$ref"
|
965
967
|
clean_list+=("branch '$branch'")
|
@@ -1505,7 +1507,7 @@ assert-subdir-ready-for-init() {
|
|
1505
1507
|
error "The subdir '$subdir' is already a subrepo."
|
1506
1508
|
fi
|
1507
1509
|
# Check that subdir is part of the repo
|
1508
|
-
if [[ -z $(git log -1 -- $subdir) ]]; then
|
1510
|
+
if [[ -z $(git log -1 --date=default -- $subdir) ]]; then
|
1509
1511
|
error "The subdir '$subdir' is not part of this repo."
|
1510
1512
|
fi
|
1511
1513
|
}
|
@@ -1535,7 +1537,7 @@ get-all-subrepos() {
|
|
1535
1537
|
add-subrepo() {
|
1536
1538
|
if ! $ALL_wanted; then
|
1537
1539
|
for path in "${subrepos[@]}"; do
|
1538
|
-
[[ $1 =~ ^$path ]] && return
|
1540
|
+
[[ $1/ =~ ^$path/ ]] && return
|
1539
1541
|
done
|
1540
1542
|
fi
|
1541
1543
|
subrepos+=("$1")
|
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
../../ext/bashplus/lib/bash+.bash
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eac_git
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Put here the authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eac_ruby_utils
|
@@ -44,6 +44,20 @@ dependencies:
|
|
44
44
|
- - ">="
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 1.0.8
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: aranha-parsers
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0.7'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.7'
|
47
61
|
- !ruby/object:Gem::Dependency
|
48
62
|
name: eac_ruby_gem_support
|
49
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -73,11 +87,16 @@ files:
|
|
73
87
|
- lib/eac_git.rb
|
74
88
|
- lib/eac_git/executables.rb
|
75
89
|
- lib/eac_git/local.rb
|
90
|
+
- lib/eac_git/local/commit.rb
|
91
|
+
- lib/eac_git/local/commit/changed_file.rb
|
92
|
+
- lib/eac_git/local/commit/diff_tree_line.rb
|
93
|
+
- lib/eac_git/local/dirty_files.rb
|
76
94
|
- lib/eac_git/local/subrepo.rb
|
77
95
|
- lib/eac_git/local/subrepo/config.rb
|
78
96
|
- lib/eac_git/remote.rb
|
79
97
|
- lib/eac_git/remote/ls_result.rb
|
80
98
|
- lib/eac_git/rspec.rb
|
99
|
+
- lib/eac_git/rspec/stubbed_git_local_repo.rb
|
81
100
|
- lib/eac_git/version.rb
|
82
101
|
- vendor/git-subrepo/Changes
|
83
102
|
- vendor/git-subrepo/Intro.pod
|
@@ -282,8 +301,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
282
301
|
- !ruby/object:Gem::Version
|
283
302
|
version: '0'
|
284
303
|
requirements: []
|
285
|
-
|
286
|
-
rubygems_version: 2.7.7
|
304
|
+
rubygems_version: 3.0.9
|
287
305
|
signing_key:
|
288
306
|
specification_version: 4
|
289
307
|
summary: Put here de description.
|