Showing 3 changed files with 111 additions and 50 deletions
+78 -19
lib/Gitprep/Manager.pm
... ...
@@ -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";
+21 -31
templates/compare.html.ep
... ...
@@ -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";
+12
templates/pull.html.ep
... ...
@@ -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},