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

[GitHub]revertコマンドとresetコマンドの違いについて![初心者]

はじめに

以前、アプリ開発に取り組んでいるときに、直前にコミットした操作に誤りが見つかり、コミットを取り消したいということがあったのですが...
どうやってコミットの履歴を消すのか分かりませんでした。
ネットで調べていくと、GitHubのコマンドには、revertコマンドresetコマンドというものがあることを発見。
しかしよくよく説明を読むにつれて、これらのコマンドを使用する際は、落とし穴にはまる危険性が高い、と思いました。

備忘録も兼ねてアウトプットします!!

revertコマンドについて

反対の内容で新規コミットを作成し、過去のコミットを打ち消すためのコマンドです。
新しくコミットを追加しているだけであり、既存コミットの履歴がGitHub上から消えることはありません。
よって、後述するresetコマンドと比較すると、安全なコマンドと言えるでしょう。

使用方法

通常は以下のコマンドを打ち込むと、自動コミットという流れになります。
コマンド入力後に自動でエディタが開くので、コミットメッセージを併せて入力する形です。

$ git revert <commit> -e

または

$ git revert <commit> --edit

逆に、新規コミットしない方法もあります。

$ git revert <commit> -n

または

$ git revert <commit> --no-edit

コミットメッセージなしでrevertできます。

resetコマンドについて

revertコマンドと違い、現在のHEADを指定された状態にリセットするコマンドです。
指定したコミット以降に行われた処理を全て元の状態に戻します。
しかし、その戻したということ自体、コミットログには一切記録が残りません。
よって、チーム開発などで使用することは、極めてリスキーなコマンドです。

使用方法

直前のコミットを元の状態に戻すとき

$ git reset --hard HEAD^

n個前のコミットまで戻すとき

$ git reset ---hard HEAD~n

resetコマンドのオプション

上記で使用している--hardを含め、いくつかのオプションが存在します。

オプション名 インデックス ワーキングツリー
--mixed(デフォルト) リセット リセットされない
--soft リセットされない リセットされない
--hard リセット リセット

おわりに

GitHubでコミットやプッシュのミスに気がついた時は、かなり焦ることが多いですよね。
そんな万が一の際に、慌てふためくことのないように、こういったイレギュラーな処理にも慣れていきたいと思いました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【GitHub】Branch protection ruleの運用ルールを作った話

この記事はMicroAd (マイクロアド) Advent Calendar 2020 - Qiitaの6日目の記事です。


前書き

この記事では、自分の所属しているチームが主に開発しているGitHub1リポジトリに関してBranch protection ruleの運用ルールを作った話についてまとめます。

背景

弊チームでは元々Branch protection ruleをなんとなくで運用していましたが、rebase等の操作に伴って外したプロテクションの戻し忘れが発生したり、手伝いに入って貰った別チームから「うちは個別のBranch protection ruleで運用したい」といった要望が出たため、正式に運用ルールを整えることにしました。

設定した運用ルール

運用ルールは最終的に以下のような形になりました2

  • よく使う名前のブランチは包括的にプロテクションをかけておく(これらのルールは編集禁止)
    • master
    • release
    • *_feature(個別の案件系ブランチ)
  • 特殊な操作・運用が必要な場合、個別のブランチに関するプロテクションを立て、そちらで制約を緩める
  • 不要になったプロテクションはなる早で削除する

これらのプロテクションを入れると以下のようになります3
スクリーンショット 2020-11-28 16.56.52.png

以下に機能面での解説をします。

正規表現を用いたプロテクション

弊チームでは、個別の案件系ブランチには${案件の識別番号}_featureという名前を付けています。
これらのブランチは並行で複数存在するため、基本的なプロテクションはワイルドカード構文を用いて行うこととしました。

これによって、featureブランチを作る度に一々プロテクションを作る必要が無くなります。

個別のブランチプロテクション

正規表現を用いたプロテクションは、より具体的な名前のプロテクションで上書きすることができます。

例えば、hoge_featureという名前のブランチに対してhoge_feature*_featureというプロテクションが有った場合は前者が優先的に適用されます。
つまり、*_featureプロテクション内でforce pushが禁止されていても、hoge_feature内でforce pushを許可することで、hoge_featureへのforce pushを可能にするようなこともできます。

これによってチームごとにプロテクションルールを設定したり、個別のブランチに対する操作の間だけ制約を緩めるようなことができます。

今回の運用ルール制定前は全体へのプロテクションを弄って制約を緩めるようなこともしていましたが、戻し忘れた際の影響が大きいということで、必要になった場合だけ個別に立ててすぐ消すという運用に落ち着きました。

おまけ

featureブランチに実際に設定しているBranch protection ruleを載せます。
スクリーンショット 2020-11-28 17.10.34.png

