Sam Jeston
History
256 lines·
14.5 KB
·HTML
| 1 | {% extends "layout_repo.html" %} |
| 2 | {% block page_title %}{{ pr.title }} · Pull request #{{ pr.number }} · {% endblock %} |
| 3 | {% block content %} |
| 4 | {% let base = r.base() %} |
| 5 | {% let purl = r.pull_url(pr.number) %} |
| 6 | <div class="pull-header"> |
| 7 | <div class="pull-title-row"> |
| 8 | <h1 class="pull-title">{{ pr.title }} <span class="text-muted">#{{ pr.number }}</span></h1> |
| 9 | {% if can_close %}<button type="button" class="btn btn-sm" data-toggle="edit-pull">Edit</button>{% endif %} |
| 10 | </div> |
| 11 | {% if can_close %} |
| 12 | <form id="edit-pull" class="box box-body form edit-pull" method="post" action="{{ purl }}/edit" hidden> |
| 13 | <label class="field"><span class="field-label">Title</span><input class="input" type="text" name="title" value="{{ pr.title }}" maxlength="256" required></label> |
| 14 | <label class="field"><span class="field-label">Description</span><textarea class="input" name="body" rows="6">{{ pr.body }}</textarea></label> |
| 15 | <div class="form-actions"> |
| 16 | <button class="btn btn-primary" type="submit">Save</button> |
| 17 | <button class="btn" type="button" data-toggle="edit-pull">Cancel</button> |
| 18 | </div> |
| 19 | </form> |
| 20 | {% endif %} |
| 21 | <div class="pull-meta"> |
| 22 | {% if pr.state == "merged" %} |
| 23 | <span class="state state-merged">{{ crate::web::fmt::icon("git-merge")|safe }} Merged</span> |
| 24 | <span><strong>{{ pr.merged_by.clone().unwrap_or(pr.author.clone()) }}</strong> merged {{ crate::web::fmt::plural(data.commits.len(), "commit") }} into <span class="branch-label">{{ pr.base_branch }}</span> from <span class="branch-label">{{ pr.head_branch }}</span>{% if let Some(t) = pr.merged_at %} <time title="{{ crate::web::fmt::datetime_full(t) }}">{{ crate::web::fmt::ago(t) }}</time>{% endif %}</span> |
| 25 | {% else if pr.state == "closed" %} |
| 26 | <span class="state state-closed">{{ crate::web::fmt::icon("git-pull-request-closed")|safe }} Closed</span> |
| 27 | <span><strong>{{ pr.author }}</strong> wanted to merge {{ crate::web::fmt::plural(data.commits.len(), "commit") }} into <span class="branch-label">{{ pr.base_branch }}</span> from <span class="branch-label">{{ pr.head_branch }}</span></span> |
| 28 | {% else %} |
| 29 | <span class="state state-open">{{ crate::web::fmt::icon("git-pull-request")|safe }} Open</span> |
| 30 | <span><strong>{{ pr.author }}</strong> wants to merge {{ crate::web::fmt::plural(data.commits.len(), "commit") }} into <span class="branch-label">{{ pr.base_branch }}</span> from <span class="branch-label">{{ pr.head_branch }}</span></span> |
| 31 | {% endif %} |
| 32 | </div> |
| 33 | </div> |
| 34 | |
| 35 | <nav class="tabs tabs-sub" aria-label="Pull request"> |
| 36 | <a class="tab{% if pull_tab == "conversation" %} selected{% endif %}" href="{{ purl }}">{{ crate::web::fmt::icon("message-square")|safe }} Conversation <span class="counter">{{ pr.comments }}</span></a> |
| 37 | <a class="tab{% if pull_tab == "commits" %} selected{% endif %}" href="{{ purl }}/commits">{{ crate::web::fmt::icon("git-commit-horizontal")|safe }} Commits <span class="counter">{{ data.commits.len() }}</span></a> |
| 38 | <a class="tab{% if pull_tab == "files" %} selected{% endif %}" href="{{ purl }}/files">{{ crate::web::fmt::icon("file-text")|safe }} Files changed <span class="counter">{{ data.files }}</span></a> |
| 39 | <span class="tabs-extra"><span class="text-success">+{{ data.additions }}</span> <span class="text-danger">−{{ data.deletions }}</span></span> |
| 40 | </nav> |
| 41 | |
| 42 | {% if pull_tab == "conversation" %} |
| 43 | <div class="layout-pull"> |
| 44 | <div class="timeline"> |
| 45 | <div class="timeline-comment"> |
| 46 | <div class="timeline-avatar">{{ crate::web::fmt::avatar(pr.author, 40)|safe }}</div> |
| 47 | <div class="comment"> |
| 48 | <div class="comment-header"> |
| 49 | <strong>{{ pr.author }}</strong> <span class="text-muted">opened this <time title="{{ crate::web::fmt::datetime_full(pr.created_at) }}">{{ crate::web::fmt::ago(pr.created_at) }}</time></span> |
| 50 | <span class="label comment-role">Author</span> |
| 51 | </div> |
| 52 | <div class="comment-body markdown-body"> |
| 53 | {% if pr.body.is_empty() %}<p class="text-muted"><em>No description provided.</em></p>{% else %}{{ body_html|safe }}{% endif %} |
| 54 | </div> |
| 55 | </div> |
| 56 | </div> |
| 57 | |
| 58 | {% for item in timeline %} |
| 59 | {% let e = item.event %} |
| 60 | {% if e.kind == "comment" %} |
| 61 | <div class="timeline-comment" id="event-{{ e.id }}"> |
| 62 | <div class="timeline-avatar">{{ crate::web::fmt::avatar(e.author, 40)|safe }}</div> |
| 63 | <div class="comment"> |
| 64 | <div class="comment-header"> |
| 65 | <strong>{{ e.author }}</strong> <span class="text-muted">commented <a class="text-muted" href="#event-{{ e.id }}"><time title="{{ crate::web::fmt::datetime_full(e.created_at) }}">{{ crate::web::fmt::ago(e.created_at) }}</time></a></span> |
| 66 | {% if e.author == pr.author %}<span class="label comment-role">Author</span>{% endif %} |
| 67 | </div> |
| 68 | <div class="comment-body markdown-body">{{ item.html|safe }}</div> |
| 69 | </div> |
| 70 | </div> |
| 71 | {% else %} |
| 72 | <div class="timeline-event"> |
| 73 | {% if e.kind == "merged" %} |
| 74 | <span class="event-badge badge-merged">{{ crate::web::fmt::icon("git-merge")|safe }}</span> |
| 75 | <span>{% if e.author.is_empty() %}This pull request was <strong>merged</strong>{% else %}<strong>{{ e.author }}</strong> merged{% endif %} |
| 76 | {% if let Some(sha) = pr.merge_commit_sha %}commit <a class="text-mono" href="{{ base }}/commit/{{ sha }}">{{ crate::web::fmt::short_sha(sha) }}</a>{% endif %} |
| 77 | into <span class="branch-label">{{ pr.base_branch }}</span> |
| 78 | {% else if e.kind == "closed" %} |
| 79 | <span class="event-badge badge-closed">{{ crate::web::fmt::icon("git-pull-request-closed")|safe }}</span> |
| 80 | <span><strong>{{ e.author }}</strong> closed this |
| 81 | {% else if e.kind == "reopened" %} |
| 82 | <span class="event-badge badge-open">{{ crate::web::fmt::icon("git-pull-request")|safe }}</span> |
| 83 | <span><strong>{{ e.author }}</strong> reopened this |
| 84 | {% else if e.kind == "branch_deleted" %} |
| 85 | <span class="event-badge">{{ crate::web::fmt::icon("git-branch")|safe }}</span> |
| 86 | <span><strong>{{ e.author }}</strong> deleted the <span class="branch-label">{{ e.body }}</span> branch |
| 87 | {% else %} |
| 88 | <span class="event-badge">{{ crate::web::fmt::icon("clock")|safe }}</span> |
| 89 | <span>{{ e.kind }} |
| 90 | {% endif %} |
| 91 | <time class="text-muted" title="{{ crate::web::fmt::datetime_full(e.created_at) }}">{{ crate::web::fmt::ago(e.created_at) }}</time></span> |
| 92 | </div> |
| 93 | {% endif %} |
| 94 | {% endfor %} |
| 95 | |
| 96 | {% if pr.state == "open" %} |
| 97 | <div class="timeline-comment merge-section"> |
| 98 | <div class="timeline-avatar merge-avatar state-{% if data.mergeability == Some(crate::git::Mergeability::Clean) %}open{% else %}neutral{% endif %}">{{ crate::web::fmt::icon("git-merge")|safe }}</div> |
| 99 | <div class="merge-box{% if data.mergeability == Some(crate::git::Mergeability::Clean) %} merge-box-ready{% endif %}"> |
| 100 | {% if !data.head_exists %} |
| 101 | <div class="merge-status"> |
| 102 | <span class="merge-status-icon status-neutral">{{ crate::web::fmt::icon("git-branch")|safe }}</span> |
| 103 | <div><strong>The head branch {{ pr.head_branch }} no longer exists.</strong><div class="text-muted">Push the branch again or close this pull request.</div></div> |
| 104 | </div> |
| 105 | {% else if !data.base_exists %} |
| 106 | <div class="merge-status"> |
| 107 | <span class="merge-status-icon status-neutral">{{ crate::web::fmt::icon("git-branch")|safe }}</span> |
| 108 | <div><strong>The base branch {{ pr.base_branch }} no longer exists.</strong></div> |
| 109 | </div> |
| 110 | {% else if data.mergeability == Some(crate::git::Mergeability::Conflicts) %} |
| 111 | <div class="merge-status"> |
| 112 | <span class="merge-status-icon status-danger">{{ crate::web::fmt::icon("x")|safe }}</span> |
| 113 | <div><strong>This branch has conflicts that must be resolved</strong><div class="text-muted">Resolve them locally and push the result:</div></div> |
| 114 | </div> |
| 115 | <pre class="command merge-instructions">git fetch origin |
| 116 | git checkout {{ pr.head_branch }} |
| 117 | git merge origin/{{ pr.base_branch }} |
| 118 | # fix conflicts, then |
| 119 | git commit |
| 120 | git push origin {{ pr.head_branch }}</pre> |
| 121 | {% else %} |
| 122 | <div class="merge-status"> |
| 123 | <span class="merge-status-icon status-success">{{ crate::web::fmt::icon("check")|safe }}</span> |
| 124 | <div><strong>This branch has no conflicts with the base branch</strong><div class="text-muted">Merging can be performed automatically.</div></div> |
| 125 | </div> |
| 126 | {% if r.access.write %} |
| 127 | <form class="merge-form" method="post" action="{{ purl }}/merge"> |
| 128 | <select class="input input-sm" name="method" aria-label="Merge method"> |
| 129 | <option value="merge">Create a merge commit</option> |
| 130 | <option value="squash">Squash and merge</option> |
| 131 | <option value="rebase">Rebase and merge</option> |
| 132 | </select> |
| 133 | <button class="btn btn-success" type="submit">{{ crate::web::fmt::icon("git-merge")|safe }} Merge pull request</button> |
| 134 | </form> |
| 135 | {% else %} |
| 136 | <p class="merge-note text-muted">Only people with write access to this repository can merge pull requests.</p> |
| 137 | {% endif %} |
| 138 | {% endif %} |
| 139 | </div> |
| 140 | </div> |
| 141 | {% else if pr.state == "merged" %} |
| 142 | <div class="timeline-comment merge-section"> |
| 143 | <div class="timeline-avatar merge-avatar state-merged">{{ crate::web::fmt::icon("git-merge")|safe }}</div> |
| 144 | <div class="merge-box merge-box-merged"> |
| 145 | <div class="merge-status"> |
| 146 | <div><strong>Pull request successfully merged and closed</strong><div class="text-muted">{% if can_delete_branch %}The <span class="branch-label">{{ pr.head_branch }}</span> branch can be safely deleted.{% else %}You're all set.{% endif %}</div></div> |
| 147 | {% if can_delete_branch %} |
| 148 | <form method="post" action="{{ base }}/branches/delete"> |
| 149 | <input type="hidden" name="branch" value="{{ pr.head_branch }}"> |
| 150 | <input type="hidden" name="return_to" value="{{ purl }}"> |
| 151 | <input type="hidden" name="pr" value="{{ pr.number }}"> |
| 152 | <button class="btn btn-sm" type="submit">Delete branch</button> |
| 153 | </form> |
| 154 | {% endif %} |
| 155 | </div> |
| 156 | </div> |
| 157 | </div> |
| 158 | {% else %} |
| 159 | <div class="timeline-comment merge-section"> |
| 160 | <div class="timeline-avatar merge-avatar state-closed">{{ crate::web::fmt::icon("git-pull-request-closed")|safe }}</div> |
| 161 | <div class="merge-box"> |
| 162 | <div class="merge-status"> |
| 163 | <div><strong>Closed with unmerged commits</strong><div class="text-muted">This pull request is closed, but the <span class="branch-label">{{ pr.head_branch }}</span> branch has unmerged commits.</div></div> |
| 164 | {% if can_delete_branch %} |
| 165 | <form method="post" action="{{ base }}/branches/delete" data-confirm="Delete the branch “{{ pr.head_branch }}”? Its commits are not merged."> |
| 166 | <input type="hidden" name="branch" value="{{ pr.head_branch }}"> |
| 167 | <input type="hidden" name="return_to" value="{{ purl }}"> |
| 168 | <input type="hidden" name="pr" value="{{ pr.number }}"> |
| 169 | <button class="btn btn-sm btn-danger" type="submit">Delete branch</button> |
| 170 | </form> |
| 171 | {% endif %} |
| 172 | </div> |
| 173 | </div> |
| 174 | </div> |
| 175 | {% endif %} |
| 176 | |
| 177 | {% if let Some(u) = ctx.user %} |
| 178 | <div class="timeline-comment comment-form-row"> |
| 179 | <div class="timeline-avatar">{{ crate::web::fmt::avatar(u.username, 40)|safe }}</div> |
| 180 | <form class="comment comment-form" method="post" action="{{ purl }}/comment"> |
| 181 | <div class="comment-header"><strong>Add a comment</strong></div> |
| 182 | <div class="comment-form-body"> |
| 183 | <textarea class="input" name="body" rows="5" placeholder="Leave a comment. Markdown is supported."></textarea> |
| 184 | <div class="form-actions form-actions-end"> |
| 185 | {% if pr.state == "open" && can_close %} |
| 186 | <button class="btn" type="submit" name="close" value="1">{{ crate::web::fmt::icon("git-pull-request-closed")|safe }} Close pull request</button> |
| 187 | {% endif %} |
| 188 | <button class="btn btn-primary" type="submit">Comment</button> |
| 189 | </div> |
| 190 | </div> |
| 191 | </form> |
| 192 | </div> |
| 193 | {% if pr.state == "closed" && can_close %} |
| 194 | <form class="reopen-form" method="post" action="{{ purl }}/state"> |
| 195 | <input type="hidden" name="action" value="reopen"> |
| 196 | <button class="btn" type="submit">Reopen pull request</button> |
| 197 | </form> |
| 198 | {% endif %} |
| 199 | {% else %} |
| 200 | <div class="banner"><span><a href="/login?next={{ crate::web::fmt::urlencode(ctx.path) }}">Sign in</a> to join the conversation.</span></div> |
| 201 | {% endif %} |
| 202 | </div> |
| 203 | |
| 204 | <aside class="pull-sidebar"> |
| 205 | <div class="sidebar-item"> |
| 206 | <h3>Branches</h3> |
| 207 | <p><span class="branch-label">{{ pr.base_branch }}</span> ← <span class="branch-label">{{ pr.head_branch }}</span></p> |
| 208 | </div> |
| 209 | <div class="sidebar-item"> |
| 210 | <h3>Changes</h3> |
| 211 | <p>{{ crate::web::fmt::plural(data.commits.len(), "commit") }}, {{ crate::web::fmt::plural(data.files, "file") }}<br> |
| 212 | <span class="text-success">+{{ data.additions }}</span> <span class="text-danger">−{{ data.deletions }}</span></p> |
| 213 | </div> |
| 214 | <div class="sidebar-item"> |
| 215 | <h3>Checkout locally</h3> |
| 216 | <pre class="command command-sm">git fetch origin pull/{{ pr.number }}/head:pr-{{ pr.number }} |
| 217 | git checkout pr-{{ pr.number }}</pre> |
| 218 | </div> |
| 219 | </aside> |
| 220 | </div> |
| 221 | |
| 222 | {% else if pull_tab == "commits" %} |
| 223 | {% if data.commits.is_empty() %} |
| 224 | <div class="blankslate box"><p>No commits to show.</p></div> |
| 225 | {% else %} |
| 226 | <div class="box"> |
| 227 | {% for c in data.commits %} |
| 228 | <div class="box-row commit-row"> |
| 229 | <div class="commit-main"> |
| 230 | <a class="commit-title" href="{{ base }}/commit/{{ c.id }}">{{ c.summary }}</a> |
| 231 | <div class="commit-meta"> |
| 232 | {{ crate::web::fmt::avatar(c.author_name, 18)|safe }} |
| 233 | <strong>{{ c.author_name }}</strong> committed <time title="{{ crate::web::fmt::datetime_full(c.committer_time) }}">{{ crate::web::fmt::ago(c.committer_time) }}</time> |
| 234 | </div> |
| 235 | </div> |
| 236 | <div class="commit-actions"> |
| 237 | <div class="btn-group"> |
| 238 | <a class="btn btn-sm btn-mono" href="{{ base }}/commit/{{ c.id }}">{{ c.short_id }}</a> |
| 239 | <button type="button" class="btn btn-sm" data-copy-text="{{ c.id }}" title="Copy full SHA">{{ crate::web::fmt::icon("copy")|safe }}</button> |
| 240 | </div> |
| 241 | <a class="btn btn-sm btn-ghost" href="{{ base }}/tree/{{ c.id }}" title="Browse the repository at this point">{{ crate::web::fmt::icon("code")|safe }}</a> |
| 242 | </div> |
| 243 | </div> |
| 244 | {% endfor %} |
| 245 | </div> |
| 246 | {% endif %} |
| 247 | |
| 248 | {% else %} |
| 249 | {% if let Some(diff) = data.diff %} |
| 250 | {% let file_ref = pr.head_sha.clone().unwrap_or(crate::web::fmt::urlpath(pr.head_branch)) %} |
| 251 | {% include "partials/diff.html" %} |
| 252 | {% else %} |
| 253 | <div class="blankslate box"><p>The changes for this pull request are no longer available.</p></div> |
| 254 | {% endif %} |
| 255 | {% endif %} |
| 256 | {% endblock %} |