Skip to content

Instantly share code, notes, and snippets.

@daijinload
Last active May 21, 2022 13:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daijinload/29eae8bb40bf03988093f529cd1cbe32 to your computer and use it in GitHub Desktop.
Save daijinload/29eae8bb40bf03988093f529cd1cbe32 to your computer and use it in GitHub Desktop.

Gitの説明 第3弾 基本操作編

今回はGitでよく使う基本的な操作を説明いたします。

すべてコマンドラインでの説明となります。

Gitを使用している方は、SourcetreeなどのGUIツールを使っている場合もあると思います。

コマンドラインでの操作が分かれば、感覚でGUIでの操作も分かって、つぶしが効くと思います。

そのためコマンドラインに拒絶反応を示さずに聞いていってほしいです。

第4弾で実際に僕が使っている応用編をやるので、そちらでやればコマンドラインでも使っていけると思える。。はずです。


余談ですが、僕はGitが流行りだした頃から使っています(自慢ではなく辛かったです。)

その頃はSVNからの移行が必要だったり、使っていたEcripseなどの統合開発環境で操作が難しく使えず、

必要に迫られてコマンドラインで使っていたら、今でもコマンドラインを使っている形です。

自己紹介

サーバーサイドエンジニアのdaijinloadです。

Node.js, TypeScript, Java, Golang, PHPあたりを業務でやったことがあります。

サブ的にではありますが、ReactやFlutterなどのフロントエンドも経験があります。

環境について

Ubuntu 20.4ベースの、LinuxMint 20.3(HWE)をVirtualBoxに入れて起動しています。

  • 第二弾でGitをセットアップした後の環境です。

Gitの構造の説明

Gitのリポジトリをcloneすると下記のように展開されます。

個人のPCにあるもの

  • working-directory(実際のファイル)
  • staging-area(またはindexと呼ぶ)(addしたファイルが入る場所)
  • local-repository【表記:main】(commitしたファイルが入る場所)
  • remote-repository【表記:origin/main】(変更不可・サーバと同期するだけ)

サーバにあるもの

  • remote-repository【表記:origin main】(本体)

Gitの各種コマンドが、Gitの構造のどこを更新しようとしているのか?が分かるようになると混乱することは無くなると思います。

ブランチの説明

リポジトリを最初に作成すると、mainブランチが作成されます(昔はmasterブランチが作成されました。ポリコレで変更となりました。)

プルリクエストを使えるなどあるので、作業するときはブランチを切ってから作業しましょう。

ブランチの名前は何でも良いのですが、修正目的によって命名ルールがあったほうが分かりやすいとのことで、僕は下記としています。

  • featureブランチ【feature/hoge】(新機能開発用)
  • refactorブランチ【refactor/hoge】(リファクタリング用(機能変更は無し))
  • fixブランチ【fix/hoge】(バグFix用)
  • docブランチ【doc/hoge】(ドキュメント用)
  • testブランチ【test/hoge】(テストのみの修正や追加用)

実際にブランチを切るコマンドは下記です。

git checkout -b feature/hoge

ハッシュ値について

Gitはコミットを行うと、コミット前のハッシュ値や追加したファイル情報などから新たなハッシュ値を生成します。

基本的にハッシュ値の集合体に名前を付けたものがブランチなので、ブランチ名はさほど重要では無いのです。

ハッシュ値だけでやろうとすると大変ですし、見づらくもなるのでブランチ名を付けているイメージでいてほしいです。

実際に見てみると下記ですね。

$ git log
commit 2d5139d600fd77d6e6a5931554981a707464cb3a (HEAD -> main, origin/main, origin/HEAD)
Author: daijinload <daijinload@gmail.com>
Date:   Thu May 5 21:45:02 2022 +0900
    add 1

commit a4ab5558407732f4d94c44c717504181f1b3e96c
Author: daijinload <daijinload@gmail.com>
Date:   Thu May 5 21:40:25 2022 +0900
    Initial commit

現状確認

git status

コミット履歴やハッシュ値を見たい場合

git log
git log --pretty=fuller

実際に変更してサーバに上げる手順

ファイルを変更(working-directoryが変わる)

git add ファイル名(指定したファイルの変更をstagingエリアに移動)
git add file1 file2... (複数指定もできる)
git add --all(全部の変更をstagingエリアに移動)
git commit -m 'メッセージ'(stagingエリアの変更をlocal-repositoryにコミットする)
git push origin ブランチ名(local-repositoryの内容を、サーバのrepositoryに反映する)
git push -f origin ブランチ名(通称フォースプッシュ)(過去改変を行ったりすると変化がありすぎてpushできなくなるので強制反映する)
git commit -am '追加'(stagingを飛ばして、local-repositoryにコミットする)

※新規にファイルを追加した場合は、変更扱いとならずにコミットできないため、addコマンドが必要になります。

サーバにあるものをローカルに展開する場合

おすすめは、fetch + rebaseです。

git fetch(ローカルのremote-repositoryとサーバのファイルを同期する。)
git rebase origin/feature/hoge

pullは、fetch + mergeという作業になるので、mergeされたくない場合は、rebaseオプションを付けるかコンフィグに足しておく。

git pull --rebase

# configに足す場合
git config --global pull.rebase true(コンフィグに設定しておく)
git pull

今のブランチを強制的に置き換える場合

自分の修正が無くなるので注意です。

