コンピューターシステム株式会社

技術BLOG

Git: 基本的な使い方と操作の取り消し

Git 2021/06/30 大阪担当

こんにちは、大阪営業所のSSKです。

最近、履歴の管理やレビューのし易さからソースコード以外でもGitを使うことが増えてます。

設計書であっても、Markdownで記載すればある程度の体裁は保てますし、GitHubのAtomエディターならPlantUMLが使えるので、UMLもバージョン管理できてとても便利です。

ただ慣れている人ならいいのですが、Git初心者には毎回Gitの使い方とか説明しないといけないので、そこにそれなりに時間がかかっています。

今回、Gitの説明用に情報をまとめられたらと思い、本記事を記載することにしました。

サーバーからファイルを取ってきて編集してサーバーに戻す手順

git clone git@****.git work
cd work
git checkout -b feature origin/master

echo abc > test.txt

git add .
git commit -m "added test.txt"
git push origin HEAD

まずはパターンを覚えるような気持ちで実行してみましょう。

実行時に個々のコマンドの意味を理解しながらやれば、そんなに難しくは無いと思います。

用語の説明
リモートリポジトリー 作業者全員がやり取りするサーバーにある大元のバージョン管理情報です。
ファイルの追加や修正後はここに入れるのを忘れないようにしましょう。
ローカルリポジトリー 作業者の端末内に持つバージョン管理情報です。
リモートリポジトリーをローカルに複製したものです。
ワーキングツリー ローカルリポジトリーから取り出したファイル群です。
ステージングエリア commit対象を登録しておく場所です。
ブランチ 機能追加やバグ修正などの目的別にコミット履歴を管理するモノです。
自分の作業用に作成したブランチで編集した内容は他のブランチに影響しないので、共同開発するときは作業毎にブランチを作成して、作業完了後にベースブランチにマージします。
同じファイルの同じ個所を複数のブランチで編集していた場合はベースブランチにマージするタイミングでコンフリクト(衝突)が発生するので、手動でファイルを整理してコンフリクトを取り除く作業が必要になります。
コマンドの説明
clone リモートリポジトリーから自分のPC上にローカルリポジトリーを複製します。
ローカルリポジトリー複製後にデフォルトブランチからワーキングツリーを作成します。(masterになっていることが多いです。)
checkout ワーキングツリーを特定のブランチのものに切り替えたり、新しいブランチを作成します。
add ワーキングツリーで追加・編集・削除したファイルやフォルダをcommit対象とするためにステージングエリアに登録します。
追加・変更・削除したすべてのファイル・フォルダをステージングエリアに登録したい場合はドットが使えます。
commit ステージングエリアの内容をローカルリポジトリーに反映します。
push ローカルリポジトリーの内容をリモートリポジトリーに反映します。

機能追加やバグ修正するとき

git fetch -p
git checkout -b new-feature origin/base

~目的の対応が完了するまで以下を繰り返し~

git add .
git commit -m "(修正内容をコメント)"
git push origin HEAD

~~~~~~~~~~~~~~~~~~~~~

# merge前にベースブランチを最新にして、作業ブランチのベースブランチを最新のものに付け替える
git fetch -p
git rebase origin/base # コンフリクトがあればこの段階で分かる。手動で修正したあとcommitしてrebase --continue
# ベースブランチを最新の状態で作り直して作業ブランチをmerge
git branch -D base
git checkout -b base origin/base
git merge new-feature
git push origin HEAD

# 作業ブランチは消しておく
git push --delete origin new-feature

ベースになるブランチに対し機能追加をしたりバグ修正をする場合、作業中の他の人に影響を与えないように別ブランチを作成して作業します。

作業開始時に作業ブランチをベースブランチから作成しますが、ローカルリポジトリーの内容がリモートリポジトリーに比べて古くなっているかもしれないため、作業ブランチ作成直前にリモートリポジトリーの内容を取り込んだ方がよいと思います。

ベースブランチとの差異が増えれば、それだけコンフリクトのリスクが増えますので。

また、ベースブランチへのマージはGitHubのようなサービスを使用すればプルリクエストという便利な機能があるので、それに任せることができます。実際はあまり手動ではマージしないかもしれません。

コマンドの説明
fetch リモートリポジトリーの内容をローカルリポジトリーに取り込みます。
rebase ベースブランチを別のものに変更したり、コミットログをまとめたりします。コミットログをまとめる場合は-iを付けます。
ここの部分はスキップできます。もしコンフリクトがあればmergeのタイミングで分かりますので、そのタイミングで取り除いてください。
branch ブランチの一覧を表示したり削除したりします。
-dで削除になりますが、対象ブランチに作業中のものがあったりすると削除できません。本当に不要な場合は-Dで強制削除できます。
merge 別のブランチの変更内容を現在のブランチに取り込みます。

rebaseの動作イメージは以下のような感じです。

特定のファイルの変更を元に戻したいとき

git status
git checkout (戻したいファイル)

コマンドの説明
status checkout後に追加・変更・削除されたファイル・フォルダを確認できます。
checkoutで元に戻したい場合、statusで表示される相対パスをコピー&ペーストすると楽です。

addを取り消したいとき(commit前)

git log
git reset HEAD
git log

デバッグコードを入れたソースコードをaddしてしまったなど、間違ってaddしてしまった場合にはresetを使います。

resetは戻したいコミットのハッシュ値を使ってコミット履歴を戻しますが、HEADを使用して戻すこともできます。HEADとは現在の最新コミットを表すポインタです。

addを取り消すためには最新のコミットの状態に戻せればいいので、最新のコミットを表すHEADを指定します。

addしたソースコードをいったんadd前に戻したいだけなので--hardは指定しません。--hardを指定するとファイルが変更前に戻ってしまいます。

reset前後のlogをチェックして、履歴が変わっていないことを確認しましょう。

コマンドの説明
reset 現在のブランチを特定のコミットまで戻します。
戻し先までにあるコミットはコミット履歴から削除されます。
--hard/--soft/--mixedでreset後のワーキングツリーとステージングエリアの状態を決めます。
--hardならワーキングツリーとステージングエリアを戻り先のコミット時の状態に戻します。
--softならワーキングツリーとステージングエリアを戻しません。(add後の状態)
--mixedならワーキングツリーを戻さずステージングエリアを戻します。(add前の状態)
デフォルトは--mixedなので指定しなければ--mixed指定時の動作になります。
log 現在のブランチのコミット履歴を確認します。

resetはコミット履歴が戻ってしまうので、共同で使っているブランチなどで使用してしまうと、他の作業者とのコミット履歴との間で不整合が出てしまうなどの危険もあります。

基本的には自分の作業ブランチでのみ使用する方が安全です。

作業者全員と合意を取っての作業であれば共通ブランチへのresetも可能ですが、規模が大きくなれば認識違いなどのリスクは大きくなっていくので、あまりお勧めはしません。

直前のcommitを取り消したいとき

git log
git reset HEAD~
git log

commitを取り消したい場合もaddを取り消したい場合と同様にresetを使います。

addと違うところは、すでにcommitしてしまっているため、今の最新のコミットの1つ前に戻すというところです。

最新のコミットはHEADで表すと説明しましたが、HEADの1つ前はHEAD~で表します。2つ前はHEAD~~です。

reset前後のlogをチェックして、履歴が1つ戻っていることを確認しましょう。

あとがき

他にもコマンドやポリシーはいろいろあって、コミットの単位はこうだとかコミット履歴は整理してからベースブランチに入れろとかあると思いますが、初心者にはまずはここまで出来るようになってもらって、あとは追々ということで。