主に設定していること

  • マージ前に1人以上のレビュー必須
  • CI(テストとlint)の成功必須
    • このリポジトリには2種類のCIが設定されていて、featureではチェックを付けている片方のみ動かしているため、チェックは動かしている方にだけ付けています
  • マージ前のrebase必須
  • 管理者にもルールを適用
  • push禁止(force pushだけでなくブランチへのpushそのものを禁止)

終わりに

今回はBranch protection ruleの運用ルールを作った話に関してまとめました。
合わせてBranch protection ruleそのものも整備しましたが、色々な事故のリスクが減って良かったです。

明日は@taka_maenishiによる「PySparkarray<struct>のフィールドを操作する」記事です。

公式資料


  1. 正確にはGitHub Enterpriseですが、ややこしいのでGitHubと書いています。 

  2. hotfix系などは*_featureと同様のプロテクションをかけていますが、記事中では省略します。 

  3. 形だけ再現したものなのでCurrently appliesが0になっていたりしますが、実際はここにプロテクションが当たっているブランチの数が出ます。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】gitが入ってるのにタブ補完がならないあなたへ

 はじめに

この記事を読んでる方は、gitでswitchする時にブランチ名がfeature/hogeだったりで打つのめんどくさいと思い、
タブ補完機能を.zshrcや.bashrcで設定しようとしてみたはずです。
でも、

macの最初から入ってるgitだとならないんですよね。

じゃあどうしたらいいのでしょうか?

結論

brew でgitを入れましょう

たったこれだけです。
最初から入ってるgitは消さなくていいです。

gitをbrewで入れる方法や、.zshrcや.bashrc内の設定方法の説明は、僕よりこのリンク先の方がわかりやーすく説明できると思うので、こちらの方にまかせます(あとは頼んだゾ。。。)
https://hirooooo-lab.com/development/git-terminal-customize-zsh/

最後に

macのデフォルトのgitで必死にタブ補完機能の付け方を探してた自分と同じ人を減らしたくて書きました。
「gitをbrewで入れればいい」って伝えたいだけでなので、文章テキトーです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Mac】zshやbashでgitのタブ補完を設定したのにならないあなたへ

はじめに

この記事を読んでる方は、gitでswitchする時にブランチ名がfeature/hogeだったりで打つのめんどくさいと思い、タブ補完機能を.zshrcや.bashrcで設定しようとしてみたはずです。
でも、

macの最初から入ってるgitだとならないんですよね。

じゃあどうしたらいいのでしょうか?

結論

brew でgitを入れましょう
たったこれだけです。
最初から入ってるgitは消さなくていいです。

gitをbrewで入れる方法や、.zshrcや.bashrc内の設定方法の説明は、僕よりこのリンク先の方がわかりやーすく説明できると思うので、こちらの方にまかせます(あとは頼んだゾ。。。)
https://hirooooo-lab.com/development/git-terminal-customize-zsh/

最後に

タブ補完機能がならなくて原因を探りに探って行き着きました。
そんな自分と同じ人を減らしたくて書きました。
「gitをbrewで入れればいい」って伝えたいだけでなので、文章テキトーです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【1分でできる】Gitコマンドを省略する方法

はじめに

エイリアスを使ってGitのコマンドを省略する方法を紹介します。

設定自体は1分で終わりますが、Gitの設定について簡単に解説しているので最後まで読んでいただけると幸いです。

設定方法

さっそくですが、以下のコマンドを実行することで設定することができます。

% git config --global alias.(設定したい省略系) (元のコマンド)

例えば、git commitをgit ciで実行したいなら

% git config --global alias.ci commit

という書き方になります。設定は以上です笑

下記の4つはよく使うので、設定しとくと作業がスムーズになります。
どのように省略するかはお好みで!

元のコマンド 省略系
commit ci
branch br
status st
checkout co

設定方法だけ知りたい方はここでサヨナラしてもらって大丈夫です。。。

Gitを使い始めたばかりの人や、コマンドの意味がよく分からない人は下の解説を参考にしてください!

コマンドの解説

上記で実行したコマンドの説明をしていきます!

↓コマンドの復習↓

% git config --global alias.(設定したい省略系) (元のコマンド)

1. configとは

configとはGitの設定を行うためのコマンドで、Gitの設定ファイルに記述を行ってくれます。
設定ファイルにこんな感じで記述しといてって頼むイメージです。

configの和訳は「設定」なのでそのままですね。

オプションに--globalを使うことでパソコンのユーザー単位で設定を行うことができます。

globalオプションをつけずに設定を行うと、ディレクトリ単位での設定になります。
今、開発しているアプリだけでコマンドを省略したい場合はglobelオプションをつけずに行いましょう。ターミナルで対象のディレクトリまで移動するのを忘れずに。