消えてほしくない場合は、ブランチを切って退避させると良いです。

git reset --hard ハッシュ値
git reset --hard ブランチ名

余談だが、下記のようにやれば、サーバのファイルで置き換えることも出来る(自分の修正が無くなるので注意!!)

git fetch
git reset --hard origin/feature/hoge

過去改変したい場合

git rebase -i ハッシュ値
or
git reset --soft ハッシュ値
git push -f origin feature/hoge(force pushとなるのでバックアップ必要)

localにあるブランチの1つコミット持って来たい場合

git cherry-pick ハッシュ値

たいていハッシュ値が被らないので、ブランチ指定しなくても持ってこれます。

持ってきたコミットは、新しいハッシュ値が振られるので、自分で変更してコミットしたときと同じ扱いとなります。

force pushして間違った場合の復元方法

直前にバックアップしている前提となります。

cd バックアップフォルダ
git clone git@github.com:daijinload/test2.git
cd test2
git checkout feature/hoge
git fetch
git reset --hard origin/feature/hoge
# ---
# 上記までが事前準備

git push -f origin feature/hoge

コミットしたユーザが間違えていた場合

特定のユーザを狙ってユーザを変更するやり方。

$ FILTER_BRANCH_SQUELCH_WARNING=1 git filter-branch -f --commit-filter '
        if [ "$GIT_COMMITTER_EMAIL" = "daijinload@gmail.com" ];
        then
                GIT_AUTHOR_NAME="daijinload";
                GIT_AUTHOR_EMAIL="daijinload@gmail.com";
                GIT_COMMITTER_NAME="daijinload";
                GIT_COMMITTER_EMAIL="daijinload@gmail.com";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD
# 確認
$ git log --pretty=fuller

ブランチを切っていた場合、下記で無かったことにしてコミットすれば終わりです。

git reset --soft ハッシュ値
git add --all
git commit -m 'message'

コンフリクトの解決をお見せします

同じブランチで作業していて、コンフリクトが起きた場合の対処法です。

  • 複数コミットがある状態でのマージは大変なので、事前に1コミットの状態に過去改変しておく。

プルリクエストの使い方

ディスクリプション大事

  • 背景 or 原因(機能追加は背景。バグfixの場合は、原因を書く)
  • 修正内容
  • 連絡事項(マージするときは消しておく)

イメージとしては、AWSのワンページャーが近いものだと思います。

指摘の仕方

お互いのメンタルのために、指摘の仕方は、人格攻撃とならないように最新の注意を払うことが必要です。

おすすめは、すごく偉い人のソースコードに指摘をするイメージが良いかと思います。

マージボタンの種類

  • Create a merge commit(細かいコミットを残したいかつ、マージコミットしたい場合。)
  • Rebase and merge(細かいコミットを残したいかつ、マージコミットを作成したくない場合。)
  • Squash and merge(シングルコミットになります。シンプルです。)

個人的には、「Squash and merge」がおすすめです。

コミットを細かくキレイにしてマージするという作業は、個人的には無駄だと思います。

忙しいときにコミットを綺麗に調整している人を見ると、いいから早くしてくれと思います。。。

バグの調査などでも、基本はリリースしたソースコードで調査できれば良いため、

コミットが綺麗で良かったという経験は無いです。


補足説明

特定のファイルのみ持ってくる

# ブランチ名で指定
git checkout origin/main file1.txt

# ハッシュ値でも指定できる
git checkout c3cc481c13de40e69bd042ced86f54f7dea33567 file1.txt

ファイルを修正中に戻したくなった場合も、1ファイルだけ戻せます。 git reset --hard などだと、全体的に戻ってしまうので、こちらがおすすめです。

文字列の一括置換などで、修正ファイルを確認している時に、関係ないファイルを戻したりするときとか便利です。

タグの説明とタグ打ち方法

タグは、リリースした時に作成しておくものです。

もし何かあった問題があった場合も、タグをリリースする運用であれば調査がしやすいです。

作成しなくても運用できますが、releaseブランチも作らずにmainブランチだけでやっていると、mainブランチのどの時点が問題なのか?パッとわからなかったりします。

ブランチだと、pushが出来てしまうため変化してしまいリリースバージョンの管理としては不十分かもしれません。

しかし、タグだとpushすることが不可能なため、リリース物のバージョン管理という意味では作ったほうが良いと思います。

ただ、Microsoftなどはリリースブランチで運用をしたほうが、タグの運用よりも良いなどと言っていたりもします。

Git 分岐ガイダンス - Azure Repos | Microsoft Docs

下記は引用です。

  • タグからブランチに変換しないと、bugfixなどの変更を反映できない。
  • タグからの変換コマンドなどを覚える必要がある。
  • タグを打ち忘れる場合がある。

このあたりは、僕の見解を次回のブランチ戦略などで話す予定です。

# 一覧表示
git tag
 
# タグ付け(local repositoryに反映)
# (タグ名はv2.0.1などのセマンティックバージョニングでも良い)
git tag -a v2022.05.19 -m 'hoge機能リリース' ハッシュ値
 
# タグ消す(失敗したときとか)
git tag --delete v2022.05.19

# リモートサーバにpushする(remoteサーバに反映)
git push origin v2022.05.19

# タグをブランチに変換する(この記事のブランチを切る方法と同じ)
git checkout タグ名
git checkout -b ブランチ名
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment