20211014のGitに関する記事は8件です。

「git revert」の「git revert」がしたい!

git revertはコミットの取り消しを行うコマンドです。 表題の通り、取り消しの取り消しを行う必要があったのでまた発生したときに焦らない用メモです。 なぜする必要があったか プルリク発行⇒topicブランチにマージされた後、やっぱりおかしいのでは?とrevertされる レビュアと話し合った結果、revertされた実装で合ってたという結論に至る 「ごめんね、元の実装でプルリク出し直しておいて」と言われ、元のブランチから再度プルリクを出そうとしたが... 変更あるって!と思いましたが、よく考えたら以下の図のようなことで取り込み済と判断されるのは当たり前でした。 commitID:abc123の作業はtopicブランチにマージ済なので「もう取り込んでるけど?」と言われていたのでした。 こうなったら取り消しの取り消しを行うしかない...。 実際の手順 topicブランチをpullして新しいブランチを作成し、revertコミットをrevertしました。 > git pull // 1.revertされた状態のtopicブランチに合わせる > git checkout -b revert-revert // 2.新しいブランチを作成する > git log // 3.revertのコミットIDを特定する commit 456def.......... (origin/revert) // revertのコミットID Author: レビュア Date: Thu Oct 14 05:16:11 2021 +0000 Revert "イケてる実装 (pull request #001)" commit 123abc.......... Author: shun.kondo Date: Thu Oct 14 05:14:41 2021 +0000 イケてる実装 > git revert 456def // 4.revertのコミットIDを指定してrevert(取り消しの取り消し) [<作業ブランチ名> <新しいコミットID>] Revert "Revert "イケてる実装 (pull request #001)"" 1 file changed, 1 deletion(-) > git push --set-upstream origin revert-revert // 5.再度push! 無事に取り消しの取り消しを行い、元の実装の通りマージすることができました 他の方法もあるのか一応調べた git resetでコミットのログごと消して-fオプションを付けて強制的にpushしてコミットログを綺麗にする...なんて方法もあるようです。 確かに「revert」「revertのrevert」とコミットログが並んでいるのはかっこよくはないですが、git resetはコミット自体がなかったことになるのでコンフリクトが起きやすいなどの弱点もあるようです。 なんにせよ作業の手順がそのまま残るのは悪いことではないと思うので、チーム開発ではgit revertを使用しておいた方が良い気がします。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitの初期設定でブランチ名をmasterからmainに変更できないときの原因と解決方法

エラー内容 git initの実行後、git branch -M mainを実行すると、以下のようなエラーが出る。 % git branch -M main error: refname refs/heads/master not found fatal: Branch rename failed 解決方法 README.mdファイルを新規作成し、git add実行後にgit commitを実行するとエラーは解消され、mainブランチを作成することができる。 % touch README.md % git add README.md % git commit -m "initial commit" % git branch -M main 上記コマンドを実行後にgit branchコマンドでブランチ一覧を確認し、mainブランチが作成されていれば成功です! % git branch * main エラーの原因 ブランチはコミットへのポインタであるため、コミットが未作成の場合ブランチは存在しません。そのため、存在しないブランチの名前を変更することはできません。 なので、最初のコミットを行うことでブランチが作成され(デフォルトではmaster)、それから(ブランチが存在するので)名前を変更できるようになります。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Git】過去のコミット位置に戻ってブランチを切る

今の状態も消したくはないけど、過去のコミット位置に戻りたいなと思った時の小技を知ったのでメモメモ。 過去のコードに戻すにはresetしないといけないのかなと思ったけど、今編集しているブランチはそのままに、過去の特定のコミット位置から新しくブランチを切る方法があるらしい。 手順 1. 戻りたいコミットのハッシュ値を調べる $ git logコマンドで、このコミット位置に戻りたい!というコミットのハッシュ値を調べておく。 2. 新しいブランチを作成する 以下のコマンドで、指定したコミット位置から新しいブランチを切ることができる。 $ git checkout -b [新しいブランチ名] [コミットのハッシュ値] 頻繁に使うものではないと思うけれど、覚えておけばresetせずに済んで助かることもあるかなと思いました(^○^) 参考記事
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitには無いpre-checkoutフックの実験的実装