なぜオプションをつけることで設定を反映させる範囲が変わるのか?

それはGitの設定ファイルがそれぞれの単位毎に存在し、オプションによってどのファイルに設定を保存するか指定しているからです。

指定なし → (Gitで管理している各ディレクトリ)/.git/config
--global → ~/.gitconfig

ですので、最初に使用したコマンドを使わなくても上記ファイルに直接書き込むことで、
Gitの設定を行うこともできます。

ちなみに--systemでパソコン単位で設定を行うことができます。ユーザーが複数いて同じ設定をしたい場合はこのコマンドを使うと便利です。

設定の優先順位は
1. ディレクトリ単位
2. ユーザー単位
3. パソコン単位
となります。

2. エイリアスとは

aliasはエイリアスとよび、超簡単に言うとニックネームのようなものです。
山田たかし君を山ちゃんと呼んだりタカポンと呼んだりしますよね。あれと同じです。
Gitでもエイリアスを登録することでコマンドにニックネームをつけることができます。

上記で紹介したコマンド以外でもエイリアスを登録できます。
例えば僕は、ログを一行で表示してくれるコマンドのエイリアスを登録しています。

設定方法は以下のようになります。

% git config --global alias.one 'log --oneline'

'log --oneline'という名前の友達に'one'とニックネームをつけています。
この場合は元のコマンドをシングルクオテーションで囲む必要があります。

エイリアスの使い方として、単に省略するために使うだけでなく、なかなか覚えられないコマンドを自分が覚えやすい形で登録することで、いちいちコマンドを調べる手間を省けます。

終わりに

本記事では初学者の方でも分かるように、Gitコマンドを省略する方法を紹介しました。

Gitに限らずいちいちコマンド打つのってかなりめんどうですよね。。。
履歴を使うのもありですがエイリアスを使えばサクッとGitを使えます。

初学者こそタイピングが遅かったり操作に時間がかかったりすると思うので、この記事が少しでも参考になれば幸いです。

また、この前までaddとcommitとpushしか知らなかった人間が書いた記事なので、ご指摘等あればコメントしていただけると喜びます。

最後まで読んでいただきありがとうございました!!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[個人開発あるある] 失われたリポジトリを発掘する旅に出る

PCの中に埋もれたgitリポジトリありませんか?私はたくさんあります。以下の方法で探り当てたリポジトリを見ると自分では全然覚えてない作りかけの物が出てきました。実家のタンスの奥から子供の頃のオモチャが出てきたような気分です。

もともとは「数ヶ月さわってないプロジェクトを久しぶりに開くにはどこに置いてたか探すことから始めなきゃならない」という当たり前のことに気付いたからでした。
ghq等を使ってる方はちゃんと管理できてるんでしょう。しかしリポジトリ迷子の私みたいな方はたくさんいると思います。そして思いついたのがpecoを使った方法です。

peco
peco公式より

こんな感じでリポジトリの一覧から選んでVSCODEで開けたら便利ですよね。
その方法を実現する手順は以下の通り。

  1. findコマンドでPC内からリポジトリの一覧を作成&保存
  2. zshrcにpecoの設定を追加
  3. zshrcにfindのエイリアスを追加

これだけです。

ちなみにpecoのインストールについては公式を御覧ください。Homebrew, Scarf, apt等でもインストールできます。

peco/peco: Simplistic interactive filtering tool

1. findコマンドでPC内からリポジトリの一覧を作成&保存

> find ~/Documents -regex ".*/.git" > /path/to/git_paths.txt

引数の~/Documentsはgitリポジトリが眠っていそうな大体の場所です。まさか~/Moviesとか~/Musicなんかにリポジトリを置いてる人はいないでしょう。findは時間がかかるのである程度検索範囲を絞ったほうが良いです。私は基本的に~/Documents以下に置いているのでここを検索対象にしました。

/path/to/git_paths.txtは一覧を保存する場所です。適当なpathを指定してください。
ちなみに私の場合、コマンドの実行は約3分。170のリポジトリが発掘されました。

2. zshrcにpecoの設定を追加

.zshrc(他のshellならその設定ファイル)を開いて以下を追記します。

