- 投稿日:2019-09-15T22:56:18+09:00
共有フォルダ教が支配する世界に転生した場合の対応案
前書き
この世界ではバージョン管理ソフトが世の中に出回り始めて20年以上、フリーでかつ信頼性も高くなったツールが流行りだして10年以上はたっています。
さすがにソースコードはバージョン管理をするところが多くなりましたが、ドキュメントや、その他重要なデータはいまだバージョン管理をしない世界をよく見かけます。
バージョン管理ツールを縛り共有フォルダでの管理を支持する、いや、もはや信仰している方々は、提案されるバージョン管理ツールの導入案を却下あるいは先延ばしにし続けてきました。
その結果として作業者がフォルダを誤操作で消したり、古いファイルを上書きしたりするという必然の結果(彼らにとっては想定外な結果)に遭遇し、時間とリソースを無駄にドブに捨てるという贅沢をし続けています。今回は、不幸にも、そのような世界に転生してしまった場合に、どうすべきかを考えてみます。
なお、この記事はバージョン管理ソフトの使い方を広めて、みんなで協力して導入していく、模範的な話ではなく、ベストではないが、最悪が回避できたらラッキー程度の話になります。
バージョン管理ツールが流行り、10年以上たって導入できないのは導入できないなりの事情が存在するからです。
なぜバージョン管理ツールは導入されないか
なぜバージョン管理ツールが導入されないかは幾つかのパターンがあります。
- バージョン管理ツールを使用する必要がないあるいは、使用できない
- バージョン管理ツールを知らない
- バージョン管理ツールは知っていても、使える人間が少ない
- 『高度なIT管理』を実現している組織の場合
- コミット履歴を残したくないケース
バージョン管理ツールを使用する必要がないあるいは、使用できない
状況としては2つ考えられます。
1つは管理対象の資源の重要性が低い場合です。
たとえば、一時的なファイルや、消えても大きな影響がない資産の場合です。もう一つはバージョン管理をするのが難しい資産です。
たとえば、動画ファイルとか仮想マシンのイメージとかはファイルのサイズが大きすぎる上、簡単に差分を確認する方法がないため、バージョン管理の対象にむいてません。こういった場合は、バージョン管理ツールを入れる必要はありません。
バージョン管理ツールを知らない
バージョン管理ツール自体を知らない人は少なくなってきてますが、バージョン管理でなにができるかを理解している人はいまだ少数です。
たとえば、昔からの人間の場合、バージョン管理ツールはソースコードや設定ファイルといったテキストしか管理できないと思っている人がいます。このため、ExcelやWordといったOffice文章等は差分の確認もできないし、バージョン管理をする意味がないと思い込んでいます。
これは、ひと昔前は事実でしたが、今現在は、ただの思い込みです。
TotoiseHGやTotoiseSVNなどに付属するDiffツールは標準でOffice文章の差分をとることができますし、WinMergeなどのDiffツールは様々なプラグインがサポートされており画像だろうが差分を見ることが可能になっています。「知らないで導入しない」パターンは、他のパターンに比べて模範的な方向にもっていく可能性が微粒子レベルで存在します。
バージョン管理ツールは知っていても、使える人間が少ない
管理者レベルでバージョン管理ツールのメリットを知っていても、末端の作業者がバージョン管理ツールを使えないなら、結局は導入はできません。
バージョン管理を使えない人間が少数、または教育期間が十二分に取れる場合、練習用のリポジトリを用意してバージョン管理ツールの教育を行うのは有効です。このリポジトリはプロダクトコードと完全に切り離して、最悪、破壊させていい状況にしておいたほうが教育効果が高いです。
…とはいえ、バージョン管理の使い方を学んでこなかった人間を大量に雇用せざる得ない状況は、たいてい学徒動員的な末期戦になっていることが多いので、教育とかいう贅沢は許されない状況である場合が多いでしょう。
『高度なIT管理』を実現している組織の場合
いわゆる『高度なIT管理』を実現している組織の場合、あまりに『高度』すぎてインターネットの接続を遮断したり、サーバー管理を『完全で完璧な高度な専門集団』にしかやらせないという方針の場合があります。
この場合、サーバーを自由に立ててバージョン管理を行うということはできません。
そして『完全で完璧な高度な専門集団』を説得する、あるいは動いていただくために掛ける労力は、しばしば、数度の共有フォルダの破壊のリスクを許容するに値する労力になる場合があります。
コミット履歴を残したくないケース
過剰な管理ごっこをしている世界においては、その防衛反応として事実を隠す反応が発生します。
そういった防衛反応として、表ざたにできないバグをこっそり直したり、試験の不具合件数をいじったりするダークサイドに堕ちた中間管理職が生まれたりします。彼らにとって闇の技法を暴いてしまうバージョン管理システムというのは相性が悪いでしょう。
共有フォルダの破壊にそなえる
すべてを捨てて旅にでるのも一つの選択肢ですが、無駄な足掻きはいくつか考えました。
外部からの支援がほぼない状況で、共有フォルダの致命的な破壊に備える程度の案になります。案1:自分でバックアップを取る
もっとも単純な案は1日に1回、夜中にでも共有フォルダの内容を自分のPCにコピーしておくことです。
この際、フォルダ名にタイムスタンプでもつけておいて、履歴としてつかえばよいでしょう。
Copyと同時に履歴を削除しておけば、バックアップフォルダの増加も抑えられると思います。PowerShellで実現する場合は以下のようになります。
$server = '\\IEWIN7\share\test' $user = 'IEWIN7\IEUser' $password = ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force $backup_root = 'C:\dev\ps\share\bk' # 残す履歴の数 $backup_cnt = 10 if ((Test-Path $server) -eq $True) { Write-Host '接続....' $cred = New-Object System.Management.Automation.PSCredential($user, $password) $drive = New-PSDrive -Name "Z" -PSProvider FileSystem -Root $server -Credential $cred -ea Stop if ((Test-Path $server) -eq $False) { Write-Error "$server に接続できません" exit 1 } } $time = Get-Date -Format "yyyyMMddHHmmss" $backup_path = Join-Path $backup_root $time Write-Host "BACKUP.... $backup_path " Copy-Item -Literal $server -Destination $backup_path -Recurse # 古いフォルダの削除 Get-ChildItem -Literal $backup_root | Sort-Object LastWriteTime -Descending | Select-Object -Skip $backup_cnt | foreach { Write-Host "Delete..." $_.FullName $rmpath = $_.FullName $cmd = "rmdir /s/q `"$rmpath`"" cmd /c $cmd }この案の素晴らしいところは、『高度なIT管理』下でも、やれるということです。
問題点としては、すべてを単純にバックアップするため履歴を追うのは困難ですし、ディスク容量を無駄に消費します。案2:分散型バージョン管理システムを共有フォルダに対して使用する
①と②で共有フォルダ中のファイルを分散バージョン管理システムの管理下に入れます。
③と④で共有フォルダのリポジトリをローカルにクローンすることでバックアップとします。定期的に②のadd&commitと④のpullを実行することに共有フォルダで変更された内容が履歴管理され、その内容はバックアップフォルダに反映されます。
定期的に実行されるaddとcommitは共有フォルダに変化がなければ履歴が作成されません。これにより更新されたファイル内容だけが履歴管理されるようになります。バージョン管理ツールがサポートする変更履歴の確認や、特定バージョンの差し戻しなどが容易に利用できるようになります。
この構成のデメリットは以下の通りです。
- 誰が更新したかわからない
- 共有フォルダ中に管理ファイルが置かれるためサイズが増える。
- これは歴がすすむにつれサイズが増大していく。
- どこかのタイミングで履歴の削除が必要になる
- 共有サーバーのディスクサイズが制限されている環境では使えない
Gitでの実現例
Gitで上記の構成を実現するためのPowerShellのスクリプト例を以下に記載します。
なおバージョンは「git version 2.23.0.windows.1」となります。$server = '\\IEWIN7\share\testgit' $user = 'IEWIN7\IEUser' $password = ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force $backup_root = 'C:\dev\ps\share\gitbk' if ((Test-Path $server) -eq $False) { Write-Host '接続....' $cred = New-Object System.Management.Automation.PSCredential($user, $password) $drive = New-PSDrive -Name "Z" -PSProvider FileSystem -Root $server -Credential $cred if ((Test-Path $server) -eq $False) { Write-Error "$server に接続できません" exit 1 } } Push-Location $server if ((Test-Path '.git') -eq $False) { # Gitフォルダではない Write-Host "Init.........." git init } git add --all git commit -a -m "auto commit" git gc Pop-Location # ローカルにコピー Write-Host "BACKUP... $backup_root" mkdir $backup_root -Force Push-Location $backup_root if ((Test-Path '.git') -eq $False) { # Gitフォルダではない $clone_remote = $server -replace '\\', '/' git clone $clone_remote . } git pull origin master Pop-Location容量の節約と効率化のため、Gitはときどき、緩いフォーマットのオブジェクトの中の幾つかを1つのバイナリファイルにパックします。緩いフォーマットのオブジェクトの場合、ちょっとだけ変更したファイルであってもそれぞれオブジェクトとして存在します。
しかし、パックをすることによりそれらをまとめて変更点だけを保持するようにします。この処理は「git gc」コマンドを実行することで手動でも実現できます。
https://git-scm.com/book/ja/v2/Git%E3%81%AE%E5%86%85%E5%81%B4-Packfileこの処理を行わないと共有サーバーのファイルサイズが更新のたびに想定以上に増大していくことになります。
共有フォルダでGit管理外の名前の変更が発生した場合、AddとCommit時に変更前のオブジェクトと履歴を紐づけることができるようです。
Mercurialの実装例
Gitで上記の構成を実現するためのPowerShellのスクリプト例を以下に記載します。
なおバージョンは「Mercurial - 分散構成管理ツール(バージョン 4.9.1)」となります。$server = '\\IEWIN7\share\testhg' $user = 'IEWIN7\IEUser' $password = ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force $backup_root = 'C:\dev\ps\share\hgbk' if ((Test-Path $server) -eq $False) { Write-Host '接続....' $cred = New-Object System.Management.Automation.PSCredential($user, $password) $drive = New-PSDrive -Name "Z" -PSProvider FileSystem -Root $server -Credential $cred if ((Test-Path $server) -eq $False) { Write-Error "$server に接続できません" exit 1 } } Push-Location $server if ((Test-Path '.hg') -eq $False) { # HGフォルダではない Write-Host "Init.........." hg init } hg add hg commit -A -m "auto commit" Pop-Location # ローカルにコピー Write-Host "BACKUP... $backup_root" mkdir $backup_root -Force Push-Location $backup_root if ((Test-Path '.hg') -eq $False) { # HGフォルダではない $clone_remote = $server -replace '\\', '/' hg clone $clone_remote . } hg pull default hg update Pop-LocationGitと違い、MercurialはGCの必要がありません。
共有フォルダでMercurial管理外の名前の変更が発生した場合、Gitとことなり変更前のオブジェクトと履歴を紐づけはできないようです。容量増加の検証
どちらのバージョン管理ツールを使用しても共有フォルダ内に履歴の管理情報を保持する必要があります。
ここで発生する懸念としては、共有フォルダのサイズがどの程度増量するかです。今回は以下の条件で検証しました。
(1)下記のスクリプトを用いて任意のフォルダに1000行x251列のエクセルファイル(1MB前後)を100個作成する。
Param( [String]$target_dir, [Int]$count, [Int]$rowcnt, [Int]$colcnt ) function create_xls($app, [String]$path, [String[]]$ary, $rowcnt) { Write-Host $path $books = $app.Workbooks $book = $books.Add() $sheets = $book.Sheets $sheet = $sheets["Sheet1"] $cells = $sheet.Cells $fromCell = $cells[1,1] $toCell = $cells[$rowcnt,$ary.Length] $rng = $sheet.Range($fromCell, $toCell) $rng.Value = $ary [System.Runtime.Interopservices.Marshal]::ReleaseComObject($fromCell) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($toCell) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($rng) | Out-Null $book.SaveAs($path) $book.Close() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($cells) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheets) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($books) | Out-Null $cell = $null Remove-Variable cell -ErrorAction SilentlyContinue $cells = $null Remove-Variable cells -ErrorAction SilentlyContinue $sheet = $null Remove-Variable sheet -ErrorAction SilentlyContinue $sheets = $null Remove-Variable sheets -ErrorAction SilentlyContinue $book = $null Remove-Variable book -ErrorAction SilentlyContinue $books = $null Remove-Variable books -ErrorAction SilentlyContinue [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() [System.GC]::Collect() } $app = New-Object -ComObject Excel.Application $app.DisplayAlerts = $False for ($i = 0; $i -lt $count; $i++) { $name = "test" + $i + ".xlsx" $path = Join-Path $target_dir $name $t = Get-Date -Format "yyyyMMddHHmmss" $ary = @($t) for ($j = 0; $j -lt $colcnt; $j++) { $ary += Get-Random 10000 } create_xls $app $path $ary $rowcnt } $app.Quit(); [System.Runtime.Interopservices.Marshal]::ReleaseComObject($app) | Out-Null $app = $null Remove-Variable app -ErrorAction SilentlyContinue [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() [System.GC]::Collect()(2)下記のスクリプトを用いて1列目の全行を全て変更して保存します。
Param( [String]$target_dir, [Int]$count, [Int]$rowcnt ) function update_xls($app, [String]$path, [String]$time, $rowcnt) { Write-Host $path $books = $app.Workbooks $book = $books.Open($path) $sheets = $book.Sheets $sheet = $sheets["Sheet1"] $cells = $sheet.Cells $fromCell = $cells[1,1] $toCell = $cells[$rowcnt,1] $rng = $sheet.Range($fromCell, $toCell) $rng.Value = $time [System.Runtime.Interopservices.Marshal]::ReleaseComObject($fromCell) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($toCell) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($rng) | Out-Null $book.SaveAs($path) $book.Close() [System.Runtime.Interopservices.Marshal]::ReleaseComObject($cells) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheet) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($sheets) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($book) | Out-Null [System.Runtime.Interopservices.Marshal]::ReleaseComObject($books) | Out-Null $cell = $null Remove-Variable cell -ErrorAction SilentlyContinue $cells = $null Remove-Variable cells -ErrorAction SilentlyContinue $sheet = $null Remove-Variable sheet -ErrorAction SilentlyContinue $sheets = $null Remove-Variable sheets -ErrorAction SilentlyContinue $book = $null Remove-Variable book -ErrorAction SilentlyContinue $books = $null Remove-Variable books -ErrorAction SilentlyContinue [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() [System.GC]::Collect() } $app = New-Object -ComObject Excel.Application $app.DisplayAlerts = $False for ($i = 0; $i -lt $count; $i++) { $name = "test" + $i + ".xlsx" $path = Join-Path $target_dir $name $time = Get-Date -Format "yyyyMMddHHmmss" update_xls $app $path $time $rowcnt } $app.Quit(); [System.Runtime.Interopservices.Marshal]::ReleaseComObject($app) | Out-Null $app = $null Remove-Variable app -ErrorAction SilentlyContinue [System.GC]::Collect() [System.GC]::WaitForPendingFinalizers() [System.GC]::Collect()(3)(2)の実行後、コミットし、コミット後のフォルダのサイズを調べます。これを10回繰り返します
Gitの場合
$src_dir = "C:\dev\ps\share\kensyou\test_dir" $target_dir = "C:\dev\ps\share\kensyou\git" $script_dir = Split-Path $MyInvocation.MyCommand.Path function gettime() { return Get-Date -Format "yyyyMMddHHmmss" } mkdir $target_dir -force | Out-Null Copy-Item $($src_dir+"\*") $target_dir push-location $target_dir $time = gettime Write-Host "$time 構成管理前" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum git init | Out-Null $time = gettime Write-Host "$time init後" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum for ($i = 1; $i -le 10; $i++) { if ($i -ne 1) { $script = Join-Path $script_dir "update_data.ps1" powershell -file $script $target_dir 100 1000 250 | Out-Null } git add --all | Out-Null git commit -a -m "auto commit" | Out-Null $time = gettime Write-Host "$time $i 回目(commit後)" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum git gc | Out-Null $time = gettime Write-Host "$time $i 回目(gc後)" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum } pop-locationMercurialの場合
$src_dir = "C:\dev\ps\share\kensyou\test_dir" $target_dir = "C:\dev\ps\share\kensyou\hg" $script_dir = Split-Path $MyInvocation.MyCommand.Path function gettime() { return Get-Date -Format "yyyyMMddHHmmss" } mkdir $target_dir -force | Out-Null Copy-Item $($src_dir+"\*") $target_dir push-location $target_dir $time = gettime Write-Host "$time 構成管理前" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum hg init | Out-Null $time = gettime Write-Host "$time init後" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum for ($i = 1; $i -le 10; $i++) { if ($i -ne 1) { $script = Join-Path $script_dir "update_data.ps1" powershell -file $script $target_dir 100 1000 250 | Out-Null } hg add | Out-Null hg commit -A -m "auto commit" | Out-Null $time = gettime Write-Host "$time $i 回目" (Get-ChildItem -LiteralPath $target_dir -Recurse -Force | Measure-Object -Sum Length).Sum } pop-location計測結果
Gitの結果
時刻 経過時間 説明 バイト数 変化バイト数 12:40:42 構成管理前 108,224,999 12:40:42 0:00:00 init後 108,240,786 15,787 12:40:46 0:00:04 1回目(commit後) 167,167,147 58,926,361 12:41:03 0:00:17 1回目(gc後) 160,253,884 -6,913,263 12:42:38 0:01:35 2回目(commit後) 223,790,889 63,537,005 12:43:00 0:00:22 2回目(gc後) 217,598,218 -6,192,671 12:44:38 0:01:38 3回目(commit後) 279,699,191 62,100,973 12:45:13 0:00:35 3回目(gc後) 272,927,795 -6,771,396 12:46:55 0:01:42 4回目(commit後) 335,808,640 62,880,845 12:47:22 0:00:27 4回目(gc後) 329,101,286 -6,707,354 12:49:06 0:01:44 5回目(commit後) 391,427,905 62,326,619 12:49:44 0:00:38 5回目(gc後) 384,702,914 -6,724,991 12:51:50 0:02:06 6回目(commit後) 447,154,138 62,451,224 12:52:57 0:01:07 6回目(gc後) 440,272,643 -6,881,495 12:54:51 0:01:54 7回目(commit後) 502,722,692 62,450,049 12:55:25 0:00:34 7回目(gc後) 495,815,728 -6,906,964 12:57:07 0:01:42 8回目(commit後) 558,031,925 62,216,197 12:57:42 0:00:35 8回目(gc後) 551,140,571 -6,891,354 12:59:24 0:01:42 9回目(commit後) 613,900,051 62,759,480 13:00:01 0:00:37 9回目(gc後) 607,291,311 -6,608,740 13:01:35 0:01:34 10回目(commit後) 669,533,780 62,242,469 13:02:13 0:00:38 10回目(gc後) 662,895,263 -6,638,517 Mercurialの結果
時刻 経過時間 説明 バイト数 変化バイト数 13:06:28 構成管理前 108,224,999 13:06:30 0:00:02 init後 108,225,115 116 13:06:40 0:00:10 1回目 160,990,957 52,765,842 13:08:27 0:01:47 2回目 217,741,339 56,750,382 13:10:11 0:01:44 3回目 274,194,265 56,452,926 13:12:06 0:01:55 4回目 330,463,591 56,269,326 13:14:03 0:01:57 5回目 386,622,952 56,159,361 13:16:20 0:02:17 6回目 442,364,652 55,741,700 13:18:28 0:02:08 7回目 498,348,170 55,983,518 13:20:14 0:01:46 8回目 554,076,263 55,728,093 13:22:02 0:01:48 9回目 609,921,087 55,844,824 13:24:05 0:02:03 10回目 666,193,613 56,272,526 ファイルのサイズとしては「GC後のGitのサイズ<Mercurialサイズ<GC前のGitのサイズ」となります。
10回程度のコミットで6倍のサイズになっています。ファイルの更新~コミット&GCの時間はGitとMercurialに大きな差はないように見えます。
※時間の注意としては、100ファイルに対して列を書き換える時間も含まれていることに注意してください。どう実行すべきか
add & commitのタイミングはとりあえず1日単位でおこなって共有フォルダのサイズの増加量を監視して調整したほうがよさそうです。
また、更新頻度にもよりますが、バージョン管理の情報が肥大化することが予想されます。
そのため、どのタイミングで履歴を捨てるかを検討した方がいいです。
(たとえばリリースが行われた時点で開発中の履歴を捨てる等)案3 ローカルにコピーしたバックアップフォルダに対して分散バージョン管理を使用する
案1のやりかたでローカルに共有フォルダの内容を定期的にコピーします。
ただし、フォルダ毎にわけるのでなく、上書き保存として、保存後、コミットをします。このメリットは共有フォルダのサイズの肥大化を防げることです。
デメリットとしては、その履歴の活用が個人でしか行えないことです。参考
Powershellで共有フォルダにアクセス
https://qiita.com/mugippoi/items/608255dee3fc9d3b35dcまとめ
今回は共有フォルダ教が支配する世界に転生した場合の対応案を考えてみました。
おそらくは最悪の状況を回避するという手としては使えないこともないでしょうが、転生しなおした方が楽だと思います。
(補足)
なお、まじめにまっとうなバージョン管理の導入を考えるなら以下で紹介している「パターンによるソフトウェア構成管理」を基に現場にあった論を組み立てた方がいいと思います。古典を読む~パターンによるソフトウェア構成管理
https://qiita.com/mima_ita/items/3213998ef17216e8c775
- 投稿日:2019-09-15T20:50:41+09:00
rebaseでcommitが消えた…?
内容
commit
がrebase
されず、想定の結果にならなかったので、事象や解決策などをまとめました。
rebase
の挙動についてはこの記事が参考になります。やりたかったこと
master
にfeature/A
をrebase
したかった。git rebase master feature/A実行結果
あれ…
feature/A
のcommit
がrebase
されていない…Before
* commit 414b95af83ab984b20147e0094ed8eade31f348b (origin/master, master) | Author: **** | Date: Sat Sep 14 22:02:50 2019 +0900 | | D | | * commit 12b5e389f870e565beb195e6b9deda974daacac0 (HEAD -> feature/A, origin/feature/A) | | Author: **** | | Date: Sat Sep 14 21:43:10 2019 +0900 | | | | C | | | * commit 53af224f9c0f1c326dbdd20efc85edd04fe84e36 | | Author: **** | | Date: Sat Sep 14 19:37:50 2019 +0900 | | | | B | | | * commit 650053d9adbaa1b33a3a6b72504cbcad9ff23eb9 |/ Author: **** | Date: Sat Sep 14 19:37:35 2019 +0900 | | A | * commit 78369ea68187c501d4b3fa7b453a9ce3eea95ca1 Author: **** Date: Sat Sep 14 19:35:28 2019 +0900 first commitAfter
* commit 414b95af83ab984b20147e0094ed8eade31f348b (HEAD -> feature/A, origin/master, master) | Author: **** | Date: Sat Sep 14 22:02:50 2019 +0900 | | D | | * commit 12b5e389f870e565beb195e6b9deda974daacac0 (origin/feature/A) | | Author: **** | | Date: Sat Sep 14 21:43:10 2019 +0900 | | | | C | | | * commit 53af224f9c0f1c326dbdd20efc85edd04fe84e36 | | Author: **** | | Date: Sat Sep 14 19:37:50 2019 +0900 | | | | B | | | * commit 650053d9adbaa1b33a3a6b72504cbcad9ff23eb9 |/ Author: **** | Date: Sat Sep 14 19:37:35 2019 +0900 | | A | * commit 78369ea68187c501d4b3fa7b453a9ce3eea95ca1 Author: **** Date: Sat Sep 14 19:35:28 2019 +0900 first commit問題点
実は
feature/A
のcommit
は全て空コミットでした、
デフォルトだと空コミットはrebase
の際に削除されてしまう。解決策
rebase
時に--keep-empty
オプションを指定する。git rebase --keep-empty master feature/A実行結果
想定通りの結果になりました!
After
* commit 1bb327740bf6cb6e25e0afb6500ed9c1020503c0 (HEAD -> feature/A) | Author: **** | Date: Sat Sep 14 21:43:10 2019 +0900 | | C | * commit 5bb9c9e4e943deccbb5e7ddeb4ac07caf158aeb9 | Author: **** | Date: Sat Sep 14 19:37:50 2019 +0900 | | B | * commit ad32378d763b315b419a86f4303f61f147886c11 | Author: **** | Date: Sat Sep 14 19:37:35 2019 +0900 | | A | * commit 414b95af83ab984b20147e0094ed8eade31f348b (origin/master, master) | Author: **** | Date: Sat Sep 14 22:02:50 2019 +0900 | | D | | * commit 12b5e389f870e565beb195e6b9deda974daacac0 (origin/feature/A) | | Author: **** | | Date: Sat Sep 14 21:43:10 2019 +0900 | | | | C | | | * commit 53af224f9c0f1c326dbdd20efc85edd04fe84e36 | | Author: **** | | Date: Sat Sep 14 19:37:50 2019 +0900 | | | | B | | | * commit 650053d9adbaa1b33a3a6b72504cbcad9ff23eb9 |/ Author: **** | Date: Sat Sep 14 19:37:35 2019 +0900 | | A | * commit 78369ea68187c501d4b3fa7b453a9ce3eea95ca1 Author: **** Date: Sat Sep 14 19:35:28 2019 +0900 first commit深掘り
rebase
は、
- 移行元の
commit
を一時退避する。- 移行先のブランチに移動する。
- 移行先に1.で一時退避した
commit
を適用という動きをするようです。
rebase
のデフォルトの動きは、3.でファイル差分が存在しない時はcommit
しない挙動のようです。追加で気になったこと
cherry-pick
で空コミットを適用しようとした時はどうなるのか。やってみたこと
cherry-pick
で空コミットを取り込んでみました。git cherry-pick 414b95af83ab984b20147e0094ed8eade31f348b実行結果
「
commit
できるものがないよ〜。
とにかくcommit
したかったら空コミットしてね。
それがイヤだったらreset
してね」
と言っているようです。On branch feature/A You are currently cherry-picking commit 414b95a. nothing to commit, working tree clean The previous cherry-pick is now empty, possibly due to conflict resolution. If you wish to commit it anyway, use: git commit --allow-empty Otherwise, please use 'git reset'解決策
cherry-pick
に--allow-emptybgit
オプションを指定しましょう。git cherry-pick --allow-emptybgit 414b95af83ab984b20147e0094ed8eade31f348bまとめ
rebase
時に--keep-empty
オプションを指定しないと空コミットがrebaseされない。cherry-pick
時に--allow-emptybgit
オプションを指定しないと手動で別作業が必要になる。今回の事象がgithubのプルリクで問題になるケースの記事を見つけたので参考にしてください。
参考記事
- 投稿日:2019-09-15T06:57:39+09:00
初心者用Github環境構築
初心者用Github環境構築
1.砂場(リモート)にため池(リポジトリ)を作ろう!
※リポジトリ(リモートの保存場所)を作成しない場合はスキップする。
※実際の砂場にため池を作る行為は器物破損に問われる場合があります。1ー1.https://github.com にアクセスする。
1ー2.右上の『+』、『New repository』
1ー3.リポジトリ情報を入力し、『Create Repository』
Owner ... リポジトリの所有者
Repository Name ... リポジトリ名
Discription ... 説明
Public/Private ... 公開(Plublic)か、非公開(Private)か。公開にする場合も招待を受けた人しか編集できない。
Add .ignore ... ファイル管理除外設定ファイルの言語。その言語で管理しないファイルの既定を定義する。(Swift言語にしました)
1ー4.ため池(リポジトリ)完成
砂場(リモート)にため池(リポジトリ)ができました!
2.砂場(リモート)のため池(リポジトリ)に編集者を招待しよう!
※リポジトリ(リモートの保存場所)を管理しない場合はスキップする。
2ー1.『Collaborators』、『Settings』
2ー2.招待するGitアカウント名を入力し、『Add collaborator』
(所有者は招待不要)
3.所有者と編集者の身元を保証しよう!
※これによりパスワード入力を回避できる。
3ー1.身元保証するアカウントでGithubにログインする。
3ー2.右上の『+』、『Settings』、『SSH and GPG keys』
3ー3.『New SSH Key』
3ー4.SSH秘密鍵と公開鍵を作成する。
ssh-keygenmkdir ~/.ssh cd ~/.ssh ssh-keygen #[Enter] #[Enter] #[Enter] cat id_rsa.pub3ー3.SSH公開キー(id_rsa.pub)を設定する。『Add SSH Key』
4.リポジトリのURLを確認する。
4ー1.『Use SSH』、コピーアイコン
- 投稿日:2019-09-15T00:20:30+09:00
Herokuにデプロイをする時に詰まった箇所について
はじめに
RailsアプリケーションをHerokuにデプロイする際、自分が詰まった箇所について説明します。
また、herokuへのデプロイ方法は、最終行に記載した<4.デプロイ手順の参考記事>を参考にデプロイをしました。それぞれのバージョンは以下の通りです。
MacOS 10.14.5
Ruby 2.5.1p57
Rails 5.2.3
heroku/7.26.2 darwin-x64 node-v11.14.0画像
https://gyazo.com/847aa4661ae3b2f278ae2328d33d32dd1.Herokuにログインする時
①現象
以下のように、herokuにログインするコマンドを実行しても、
$heroku loginメールアドレスおよびパスワードを入力する画面いならない(おそらく、このような方法でログインすることもできるのだろう)。
動画(見えづらくて申し訳ありません(>人<;))
https://gyazo.com/e3873154a60890c7fa5aab07146c962c②解決方法
以下のようなコマンドを入力すれば、解決できます。
$ heroku login --interactive動画
https://gyazo.com/4829936b6a6626a7ea229383eecbeae9③参考記事
https://teratail.com/questions/158638
2.Railsの設定
(1).Gemfileの設定
本番環境用にGemfileの設定しておかないと、以下のようなエラーが発生します。
(今回は、自分がアプリで使用したdeviseおよびjquery-railsの2つのgemを例にあげます。)①エラー現象
以下のような画面が表示され、デプロイが失敗する。
deviseの場合、
remote: Caused by: remote: NameError: uninitialized constant Devise画像
https://gyazo.com/eb6608754ad0937c550eb45acdf848b5jquery-railsの場合、
remote: rake aborted! remote: Sprockets::FileNotFound: couldn't find file 'jquery' with type 'application/javascript'画像
https://gyazo.com/71cc267fe306d82fdf6e65df2b2288a1②解決方法
Gemfileの一番下に、以下のような設定をすると解決します(deviseおよびjquery-rails)。
group :development, :production, :test do gem 'devise' gem 'jquery-rails' end画像
https://gyazo.com/625adb044cecaff749c60f4f77fb317a(2).テンプレートリテラル記法を用いる場合のproduction.rbの設定
①エラー現象
以下のようなエラー画面が表示され、デプロイが失敗する。
remote: rake aborted! remote: Uglifier::Error: Unexpected character '`'下の方に赤文字で以下のような表示がされる。
remote: ! Precompiling assets failed.全体の画像
https://gyazo.com/37b8b091eda6cec2c0514b54dea5a5c5②解決方法
config/environments/production.rbにある以下のコードをコメントアウトする。
# config.assets.js_compressor = :uglifier自分の場合、production.rbの26行目に書いてありました。
https://gyazo.com/b66d6c1a13d7b22a5105f88e1303f40dそもそも、テンプレートリテラル記法とは?
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/template_strings3.デプロイ成功後
(1).デプロイは成功後にアクセスするURLについて
①現象
herokuへのデプロイが成功すると、以下のような長いログの画面が表示される
https://gyazo.com/2d2e4ea40e66373aa6b62cb7df7f15cc
(画面が青い理由は、どこからどこまでがデプロイのログなのかを、自分で判断するためです。見えづらくて申し訳ありません(>人<;))。そして、以下のような画面が表示される。
$ git push heroku master ・ ・ ・ remote: -----> Compressing... remote: Done: 36.9M remote: -----> Launching... remote: Released v6 remote: https://enigmatic-reaches-21915.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/enigmatic-reaches-21915.git * [new branch] master -> masterそして、同時にherokuへのURLが生成されます。
remote: Released v6 remote: https://enigmatic-reaches-21915.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/enigmatic-reaches-21915.git * [new branch] master -> master②解決方法
アクセスできるURLは以下のような表示がされている方にアクセスすると解決します。
remote: https://<個別のアプリの名前>.herokuapp.com/ deployed to Heroku※自分は、今回デプロイするときのアプリの名前を指定してなかったので、
enigmatic-reaches-21915という名前になっています。
③参考記事
https://qiita.com/kodai_0122/items/a1f01b18bb3e0ddde62a
(2).デプロイは成功し、正しいURLにアクセスしたが、エラー画面が表示される問題
①エラー現象
正しいURLにアクセスした時、以下のようなエラー画面が表示される。
"We're sorry, but something went wrong."画像
https://gyazo.com/3a6a0c733d87efe0866c2e3f8d585a0f②解決方法
デプロイをした後に、本番環境においてマイグレーションを行えば、解決できます。
③参考記事
https://i.gyazo.com/3a6a0c733d87efe0866c2e3f8d585a0f.png
https://qiita.com/KazuhoE/items/06d13ccd4c72fd31c5d9
https://teratail.com/questions/1241834.デプロイ手順の参考記事
・https://qiita.com/NaokiIshimura/items/eee473675d624a17310f
・https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39
・https://sweets-engineer.com/heroku/#heroku
・https://qiita.com/fuwamaki/items/f7752eb7a2727660239f