タイトル何言ってるかわかりませんか、そーですか。
運用作業なんかの記録をRedmineで管理してて、作業に伴ってできるファイルなんかはgitで管理したりしてます。
んで、チケット毎にブランチをきったりフォルダを作ったりするんですが、
名前規則を、_日付チケット番号内容_みたいにしてます。
いちいち手打ちだと面倒なんで、チケット画面からコピペでコマンド打てると楽だなってことです。
わかりませんね。
画面はこんな感じ。

下準備
管理者権限が必要です。
プラグイン
必要なプラグインは
API有効化
REST APIを有効にしておきます。
表示のカスタマイズ
[管理]→[表示のカスタマイズ]で、View Customize pluginの設定画面を開きます。
[新しい表示のカスタマイズ]で、カスタマイズを作成します。
パスのパターン: /issues/[0-9]+
挿入位置: チケット詳細の下
種別: JavaScript
コードは
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Path patern: /issues/[0-9]+ */ | |
$(function () { | |
getYYYYMMDD = function getYYYYMMDD(dt) { | |
var y = ("0000" + dt.getFullYear()).slice(-4); | |
var m = ("00" + (dt.getMonth() + 1)).slice(-2); | |
var d = ("00" + dt.getDate()).slice(-2); | |
var result = y + m + d; | |
return result; | |
} | |
var illegalRe = /[\/\?<>\\:\*\|":]/g; | |
var illegalGitRe = /[\[\]]/g; | |
var controlRe = /[\x00-\x1f\x80-\x9f]/g; | |
var reservedRe = /^\.+$/; | |
// var windowsReservedRe = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i; | |
var windowsTrailingRe = /[\. ]+$/; | |
sanitize = function (input, replacement) { | |
var sanitized = input | |
.replace(illegalRe, replacement) | |
.replace(illegalGitRe, replacement) | |
.replace(controlRe, replacement) | |
.replace(reservedRe, replacement) | |
//.replace(windowsReservedRe, replacement) | |
.replace(windowsTrailingRe, replacement) | |
.trim() | |
.replace(/_+/g, '_'); | |
return sanitized; | |
} | |
$.ajax({ | |
type: 'GET', | |
url: '/issues/' + ViewCustomize.context.issue.id + '.json', | |
headers: { | |
'X-Redmine-API-Key': ViewCustomize.context.user.apiKey | |
}, | |
}).done(function (data) { | |
$.ajax({ | |
type: 'GET', | |
url: '/projects/' + data.issue.project.id + '.json', | |
headers: { | |
'X-Redmine-API-Key': ViewCustomize.context.user.apiKey | |
}, | |
context: data | |
}).done(function (data) { | |
var subj = sanitize(this.issue.subject, '_').replace(/\s/g, '_'); | |
var ops = "%OPS%\\" + this.issue.project.name.replace(/\s/g, ''); | |
var folder = data.project.description.match(/#opsfolder\s*=\s*(.+)/); | |
if (folder) { | |
if (folder.length >= 2) { | |
ops = "%OPS%\\" + folder[1]; | |
} | |
} | |
var str = ops + "\\" + getYYYYMMDD(new Date(this.issue.created_on)) + "_" + this.issue.id + "_" + subj; | |
var git = this.issue.tracker.name + "/#" + this.issue.id + "/" + subj; | |
var commands = [ | |
'cd "' + ops + '"', | |
'git status', | |
'git checkout -b "' + git + '"', | |
'mkdir "' + str + '"', | |
'git add .', | |
'git commit -am "resolved #' + this.issue.id + '"', | |
'git checkout master', | |
'git merge --no-ff "' + git + '"', | |
'git push origin master', | |
]; | |
var html = ""; | |
for (var cmd of commands) { | |
html += '<span>' + cmd + '</span><span class="cmd icon icon-copy"></span><br/>'; | |
} | |
$('.attributes').append('<div class="wiki"><pre>' + html + '</pre></div>'); | |
$('span.cmd').on('click', function (event) { | |
//$(this).prev().select(); | |
//document.getSelection().selectAllChildren($(this).prev()); | |
document.getSelection().selectAllChildren(this.previousElementSibling); | |
document.execCommand('copy'); | |
}); | |
}); | |
}) | |
}) |
こんな感じ。
commands周辺をお好みで変更します。
REST callを2段階でやってるので、コマンド表示まで若干のタイムラグがあったりなかったりします。