... | ... |
@@ -15,29 +15,74 @@ use Gitprep::Util; |
15 | 15 |
has 'app'; |
16 | 16 |
has 'authorized_keys_file'; |
17 | 17 |
|
18 |
-sub lock_rep { |
|
19 |
- my ($self, $rep_info) = @_; |
|
20 |
- |
|
21 |
- my $git_dir = $rep_info->{git_dir}; |
|
22 |
- my $lock_file = "$git_dir/config"; |
|
23 |
- |
|
24 |
- open my $lock_fh, '<', $lock_file |
|
25 |
- or croak "Can't open lock file $lock_file: $!"; |
|
26 |
- |
|
27 |
- flock $lock_fh, LOCK_EX |
|
28 |
- or croak "Can't lock $lock_file"; |
|
29 |
- |
|
30 |
- return $lock_fh; |
|
18 |
+has '_tmp_branch' => '__gitprep_tmp_branch__'; |
|
19 |
+ |
|
20 |
+sub prepare_merge { |
|
21 |
+ my ($self, $work_rep_info, $rep_info1, $base_branch, $rep_info2, $target_branch) = @_; |
|
22 |
+ |
|
23 |
+ # Fetch base repository |
|
24 |
+ my $base_user_id = $rep_info1->{user}; |
|
25 |
+ my @git_fetch_base_cmd = $self->app->git->cmd($work_rep_info, 'fetch', 'origin', $base_branch); |
|
26 |
+ Gitprep::Util::run_command(@git_fetch_base_cmd) |
|
27 |
+ or Carp::croak "Can't execute git fetch: @git_fetch_base_cmd"; |
|
28 |
+ |
|
29 |
+ # Remeve remote |
|
30 |
+ my $target_user_id = $rep_info2->{user}; |
|
31 |
+ my @git_remote_remove_cmd = $self->app->git->cmd( |
|
32 |
+ $work_rep_info, |
|
33 |
+ 'remote', |
|
34 |
+ 'remove', |
|
35 |
+ $target_user_id |
|
36 |
+ ); |
|
37 |
+ Gitprep::Util::run_command(@git_remote_remove_cmd); |
|
38 |
+ |
|
39 |
+ # Set remote add target repository |
|
40 |
+ my $target_git_dir = $rep_info2->{git_dir}; |
|
41 |
+ my @git_remote_add_cmd = $self->app->git->cmd( |
|
42 |
+ $work_rep_info, |
|
43 |
+ 'remote', |
|
44 |
+ 'add', |
|
45 |
+ $target_user_id, |
|
46 |
+ $target_git_dir |
|
47 |
+ ); |
|
48 |
+ Gitprep::Util::run_command(@git_remote_add_cmd) |
|
49 |
+ or Carp::croak "Can't execute git remote add: @git_remote_add_cmd"; |
|
50 |
+ |
|
51 |
+ # Fetch target repository |
|
52 |
+ my @git_fetch_target_cmd = $self->app->git->cmd($work_rep_info, 'fetch', $target_user_id, $target_branch); |
|
53 |
+ Gitprep::Util::run_command(@git_fetch_target_cmd) |
|
54 |
+ or Carp::croak "Can't execute git fetch: @git_fetch_target_cmd"; |
|
55 |
+ |
|
56 |
+ # Checkout tmp branch and git reset --hard from my remote branch |
|
57 |
+ my @git_checkout_tmp_branch = $self->app->git->cmd( |
|
58 |
+ $work_rep_info, |
|
59 |
+ 'checkout', |
|
60 |
+ $self->_tmp_branch |
|
61 |
+ ); |
|
62 |
+ Gitprep::Util::run_command(@git_checkout_tmp_branch) |
|
63 |
+ or Carp::croak "Can't execute git checkout: @git_checkout_tmp_branch"; |
|
64 |
+ |
|
65 |
+ # git reset --hard |
|
66 |
+ my @git_reset_hard_cmd = $self->app->git->cmd( |
|
67 |
+ $work_rep_info, |
|
68 |
+ 'reset', |
|
69 |
+ '--hard', |
|
70 |
+ "origin/$base_branch" |
|
71 |
+ ); |
|
72 |
+ Gitprep::Util::run_command(@git_reset_hard_cmd) |
|
73 |
+ or Carp::croak "Can't execute git reset --hard: @git_reset_hard_cmd"; |
|
31 | 74 |
} |
32 | 75 |
|
33 | 76 |
sub check_merge_automatical { |
34 |
- my ($self, $rep_info, $branch1, $branch2) = @_; |
|
77 |
+ my ($self, $work_rep_info, $rep_info1, $base_branch, $rep_info2, $target_branch) = @_; |
|
35 | 78 |
|
36 | 79 |
# Create patch |
80 |
+ my $tmp_branch = $self->_tmp_branch; |
|
81 |
+ my $target_user_id = $rep_info2->{user}; |
|
37 | 82 |
my @git_format_patch_cmd = $self->app->git->cmd( |
38 |
- $rep_info, |
|
83 |
+ $work_rep_info, |
|
39 | 84 |
'format-patch', |
40 |
- "$branch1..$branch2", |
|
85 |
+ "$tmp_branch..$target_user_id/$target_branch", |
|
41 | 86 |
"--stdout" |
42 | 87 |
); |
43 | 88 |
open my $git_format_patch_fh, '-|', @git_format_patch_cmd |
... | ... |
@@ -54,7 +99,7 @@ sub check_merge_automatical { |
54 | 99 |
|
55 | 100 |
# Check if this patch can be applied |
56 | 101 |
my @git_apply_cmd = $self->app->git->cmd( |
57 |
- $rep_info, |
|
102 |
+ $work_rep_info, |
|
58 | 103 |
'apply', |
59 | 104 |
$patch_file, |
60 | 105 |
'--check' |
... | ... |
@@ -64,6 +109,21 @@ sub check_merge_automatical { |
64 | 109 |
return $automatical; |
65 | 110 |
} |
66 | 111 |
|
112 |
+sub lock_rep { |
|
113 |
+ my ($self, $rep_info) = @_; |
|
114 |
+ |
|
115 |
+ my $git_dir = $rep_info->{git_dir}; |
|
116 |
+ my $lock_file = "$git_dir/config"; |
|
117 |
+ |
|
118 |
+ open my $lock_fh, '<', $lock_file |
|
119 |
+ or croak "Can't open lock file $lock_file: $!"; |
|
120 |
+ |
|
121 |
+ flock $lock_fh, LOCK_EX |
|
122 |
+ or croak "Can't lock $lock_file"; |
|
123 |
+ |
|
124 |
+ return $lock_fh; |
|
125 |
+} |
|
126 |
+ |
|
67 | 127 |
sub create_work_rep { |
68 | 128 |
my ($self, $user, $project) = @_; |
69 | 129 |
|
... | ... |
@@ -84,11 +144,10 @@ sub create_work_rep { |
84 | 144 |
or croak "Can't git clone: @git_clone_cmd"; |
85 | 145 |
|
86 | 146 |
# Create temparary branch |
87 |
- my $gitprep_tmp_branch_name = '__gitprep_tmp_branch__'; |
|
88 | 147 |
my @git_branch_cmd = $self->app->git->cmd( |
89 | 148 |
$work_rep_info, |
90 | 149 |
'branch', |
91 |
- $gitprep_tmp_branch_name, |
|
150 |
+ $self->_tmp_branch |
|
92 | 151 |
); |
93 | 152 |
Gitprep::Util::run_command(@git_branch_cmd) |
94 | 153 |
or Carp::croak "Can't execute git branch: @git_branch_cmd"; |
... | ... |
@@ -101,7 +101,8 @@ |
101 | 101 |
} |
102 | 102 |
|
103 | 103 |
# Commits |
104 |
- my $commits = $git->forward_commits(app->rep_info($user_id, $project_id), $from_rev, $rev); |
|
104 |
+ my $rep_info = app->rep_info($user_id, $project_id); |
|
105 |
+ my $commits = $git->forward_commits($rep_info, $from_rev, $rev); |
|
105 | 106 |
my $commits_count = @$commits; |
106 | 107 |
my $commits_date = {}; |
107 | 108 |
my $authors = {}; |
... | ... |
@@ -114,10 +115,10 @@ |
114 | 115 |
my $authors_count = keys %$authors; |
115 | 116 |
|
116 | 117 |
# Start commit |
117 |
- my $start_commit = $git->separated_commit(app->rep_info($user_id, $project_id), $from_rev, $rev); |
|
118 |
+ my $start_commit = $git->separated_commit($rep_info, $from_rev, $rev); |
|
118 | 119 |
|
119 | 120 |
# End commit |
120 |
- my $end_commit = $git->get_commit(app->rep_info($user_id, $project_id), $rev); |
|
121 |
+ my $end_commit = $git->get_commit($rep_info, $rev); |
|
121 | 122 |
|
122 | 123 |
if (!$start_commit || !$end_commit) { |
123 | 124 |
$self->reply->not_found; |
... | ... |
@@ -125,7 +126,7 @@ |
125 | 126 |
} |
126 | 127 |
|
127 | 128 |
# Branches |
128 |
- my $branches = $git->branches(app->rep_info($user_id, $project_id)); |
|
129 |
+ my $branches = $git->branches($rep_info); |
|
129 | 130 |
@$branches = sort { $a->{commit}{age} <=> $b->{commit}{age} } @$branches; |
130 | 131 |
|
131 | 132 |
# Variables |
... | ... |
@@ -147,41 +148,30 @@ |
147 | 148 |
# Create working repository if it don't exist |
148 | 149 |
$self->app->manager->create_work_rep($user_id, $project_id); |
149 | 150 |
|
150 |
- # Fetch repository |
|
151 |
+ # Lock working repository |
|
151 | 152 |
my $work_rep_info = app->work_rep_info($user_id, $project_id); |
152 |
- my @git_fetch_cmd = $self->app->git->cmd($work_rep_info, 'fetch'); |
|
153 |
- Gitprep::Util::run_command(@git_fetch_cmd) |
|
154 |
- or Carp::croak "Can't execute git fetch: @git_fetch_cmd"; |
|
153 |
+ my $lock_fh = $self->app->manager->lock_rep($work_rep_info); |
|
155 | 154 |
|
156 |
- # Lock repository |
|
157 |
- my $lock = $self->app->manager->lock_rep($work_rep_info); |
|
158 |
- |
|
159 |
- # Checkout tmp branch and git reset --hard from my remote branch |
|
160 |
- my $gitprep_tmp_branch_name = '__gitprep_tmp_branch__'; |
|
161 |
- my @git_checkout_tmp_branch = $self->app->git->cmd( |
|
162 |
- $work_rep_info, |
|
163 |
- 'checkout', |
|
164 |
- $gitprep_tmp_branch_name, |
|
165 |
- ); |
|
166 |
- Gitprep::Util::run_command(@git_checkout_tmp_branch) |
|
167 |
- or Carp::croak "Can't execute git checkout: @git_checkout_tmp_branch"; |
|
168 |
- |
|
169 |
- # git reset --hard |
|
170 |
- my @git_reset_hard_cmd = $self->app->git->cmd( |
|
155 |
+ # Prepare merge |
|
156 |
+ $self->app->manager->prepare_merge( |
|
171 | 157 |
$work_rep_info, |
172 |
- 'reset', |
|
173 |
- '--hard', |
|
174 |
- "origin/$from_rev" |
|
158 |
+ $rep_info, |
|
159 |
+ $from_rev, |
|
160 |
+ $rep_info, |
|
161 |
+ $rev |
|
175 | 162 |
); |
176 |
- Gitprep::Util::run_command(@git_reset_hard_cmd) |
|
177 |
- or Carp::croak "Can't execute git reset --hard: @git_reset_hard_cmd"; |
|
178 | 163 |
|
179 | 164 |
# Check merge automatically |
180 | 165 |
$merge_automatical = $self->app->manager->check_merge_automatical( |
181 |
- app->work_rep_info($user_id, $project_id), |
|
182 |
- $gitprep_tmp_branch_name, |
|
183 |
- "origin/$rev" |
|
166 |
+ $work_rep_info, |
|
167 |
+ $rep_info, |
|
168 |
+ $from_rev, |
|
169 |
+ $rep_info, |
|
170 |
+ $rev |
|
184 | 171 |
); |
172 |
+ |
|
173 |
+ # Unlock explicitly |
|
174 |
+ close $lock_fh; |
|
185 | 175 |
} |
186 | 176 |
|
187 | 177 |
layout 'common', title => "Comparing $from_rev...$rev \x{30fb} $user_id/$project_id"; |
... | ... |
@@ -88,6 +88,18 @@ |
88 | 88 |
where => {pull_request => $row_id, number => 1} |
89 | 89 |
)->one; |
90 | 90 |
|
91 |
+ # Check merge automatically |
|
92 |
+ my $merge_automatical; |
|
93 |
+ if ($api->can_write_access($session_user_id, $user_id, $project_id) && $pull_request->{open}) { |
|
94 |
+ $merge_automatical = $self->app->manager->check_merge_automatical( |
|
95 |
+ app->work_rep_info($user_id, $project_id), |
|
96 |
+ $rep_info, |
|
97 |
+ $branch1, |
|
98 |
+ $rep_info, |
|
99 |
+ $branch2 |
|
100 |
+ ); |
|
101 |
+ } |
|
102 |
+ |
|
91 | 103 |
# Commit body arguments |
92 | 104 |
my %commit_body_args = ( |
93 | 105 |
id => $end_commit->{id}, |