Gitへの要求はどこまでも続きそうです。 すみません、Gitのmasterリポジトリをいじる記事ではありません。  Gitの外側から制御して、新規のフック処理を実装するものです。  Gitフックはリモートリポジトリ方向へは手厚いですが、ローカルワークツリー方向へはニーズが無いのか、さっぱりです。  今回は、クライアントサイドフックのcheckout処理前を実装しようと思います。贅沢を言えばきりがないので、checkoutコマンドの一部だけ対応します。 git checkout -- <ファイル> で、過去のコミット分にファイル単位で戻す。 環境 Windows10 64bit home 21H1 VisualStudio 2019 Community 16.11.4 C# .NET 4.8 Git for Windows 2.33.0.2-64-bit TortoiseGit 2.12.0.0-64bit どんな感じでフックを作るのか。 ①binフォルダをbin2フォルダにコピー ②binフォルダに今回作るGit.exeを配置(上書きで) ③リポジトリの.git/hooksフォルダにフックスクリプトを配置 Git.exeを使う人は、bin2フォルダは知らないから、binフォルダのGit.exeを呼び出すことになる。そこでコマンド解析し、pre-checkoutフックを呼び出すこととする。 実際の仕事は、bin2フォルダのオリジナルのGit.exeにお願いする。 おまけで、ログファイルも作ってみる。 ラッパー的な実装ということになります。 今回作るもの .NETのコンソールアプリケーションを作ります。  実は、TortoiseGitを推してまして、TortoiseGitの『このリビジョンに戻す(E)』を選択されたときのフックが欲しくて、こんなことになっています。  Git.exeの処理結果は標準出力で受け取ることができます。なので、子プロセスとしてオリジナルのGit.exeを呼び出し、その標準出力をそのまま今回作るGit.exeの標準出力とする。そうすると、Git.exeを呼び出した人は、変なツールを実行しているとも気が付かずに、Gitを正しく操作できてしまいます。 Git.exe(ログファイル出力対応版)を作る できました。 コンソールアプリケーション(.NET Framework)で.NET4.8のプロジェクトを作りました。プロジェクト名は『git』で。 Program.cs using System; using System.IO; using System.Text; namespace git { class Program { //リポジトリフォルダ const string REPOSROOT = @"C:\WORK\test\"; //Gitコマンドログファイル const string LOGFILEPATH = REPOSROOT + @".git\hooks\git.log"; //オリジナルGitコマンドEXE const string GITCMD = @"C:\Program Files\Git\bin2\git.exe"; static void Main(string[] args) { string parm = ""; System.Diagnostics.Process p = null; string results = ""; //コマンドラインパラメータ連結 parm = string.Join(" ", args); //ログファイル出力 File.AppendAllText(LOGFILEPATH, $"{DateTime.Now} : git {parm}\n"); //オリジナルGitコマンド実行 p = new System.Diagnostics.Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardInput = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.WorkingDirectory = REPOSROOT; p.StartInfo.FileName = GITCMD; p.StartInfo.Arguments = parm; //UTF8を使っている。 p.StartInfo.StandardOutputEncoding = Encoding.UTF8; p.Start(); results = p.StandardOutput.ReadToEnd(); p.WaitForExit(); p.Close(); //オリジナルGitコマンドの標準出力を、そのまま自分の標準出力とする。 //バイナリを使わないと一部文字化けが発生する。 //『あいうえお.bat』等 byte[] wkBuff = System.Text.Encoding.UTF8.GetBytes(results); Stream stdout = Console.OpenStandardOutput(); stdout.Write(wkBuff, 0, wkBuff.Length); stdout.Close(); } } }  リポジトリのパス等を固定で持っていますが、configファイルにでも設定するように修正すれば汎用性は上がります。  まずは、このコマンドログファイル出力のみのバージョンで、お目当てのコマンドが取れているか確認が大事です。 動かしてみる TortoiseGitで、過去のコミット分のファイルの右クリックで、『このリビジョンに戻す』を選択します。 きちんと、『aaa.bat』のcheckoutが取れていますね。 Git.exe(pre-checkoutフック対応版)を作る Program.cs using System; using System.IO; using System.Text; namespace git { class Program { //リポジトリフォルダ const string REPOSROOT = @"C:\WORK\test\"; //Gitコマンドログファイル const string LOGFILEPATH = REPOSROOT + @".git\hooks\git.log"; //オリジナルGitコマンドEXE const string GITCMD = @"C:\Program Files\Git\bin2\git.exe"; //Bashコマンド const string BASHCMD = @"C:\Program Files\Git\bin\bash.exe"; //フックスクリプト const string HOOKSH = @".git\hooks\pre-checkout"; static void Main(string[] args) { string parm = ""; System.Diagnostics.Process p = null; string results = ""; //コマンドラインパラメータ連結 parm = string.Join(" ", args); //ログファイル出力 File.AppendAllText(LOGFILEPATH, $"{DateTime.Now} : git {parm}\n"); //pre-checkoutフック if(args[0] == "checkout" && args[2] == "--") { //ログファイル出力 File.AppendAllText(LOGFILEPATH, $"{DateTime.Now} : pre-checkout\n"); //スクリプト実行コマンド実行 p = new System.Diagnostics.Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardInput = true; p.StartInfo.CreateNoWindow = true; p.StartInfo.WorkingDirectory = REPOSROOT; p.StartInfo.FileName = BASHCMD; p.StartInfo.Arguments = HOOKSH + " " + parm; p.Start(); p.WaitForExit(); p.Close(); } //オリジナルGitコマンド実行 p = new System.Diagnostics.Process(); p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardInput = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.WorkingDirectory = REPOSROOT; p.StartInfo.FileName = GITCMD; p.StartInfo.Arguments = parm; //UTF8を使っている。 p.StartInfo.StandardOutputEncoding = Encoding.UTF8; p.Start(); results = p.StandardOutput.ReadToEnd(); p.WaitForExit(); p.Close(); //オリジナルGitコマンドの標準出力を、そのまま自分の標準出力とする。 //バイナリを使わないと一部文字化けが発生する。 //『あいうえお.bat』等 byte[] wkBuff = System.Text.Encoding.UTF8.GetBytes(results); Stream stdout = Console.OpenStandardOutput(); stdout.Write(wkBuff, 0, wkBuff.Length); stdout.Close(); } } } ログファイル出力の下に少しだけ追加しました。 Bashシェルスクリプトを実行しますが、Bash.exeにお願いしているだけです。 pre-checkoutフックスクリプトを作る hooksフォルダに配置しました。 pre-checkout #!/bin/sh cd `dirname $0` pwd echo `date` "pre-checkout start" >> pre-checkout.txt echo `date` '$1 =' "$1" >> pre-checkout.txt echo `date` '$2 =' "$2" >> pre-checkout.txt echo `date` '$3 =' "$3" >> pre-checkout.txt echo `date` '$4 =' "$4" >> pre-checkout.txt echo `date` "pre-checkout end" >> pre-checkout.txt echoだけのダミーです。 動かしてみる もう一度、同じことをします。 ログファイルに『pre-checkout』が出力されています。  フックスクリプトのデバッグ用テキストにコマンドラインパラメータが渡っていったのが出力されています。  ここで入手した、ハッシュとファイル名を元ネタとして、何かできそうな気がしました? 作ってみて  VisualStudioのようにGit直結でというようなツールばかりではないので、手動での操作が介在するため、ミスはさけられないのです。そこで、素直にGitフックでチェックしたり、なんとかしたりすればOKでは?発想となるのです。  セットものとして管理したくなったものは、いっしょにコミットしたり、チェックアウトしたくなるのです。『元に戻すのなら、2ファイル同時にチェックアウトして、同期をとって!!』的なルールを決めていても、きびしい感じです。  少しいいかげんな作りですが、メンテできる人がいれば、まあまあ使えそうな感じもします。記事に汎用性を持たせるために、pre-checkoutスクリプトはBashシェルスクリプトにしてますが、Git for Windowsなので、PowerShell直接呼出しのほうが、メンテしやすいかもしれません。  本当は、TortoiseGitの機能のフックスクリプトにpre_checkout_hookがあればうれしいです。TortoiseGitのpre_commit_hookフックスクリプトは画面でチェックを付けた管理外のファイル名も参照できるので、楽々です。  フック機能はうまく使えば楽になりますが、やりすぎは厳禁かもしれません。今回のはセーフかな?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHubへのPushができない?