function peco-select-repository() {
  local repo=$(cat /path/to/git_paths.txt | sed s/\.git$// | peco)
  if [ -n "$repo" ]; then
    print -z "${repo}"
  fi
}
alias gp=peco-select-repository

内容を解説すると2行目のcatでファイルを読み込み、sedで末尾の.gitを削除(取得したいのは.gitディレクトリの親ディレクトリなので)、そしてpecoに渡しています。

4行目のprint -z "${repo}"でパスを出力します。そのまま実行しても仕方がないので目的により書き換えたほうが良いかもしれません。

print -z "cd ${repo}"   # 移動したい場合
print -z "code ${repo}" # VSCODEで開きたい場合

個々の目的に応じて書き換えてください。

これを保存してターミナルを開き直すと使えるようになります。
gp+returnでリポジトリの一覧が表示されます。

3. zshrcにfindのエイリアスを追加

1で実行したfindは定期的に行って更新する必要があります。とは言っても最近のリポジトリは覚えているでしょうから頻繁に行う必要はありません。数ヶ月に1回で十分だと思います。
その時にfind hogehoge~~~と書くのは面倒なのでaliasを設定しておきます。.zshrcに書きます。

alias reposearch='find ~/Documents -regex ".*/.git" > /path/to/git_paths.txt'

ターミナルを開き直すとreposearchでfindを実行できるようになります。

まとめ

最終的に私の.zshrcに追記したのはこんな感じです。
my_git_repo.txtはzshrcの近くにある方が管理しやすいと思うので同じ階層の~/.zsh/に置くことにしました。

function peco-select-repository() {
  local repo=$(cat ~/.zsh/my_git_repo.txt | sed s/\.git$// | peco)
  if [ -n "$repo" ]; then
    print -z "code ${repo}"
  fi
}
alias gp=peco-select-repository
alias reposearch='find ~/Documents -regex ".*/.git" > ~/.zsh/my_git_repo.txt'
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git rebaseのユースケース

目的

  • 最近プロジェクトで$ git rebaseをすることがあったので例として紹介する

前提情報

  • 実際の開発現場で$ git rebaseを実行したときの内容をまとめる。
  • このプロジェクトの開発言語はPHPでフレームワークはLaravelを使用している。

ユースケース

  1. 自分の作業ブランチはmasterから分岐したブランチである。わかりやすいように自分の作業ブランチはAブランチとする。
  2. 先輩の作業ブランチもmasterから分岐したブランチである。わかりやすいように先輩の作業ブランチをBブランチとする。
  3. 先輩がDBの設計とマイグレーションを実施し自分がサーバサイドの機能を作成する段取りになっていた。
  4. DBができないとサーバサイドの実装はできないがDBのER図やカラム情報がドキュメントで開示されていたた。そのため先行してmasterからAブランチを分岐して作業を開始した。
  5. Aブランチの実装完了前に、先輩が作業完了しBブランチをリモートリポジトリにpushした。
  6. Aブランチはmasterから分岐しているが、分岐元をBブランチにしたい。下記の方法でrebaseを行い分岐元をBブランチとした。
    1. $ git fetchを実行してリモートリポジトリの最新の情報をリモート追跡ブランチに取得した。
    2. $ git branch -aを実行してリポジトリの一覧を出力しBブランチがあることを確認した。
    3. $ git checkout Bブランチ名を実行してBブランチをローカルリポジトリに取得した。
    4. $ git switch Aブランチ名を実行してAブランチに移動した。
    5. $ git rebase Bブランチ名を実行してAブランチの分岐元をmasterからBブランチに変更した。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ターミナルの出力結果をテキストに出力する

0.背景

ターミナルで出力した結果をテキストに出力できたら便利だと思い、まとめました。

1.使用環境

mac.os バージョン10.15.6
Ruby2.6.6

2.実際やってみる

Rubyのバージョンを追加する際にインストール可能なバージョンを確認したいと思い、
rbenv install --list-allを実行したところ、見切れてしまいました。
ターミナル.png
新たにインストールを行う、2.5.1のバージョンを探していますが見当たりません。
※rbenvとは、Rubyのバージョンを簡単に切り替えてくれるツールのことです。
参考リンク:rbenvの使い方と仕組みについて

そこで下記のサイトを元に出力してみました。
[Tool] Mac標準コマンドで出来る!ターミナルの出力結果をテキストファイルにも保存する方法

$ script sample.txt           #ファイル名を指定する
$ rbenv install --list-all    #実行したい処理
...
$ exit                       #書き出しを終了

実行するとsample.txtの名前でテキストに出力できたことが分かります。
無事探していた2.5.1も見つかりました。

sample.txt.png

3.どこに保存されているのか?

先ほどのコマンドは保存場所を指定していません。ではどこに保存されているのか?というと
ホームディレクトリに保存されます。ホームディレクトリはmacの場合、Finderを開いてShift + command + Hで飛べます。

補足:ファイル名を指定しない場合

ファイルを指定しない場合、typescriptに保存されます。
参考リンク:Linuxコマンド【script】
typescriptもホームディレクトリに保存されます。
screen typescript.png

4.応用先

Gitでlogを出力したいときなど、いろんなところで活用できるのではないかと思います。
読んで頂き、ありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む