| ... | ... | @@ -223,6 +223,9 @@ sub startup { | 
| 223 | 223 |  | 
| 224 | 224 | # Network Graph | 
| 225 | 225 |          $r->get('/network/graph/(*rev1)...(*rev2_abs)' => template '/network/graph'); | 
| 226 | + | |
| 227 | + # Pull | |
| 228 | +        $r->get('/pull/(*rev1)...(*rev2_abs)' => template '/pull'); | |
| 226 | 229 |  | 
| 227 | 230 | # Get branches and tags | 
| 228 | 231 |          $r->get('/api/revs' => template '/api/revs'); | 
| ... | ... | @@ -24,8 +24,8 @@ | 
| 24 | 24 |  | 
| 25 | 25 | %= javascript begin | 
| 26 | 26 |      $(document).ready(function () { | 
| 27 | - // Update user and project hidden field | |
| 28 | -      $('[name=remote-btn]').on('click', function () { | |
| 27 | + // Click compare button | |
| 28 | +      $('[name=compare-btn]').on('click', function () { | |
| 29 | 29 |          var branch = $('[name=branch]').val(); | 
| 30 | 30 |          var remote = $(this).closest('[name=remote]'); | 
| 31 | 31 |          var remote_member = remote.find('[name=remote-member]').text(); | 
| ... | ... | @@ -35,6 +35,18 @@ | 
| 35 | 35 |          location.href = '<%= url_for("/$user/$project/network/graph/") %>' + branch + '...' | 
| 36 | 36 | + remote_member + '/' + remote_project + '/' + remote_branch; | 
| 37 | 37 | }); | 
| 38 | + | |
| 39 | + // Click pull button | |
| 40 | +      $('[name=pull-btn]').on('click', function () { | |
| 41 | +        var branch = $('[name=branch]').val(); | |
| 42 | +        var remote = $(this).closest('[name=remote]'); | |
| 43 | +        var remote_member = remote.find('[name=remote-member]').text(); | |
| 44 | +        var remote_project = remote.find('[name=remote-project]').text(); | |
| 45 | +        var remote_branch = remote.find('[name=remote-branch]').val(); | |
| 46 | + | |
| 47 | +        location.href = '<%= url_for("/$user/$project/pull/") %>' + branch + '...' | |
| 48 | + + remote_member + '/' + remote_project + '/' + remote_branch; | |
| 49 | + }); | |
| 38 | 50 | }); | 
| 39 | 51 | % end | 
| 40 | 52 |  | 
| ... | ... | @@ -67,7 +79,8 @@ | 
| 67 | 79 | %= select_field 'remote-branch' => $mbranches, style => 'margin-top:5px;margin-bottom:7px;width:150px'; | 
| 68 | 80 | </div> | 
| 69 | 81 | <div class="text-right"> | 
| 70 | - <button name="remote-btn" class="btn" style="margin-top:5px">Compare</button> | |
| 82 | + <button name="compare-btn" class="btn" style="margin-top:5px">Compare</button> | |
| 83 | + <button name="pull-btn" class="btn" style="margin-top:5px">Pull</button> | |
| 71 | 84 | </div> | 
| 72 | 85 | </div> | 
| 73 | 86 | <hr style="margin:0"> | 
| ... | ... | @@ -61,7 +61,7 @@ | 
| 61 | 61 | <h3>Graph</h3> | 
| 62 | 62 | <div style="margin-bottom:20px">Compare 100 commits.</div> | 
| 63 | 63 | <div style="margin-bottom:10px"> | 
| 64 | - <span style="color:blue;font-size:22px"><b><%= "$user / $project / $branch" %></big></span> | |
| 64 | + <span style="color:blue;font-size:22px"><%= "$user / $project / $branch" %></span> | |
| 65 | 65 | </div> | 
| 66 | 66 | <div id="graph" class="well" style="width:800px;overflow:auto;padding-left:10px;padding-right:10px"> | 
| 67 | 67 | <table> | 
| ... | ... | @@ -88,7 +88,7 @@ | 
| 88 | 88 | </table> | 
| 89 | 89 | </div> | 
| 90 | 90 | <div style="margin-bottom:30px"> | 
| 91 | - <span style="color:green;font-size:18px"><b><big><%= "$remote_user / $remote_project / $remote_branch" %></big></b></span> | |
| 91 | + <span style="color:green;font-size:22px"><%= "$remote_user / $remote_project / $remote_branch" %></span> | |
| 92 | 92 | </div> | 
| 93 | 93 | </div> | 
| 94 | 94 |  | 
| ... | ... | @@ -0,0 +1,81 @@ | 
| 1 | +<% | |
| 2 | +  my $user = param('user'); | |
| 3 | +  my $project = param('project'); | |
| 4 | +  my $branch = param('rev1'); | |
| 5 | +  my $rev2_abs = param('rev2_abs'); | |
| 6 | + my ($remote_user, $remote_project, $remote_branch) = split /\//, $rev2_abs, 3; | |
| 7 | + | |
| 8 | + my $commits = app->git->get_commits($user, $project, $branch, 100); | |
| 9 | + my $remote_commits = app->git->get_commits( | |
| 10 | + $remote_user, | |
| 11 | + $remote_project, | |
| 12 | + $remote_branch, | |
| 13 | + 100 | |
| 14 | + ); | |
| 15 | + | |
| 16 | +  my $merged_commits_h = {}; | |
| 17 | +  for my $commit (@$commits) { | |
| 18 | +    my $id = $commit->{id}; | |
| 19 | +    $merged_commits_h->{$id} ||= {}; | |
| 20 | +    $merged_commits_h->{$id}{age} = $commit->{age}; | |
| 21 | +    $merged_commits_h->{$id}{age_string_date} = $commit->{age_string_date}; | |
| 22 | +    $merged_commits_h->{$id}{title} = $commit->{title}; | |
| 23 | +    $merged_commits_h->{$id}{type} = 'local'; | |
| 24 | + } | |
| 25 | +  for my $commit (@$remote_commits) { | |
| 26 | +    my $id = $commit->{id}; | |
| 27 | +    if ($merged_commits_h->{$id}) { | |
| 28 | +      $merged_commits_h->{$id}{type} = 'same'; | |
| 29 | + } | |
| 30 | +    else { | |
| 31 | +      $merged_commits_h->{$id} ||= {}; | |
| 32 | +      $merged_commits_h->{$id}{age} = $commit->{age}; | |
| 33 | +      $merged_commits_h->{$id}{age_string_date} = $commit->{age_string_date}; | |
| 34 | +      $merged_commits_h->{$id}{title} = $commit->{title}; | |
| 35 | +      $merged_commits_h->{$id}{type} = 'remote'; | |
| 36 | + } | |
| 37 | + } | |
| 38 | + | |
| 39 | + my $merged_commits = []; | |
| 40 | + for my $id ( | |
| 41 | +    sort { $merged_commits_h->{$b}{age} <=> $merged_commits_h->{$a}{age}} | |
| 42 | + keys %$merged_commits_h) | |
| 43 | +  { | |
| 44 | +    my $commit = {%{$merged_commits_h->{$id}}}; | |
| 45 | +    $commit->{id} = $id; | |
| 46 | + push @$merged_commits, $commit; | |
| 47 | + } | |
| 48 | +%> | |
| 49 | + | |
| 50 | +% layout 'common', title => "Pull $user/$project/$branch...$rev2_abs"; | |
| 51 | + %= include 'include/header'; | |
| 52 | + | |
| 53 | + %= javascript begin | |
| 54 | +    $('document').ready(function () { | |
| 55 | + // Scroll to right | |
| 56 | +      $('#graph').scrollLeft(1000); | |
| 57 | + }); | |
| 58 | + % end | |
| 59 | + | |
| 60 | + <div class="container"> | |
| 61 | + <h3>Pull</h3> | |
| 62 | + <div class="row" style="font-size:22px"> | |
| 63 | + <div class="span5"> | |
| 64 | + <div class="well" style="text-align:center"> | |
| 65 | + <span style="color:blue;"><%= "$user / $project / $branch" %></span> | |
| 66 | + </div> | |
| 67 | + </div> | |
| 68 | + <div class="span2"> | |
| 69 | + <div style="padding: 19px;text-align:center;font-size:26px"> | |
| 70 | + ⇐ | |
| 71 | + </div> | |
| 72 | + </div> | |
| 73 | + <div class="span5"> | |
| 74 | + <div class="well" style="text-align:center"> | |
| 75 | + <span style="color:green;"><%= "$remote_user / $remote_project / $remote_branch" %></span> | |
| 76 | + </div> | |
| 77 | + </div> | |
| 78 | + </div> | |
| 79 | + </div> | |
| 80 | + | |
| 81 | + %= include '/include/footer'; |