GitHubへのPushが出来なくなった。 訳も分からず調べていたらなんとなく解決できたのでまとめてみる。 やりたいこと コマンドからGitHubへのPushを行いたい。 エラー内容 remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead. remote: Please see https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information. fatal: Authentication failed for 'https://github.com/taiki003838/markdown-editor.git/' 調査 ご丁寧にエラー文にリンクが貼られていたので飛んでみると 今まではローカルでGitHubにアクセスするにパスワード認証を使用しておりましたが、脆弱性防止のために個人アクセストークン認証に変更になったそうです。(2021年8月13日にパスワード認証が廃止されます) こういう風に変わったみたいですね。ふむふむ *解決策 GitHubで個人アクセストークンを生成する方法する。 ↓こちらにGitHubで個人アクセストークンを生成するまでの手順が記載されています。 https://docs.github.com/ja/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token 参考 無事解決できてよかった~
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows10にSSH鍵を作成してGitHubにSSH鍵を登録する

前提条件 gitをインストールしていること。 gitのユーザ名、メールアドレスをGitHubアカウントと合わせておくこと。 WindowsにてSSH鍵を生成する ターミナルを起動して、コマンド「ssh-keygen」を叩く。 3回ほど何も入力せずにEnterを叩く。 ターミナル PS C:\Users\XXXX> ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (//.ssh/id_rsa): c:/Users/XXXX/.ssh/id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in c:/Users/XXXX/.ssh/id_rsa. Your public key has been saved in c:/Users/XXXX/.ssh/id_rsa.pub. The key fingerprint is: 48:--:--:--:0b:bf:0a:fd:ff:--:--:--:--:--:--:-- XXXX@YOUR SERVER NAME The key's randomart image is: +--[ RSA 2048]----+ | 略 | +-----------------+ SSH公開鍵をGitHubに登録する。 ターミナルを起動してコマンド「clip < .ssh/id_rsa.pub」を叩く。 (または、C:\Users\XXXX.ssh\id_rsa.pubをエディタで開いて内容をコピーする。) ターミナル PS C:\Users\XXXX> clip < .ssh\id_rsa.pub GitHubにアクセスして右上アイコンからsettingsをクリックする。 その後SSH and GPG Keys → New SSH Keyをクリックする。 Titleはわかりやすいクライアント名にする。 Keyにクリップした公開鍵を貼り付ける。 以上でGitHubにSSH鍵の登録することができました。 クライアントで、Gitリモートリポジトリをクローンできるか確認してください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Windows10でSSH鍵を作成して、GitHubに鍵を登録する

前提条件 gitをインストールしていること。 gitのユーザ名、メールアドレスをGitHubアカウントと合わせておくこと。 WindowsにてSSH鍵を生成する ターミナルを起動して、コマンド「ssh-keygen」を叩く。 3回ほど何も入力せずにEnterを叩く。 ターミナル PS C:\Users\XXXX> ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (//.ssh/id_rsa): c:/Users/XXXX/.ssh/id_rsa Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in c:/Users/XXXX/.ssh/id_rsa. Your public key has been saved in c:/Users/XXXX/.ssh/id_rsa.pub. The key fingerprint is: 48:--:--:--:0b:bf:0a:fd:ff:--:--:--:--:--:--:-- XXXX@YOUR SERVER NAME The key's randomart image is: +--[ RSA 2048]----+ | 略 | +-----------------+ SSH公開鍵をGitHubに登録する。 ターミナルを起動してコマンド「clip < .ssh/id_rsa.pub」を叩く。 (または、C:\Users\XXXX.ssh\id_rsa.pubをエディタで開いて内容をコピーする。) ターミナル PS C:\Users\XXXX> clip < .ssh\id_rsa.pub GitHubにアクセスして右上アイコンからsettingsをクリックする。 その後SSH and GPG Keys → New SSH Keyをクリックする。 Titleはわかりやすいクライアント名にする。 Keyにクリップした公開鍵を貼り付ける。 以上でGitHubにSSH鍵の登録することができました。 クライアントで、Gitリモートリポジトリをクローンできるか確認してください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コードレビューのすゝめ

概要 みなさんコードレビューしていますか?(されていますか?) 私は基本的にコードレビューをすべき(されるべき)だと考えています。 今回は、なぜコードレビューをした方がいいのか、誰が誰にすべきなのか、具体的なやり方、注意点についてご紹介したいと思います。 なお、本記事はあくまでも私個人の考え方なので正解というわけではないです。 ※ 前提として、コードレビューと動作レビューは別物の想定です。 誰が誰にレビューするべき? 私は新人・玄人関係なく、コードレビューするべきだし、されるべきだと考えています。 レビュー者は、必ずしもコードが綺麗に書ける人・経験が豊富な人である必要はないです。 コードレビューすることで、こんな書き方や考え方があるんだということをレビュー者が学べたり、知識が少ないからこその気付きがあったりします。したがって、新人だからとか不慣れだからとかは気にしなくてもいいです。 品質担保を目的とするのであれば、新人と経験者の二人をレビュー者とすれば良いですね。 少なくとも、これまでコードレビューをしてこなかったチームや会社なのであれば、不慣れな方がコードレビューするからといって、品質が下がるということはないのでご安心ください。(笑) 具体的なやり方 前提条件 ラベル GithubやGitlabにラベルというものがありますので、ぜひ活用しましょう。 参考までに私がよく利用しているラベルの一部を紹介します。 名称 意味 doing 現在作業中です done / finished / fixed 作業終了しました reviewable レビュー可能な状態です feedback フィードバックがあるので確認してください mergeable マージ可能な状態です フロー issue作成からmergeするまでの流れを記載してみました。 注意点 レビューが必要かどうかの基準を設ける 全て機械的にレビューするのではなく、例えば、文言変更だけの場合はレビューは無しでOKなど、レビューが必要かどうかの基準をチームで定めるのは良いと思います。 コードの分量(レビューにかける時間) 基本5分程度を目安にできるくらいがいいです。 (レビュー者と被レビュー者が慣れるまでは時間がかかりますが、それは仕方ないです。) また、マージリクエスト(プルリクエスト)もそれくらいの粒度で作成できると良いです。 どでかいのをレビュー依頼されると、、、見ること自体辛いですし、レビューの精度は格段に落ちます。(笑) 改善案は具体的に書く レビュー時のコメントは具体的に書いてあげましょう。 サンプルコード PHPのサンプルコードで試しにレビューして、コメントしてみます。 function getUserIds($users) { $data = []; for($i = 0; $i < count($users); $i++) { $data[] = $users[$i]->id; } return $data; } 良くない例 もう少し簡潔に記載してください。 良い例 具体的な改善案を示してあげると対応もしやすいです。 `array_map`という関数を使えばもっと簡潔に書けそうです! https://www.php.net/manual/ja/function.array-map.php 余談ですが 昔、私は上記のような良いコメントのおかげで、array_mapという関数を知ることができました(笑) レビューにおいて立場や経験は関係ない!? 立場や経験などを気にしてレビューはしないようにしましょう。(No忖度!) 例えば、A先輩は10年のベテランだから、気になるところがあるけれどコメントせず承認だけしとけばいいよね? や 俺はベテランなのになんで新人のBからコメントされないといけないの?とかはやめましょうね。 レビュー者は素直に気づいたことはコメントしたり、質問したりしましょう。 また、被レビュー者は私のコードを見てくれてありがとう。コメントありがとう。気づかせてくれて(教えてくれて)ありがとう。の気持ちを持ちましょう。 コミュニケーション 当たり前ですが、これが多分一番大事ですね。 コメントは感情のない文章でのやりとりなので、レビュー者にそんなつもりがなくても冷たい感じに受け取られてしまったり、怒っている感じに受け取られてしまったりします。 だから、コメントする時は表現を気をつけたり、顔文字をつけたり、など簡単にできる最低限の配慮があるといいですね。 また、どうしてもコメントだとやりとりが長くなりそうといういう時は、口頭で伝える+簡単なコメントという感じがいいですね。 さいごに コードレビューのメリットややり方をご紹介してきましたがいかがでしょうか? もちろん、デメリットとしてレビュー工数がかかってしまいます。 ただ、そのデメリットを鑑みても、メリットの方が勝ると私は考えています。 この辺は案件の規模や予算などによっても分かれるところかと思いますが、まだレビューしたことないよーという方はぜひチャレンジしてみてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む