はじめに
こんにちは、Watanabe Jin(@Sicut_study)です。
今回は記事1本で初心者が必要な知識を全て学べるGitチュートリアルを紹介していきます。
世の中にはたくさんのGitに関する教材があります。しかし、真に良いと思える教材はありません。
もちろん私も4年前はGitという言葉を知らない状態から、書籍などで学習をしました。
しかし、書籍で知識を得たとしても実際にコマンドを使って実践的に学んだわけではなかったのでほとんど身になりませんでした。
私が思う世の中にあるGitの教材のイケてない点は2つです。
結局ほとんどの人が、教材ではなく実際に使ってみて使えるようになっているはずです。
書籍でやったことを全部ちゃんとできるようになった人はいないと考えています。
実際に利用するコマンドは限られている、たまに使うコマンドを紹介しとしても「この記事1本」で説明することができると思って完全版の記事を書くことにしました。
このハンズオンを最後まで行うことで、現場で問題なく利用できるスキルを身につけることが可能です。
動画で学びたい方へ
こちらの記事をテキストにより詳細に解説している動画を投稿しています。
初心者の方はぜひこちらをご活用ください。
おすすめ記事
他にも多くの1本で学べる完全版ハンズオンを投稿しています。よければご覧ください。
1. Gitとは?
Gitとは世界で最も人気のあるバージョン管理システムです。
バージョン管理システムとは、コードに加えられた変更をリポジトリと言われるデータベースにバージョンとして記録するシステムです。
変更履歴を管理して見られるようにすることで、どのような変更をなぜ加えたのかを確認が可能です。履歴をみることで「誰が」「どのような変更を」「なぜ加えたのか」を確認することができます。
バージョン管理をしていないとどうなるのでしょうか?
バージョン管理システムがないと、コードがまとまったフォルダをまるまるコピーして残しておく必要があります。
こんなファイルみたことないですか??👇
バージョン管理には「中央集中型システム」と「分散型システム」に分類が可能です。
中央集中型システムには、Subversion
やConcurrent Version System
があります。
中央集中型では中央のサーバーに接続して最新のコードを取得します。
欠点は単一障害点があります。 もしサーバーがオフラインになってしまったとするとバージョン管理ができくなってしまいます。
その欠点をカバーしたのが「分散型システム」です。
分散型システムにはGit
やMercurial
などがあります。
ユーザーそれぞれにリポジトリをもつため、他のリポジトリと同期することができます。
中央に主となるサーバーがないためオフラインになる心配もありません。
この中でも特にGitは世界中で最も利用されるバージョン管理システムとなります。
あなたがソフトウェアエンジニアを目指すのであれば、必須のスキルになります。
ハンズオンを全て行うことで実際に現場で利用するGitの知識を網羅することが可能です。
3. GitHubとは?
GitとGitHubは同じように扱われることもありますが、異なるものです。
GitHubはクラウド上でGitを使ってバージョン管理できるサービスのことを表します。
その他にもWebサービスならではのプロジェクト管理の機能を利用することも可能です。
「プルリクエスト」などはGitHubで利用できる一つの機能となります。
2. Gitのインストール
ハンズオンを行う前にGitをインストールしましょう。
それぞれのOSにあった方法(Windows, Mac)でインストールを行ってください。
ここではLinuxでのインストールを紹介します。
$ apt update
$ apt install git
❯ git version
git version 2.43.0
git version
とターミナルに入力してバージョンが表示されれば完了です。
3. Gitの初期設定
まずはGitとGitHubの初期設定を行っていきます。
バージョン管理には「誰が」「いつ」「どのような変更をしたか」を記録するためにユーザー情報を付与しています。
その情報を利用前に設定する必要があります。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
ここでは名前とメールアドレスを設定しました。global
とすることでPCのどこでGitを利用してもこのユーザー情報を付与することができます。
次にGitHubにあるクラウド上のリポジトリ(リモートリポジトリ)と、手元のリポジトリ(ローカルリポジトリ)を通信できるような設定をおこないます。
ここではSSH接続という方法で通信を行うことで、普段であれば必要なユーザー名、パスワード入力をしないでも簡単にローカルリポジトリとリモートリポジトリを同期できるようにしましょう。
まずはSSHで必要となる公開鍵
と秘密鍵
を設定します。
公開鍵と秘密鍵はシンデレラのガラスの靴のような関係があります。
ガラスの靴(公開鍵)をGitHubに設定します。
そしてGitHubはアクセスが合ったときに、そのガラスの靴をはける人だけをシンデレラ(正しいユーザー)と認めてリクエストを許可します。
秘密鍵と公開鍵のペアが正しくない場合はリクエストが通らないようになっています。
まずは公開鍵と秘密鍵のペアを作成しましょう
$ cd ~/.ssh
$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/(username)/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Enterキー
を3回押せば公開鍵と秘密鍵が作成できます。
❯ ls ~/.ssh
authorized_keys id_rsa id_rsa.pub
id_rsa
が秘密鍵、id_rsa.pub
が公開鍵にあたります。
公開鍵の内容をクリップボードにコピーします。
$ pbcopy < ~/.ssh/id_rsa.pub (Mac)
$ clip < ~/.ssh/id_rsa.pub (Windows)
$ cat ~/.ssh/id_rsa.pub | xsel --clipboard --input (Linux)
次にGitHubにアクセスします。
アカウントがまだない方は作成をしてください。
右上のアイコンをクリックするとメニューが開くので、Settingsをクリック
左メニューの「SSH and GPCG Keys」をクリック
「New SSH Key」をクリックして
Title : handson (なんでもよい)
Key : クリップボードの内容を貼り付け (Ctrl+v)
「Add SSH Key」をクリックしたら設定完了です。
$ ssh -T git@github.com
Hi jinwatanabe! You've successfully authenticated, but GitHub does not provide shell access.
このコマンドを実行してレスポンスが返ってきたら成功です。
4. リポジトリを作ろう
まずはローカルリポジトリを作りましょう。
この操作はGitを使ってプロジェクトを管理する場合に最初に必ず行う必要があります。
以下のコマンドを実行すればリポジトリを作成することが可能です。
$ mkdir git_handson
$ cd git_handson
$ git init
Initialized empty Git repository in /home/jinwatanabe/workspace/qiit/git_handson/.git/
リポジトリにすることで以降出てくるgit add
やgit commit
などのコマンドが利用できるようになります。
$ ls -la
合計 12
drwxrwxr-x 3 jinwatanabe jinwatanabe 4096 9月 28 11:03 .
drwxrwxr-x 3 jinwatanabe jinwatanabe 4096 9月 28 11:03 ..
drwxrwxr-x 7 jinwatanabe jinwatanabe 4096 9月 28 11:03 .git
.git
というディレクトリが作られました。
これは隠しファイルとなっているので画面から見ると表示されません
この.git
にプロジェクトのバージョン管理に関する情報が含まれています。
試しに.gitを削除してみましょう
rm -rf .git
❯ git status
fatal: not a git repository (or any of the parent directories): .git
git status
を実行するとgitレポジトリではないですと言われました。(git statusについては後で説明)
このあとのハンズオンのために再度リポジトリを作成しておきましょう
$ git init
5. Gitワークフロー
ここからはGitでプロジェクトのバージョン管理をするときの一般的なフローを紹介してい行きます。
あなたは開発しているシステムに脆弱性がみつかり、ハッキングをされてしまっている状況だとします。
そこでコードを修正してリポジトリに反映させようとします。ここでリポジトリに対して永続的に保存するために行うのがコミット(Commit)です。
コミットをすることで、リポジトリに変更の履歴が残ります。
しかし、一部ファイルは履歴に含めたくない(commitしたくない)と考えることもあります。
そこでGitにはステージング(インデックス)というコミットしたファイルを仮でおいておく場所が存在します。
ステージングに追加するファイルをaddコマンドで選択することによって、コミットに履歴に追加したいファイルだけを含めることが可能です。
もしステージングに不要なファイルが含めてしまった場合は、ステージングから特定のファイルを外すことも可能です。
ここまでの流れはざっくりこんな感じになります。
コミットをすることによって、以下の情報が変更に対して付与されるため履歴を管理できるのです。
ローカルリポジトリにコミットができたら、次にGitHubにあるリモートリポジトリに変更を反映します。
リモートリポジトリに反映することでクラウドから他のメンバーは最新のコードを取得することが可能です。
ここまでの流れをgitコマンドで実行すると以下のようになります。
$ git add [ファイル名]
$ git commit -m "どのような変更をしたかのメッセージ"
$ git push
# リモートリポジトリの変更を取得する場合
$ git pull
それでは実際にやってみましょう。
現在ローカルのリポジトリはあるので、まずはリモートリポジトリをGitHubで作成しましょう。
GitHubにアクセスして、アイコンをクリックしてメニューを開き、「Your Repository」をクリックします。
右上の「New」をクリック
Repository nameに「gith_full_course」と入力して「Create Repository」をクリック
これでリモートリポジトリが完成しました。
次にローカルリポジトリとリモートリポジトリを同期させる設定をコマンドで実行します。
「Quick setup」の選択している2行のコマンドを実行します。
$ git branch -M main
$ git remote add origin git@github.com:jinwatanabe/git_full_course.git
git branch -M main
はmainという名前のブランチを作成しています。こちらは後ほど説明します。
最後のコマンドで実行した場所のリポジトリとリモートリポジトリを紐付けています。
それではまずはステージングエリアに追加するところをやっていきます。
VSCodeで作成したリポジトリを開いてください。
そしてindex.js
というファイルを作ります。
$ touch index.js
今回は適当なコードを書いてみます。以下をコピペして貼り付けてください。
console.log("Hello Git");
それでは、git status
コマンドで状態を確認してみましょう。
$ git status
ブランチ main
No commits yet
追跡されていないファイル:
(use "git add <file>..." to include in what will be committed)
index.js
nothing added to commit but untracked files present (use "git add" to track)
git status
コマンドを使うと、のコマンドを実行すると、どの変更がステージング済みでどの変更がまだステージングされていないのか、どのファイルが Git の追跡対象外になっているのかが表示されます。
この場合、index.jsがまだステージングに追加されていないことがわかります。
それではステージングに変更を追加しましょう。
$ git add index.js
$ git status
ブランチ main
No commits yet
コミット予定の変更点:
(use "git rm --cached <file>..." to unstage)
new file: index.js
index.jsがコミットされたことがわかります。
それでは複数ファイルを次はステージングに上げてみましょう
$ touch index2.js
$ touch index3.js
console.log("Hello Git2");
console.log("Hello Git3");
$ git status
ブランチ main
No commits yet
コミット予定の変更点:
(use "git rm --cached <file>..." to unstage)
new file: index.js
追跡されていないファイル:
(use "git add <file>..." to include in what will be committed)
index2.js
index3.js
それではindex2.jsとindex3.jsをステージングに追加します。
1つずつ丁寧に追加してもいいですが複数ファイルを追加するときはもっと便利な追加の仕方があります。
$ git add index2.js index3.js
or
$ git add .
git addに続いて複数ファイルを指定するか、.
を使うことではディレクトリ配下のステージング追加されていないファイルをすべて追加することが可能です。
git add .
が実際には多く利用されます。
それでは、次にコミットして履歴を追加しましょう
$ git commit -m "初めてのコミット"
[main (root-commit) f073dd5] 初めてのコミット
3 files changed, 2 insertions(+)
create mode 100644 index.js
create mode 100644 index2.js
create mode 100644 index3.js
git_handson on main via v22.4.0
$ git status
ブランチ main
nothing to commit, working tree clean
コミットが終わることで、git statusから表示がなくなりました。
それでは最後にローカルリポジトリとリモートリポジトリを同期させます。
$ git push origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (5/5), 363 bytes | 363.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:jinwatanabe/git_full_course.git
* [new branch] main -> main
origin main
はオリジンがリモートリポジトリのことを指しており、リモートリポジトリのmainブランチに対して、ローカルの変更を反映させるというコマンドです。
異なるブランチにpushする場合はmainの部分が変わります (あとで説明します)
先ほど作成したGitHubのリポジトリをみるとローカルリポジトリの内容が同期していることがわかります。
6. コミットは細かくする
コミットはステージングにある変更を履歴に含めますが、なるべく細かくステージングに入れてコミットすることをおすすめします。
細かいコミットにしておけばピンポイントで取り消したいコミットをなくすことが可能です。(revert)
もし全部のコミットが1つにまとまっている場合、修正の一部だけを取り消すというのが難しくなります。
バグ修正中にタイポを見つけたら同じコミットに含めるのではなく、それぞれ別にしてメッセージも意味のあるものにするのが大切です。
コミットメッセージはそれぞれのコミットが何を行ったのか伝えるためにも大切です。
7. ステージングの変更を消す
index1.jsの内容を少し変更します。
console.log("change");
変更を確認してみましょう。git diff
が使えます。
$ git status
ブランチ main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.js
$ git diff
diff --git a/index.js b/index.js
index bb8ec33..5e022a9 100644
--- a/index.js
+++ b/index.js
@@ -1 +1 @@
-console.log("Hello Git");
+console.log("change");
履歴に保存されているindex1.jsとの差分を表示してくれます。
それではステージングに持っていきます。
$ git add .
$ git status
ブランチ main
コミット予定の変更点:
(use "git restore --staged <file>..." to unstage)
modified: index.js
index.jsの修正が間違えていたので、ステージングから戻してみます。
$ git resotre --staged index1.js
ブランチ main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: index.js
git restore --staged
で戻すことができます。
では、index1.jsに加えた変更ももとに戻したいと思います。
$ git checkout index.js
checkout
することによって修正ももとに戻ります。
では新しいファイルをつくりましょう
$ touch index4.js
$ git status
ブランチ main
追跡されていないファイル:
(use "git add <file>..." to include in what will be committed)
index4.js
nothing added to commit but untracked files present (use "git add" to track)
ここでファイルを取り消すためにcheckout
してみましょう
$ git checkout index4.js
$ git status
ブランチ main
追跡されていないファイル:
(use "git add <file>..." to include in what will be committed)
index4.js
新規追加されたファイルはcheckout
ではもとに戻せません。
ファイルを削除すると戻すことができます
$ rm -rf index4.js
$ git status
ブランチ main
nothing to commit, working tree clean
ちなみにcheckoutはaddと同じく.
や複数ファイル選択もできます。
8. 特定のファイルやでディレクトリをgitの管理外にする
次に特定のファイルやディレクトリをgitの管理対象外にするgit rm
コマンドを紹介します。
まずは1つ秘密の情報が載っているファイルをcommitします。
$ touch secret.txt
秘密の情報
$ git add .
git_handson on main [+] via v22.4.0
$ git commit -m "色々開発した"
[main 9f13ec2] 色々開発した
2 files changed, 2 insertions(+), 1 deletion(-)
create mode 100644 secret.txt
$ git push origin main
GitHubのリポジトリにsecret.txtが追加されました
しかし気づきます。このファイルはGitHubにアップロードしてはいけないファイルだということに。
そこでsecret.txt
をgitの管理外に戻したいと思います。
$ git rm --cached secret.txt
❯ git status
ブランチ main
コミット予定の変更点:
(use "git restore --staged <file>..." to unstage)
deleted: secret.txt
追跡されていないファイル:
(use "git add <file>..." to include in what will be committed)
secret.txt
git rm --cached [ファイル名]
でgitの対象外にできます。
もしファイルも削除したい場合はgit rm [ファイル名]
で対象から外してファイル削除まで可能です。
いまのままでは追跡されていないファイルにsecret.txt
があり、add
してしまう可能性がありますので、ここにも表示されないようにgitから完全に対象にならないよう設定してきます。
そこで利用するのが.gitignore
です。
$ touch .gitignore
このファイルにgitの管理対象にしたいファイルやディレクトリを選択することができます
secret.txt
VSCodeをみるとsecret.txtのファイルが削除されたことに成ります。
これはgitで管理から削除されてなくなったことを表しています。
では、pushまでやってきます。
$ git add . // .gitingnoreファイルをステージングへ
$ git commit -m "秘密のファイルを削除"
$ git push origin main
GitHubからsecret.txtが消えました
ここで注意が必要なのは一度Pushしてしまうとクラウドに履歴が残ってしまうため、完全に削除することは不可能です。シークレットな情報をクラウドにあげてしまうと、誰かに見つかってしまった場合悪用されることに繋がります。AWSのシークレットキーが流出した場合はAWSのリソースを気づかないうちに使われて高額請求につながることがあります。秘密の情報は.gitignoreに追加するのを忘れないでください。
それでは次にディレクトリごとgitの管理外に設定したいと思います。
$ mkdir log
$ touch log/log1.txt
$ touch log/log2.txt
そしてGitHubにpushします。
$ git add .
$ git commit -m "logを追加"
$ git push origin main
ログがGitHubに追加されました。
しかし思いました。ログを管理する必要はないのでバージョン管理から外したい。
そこでlog
ディレクトリをそのまま管理外にしてみます。
$ git rm --cached log
fatal: not removing 'log' recursively without -r
しかし上手く行きません。ディレクトリの中身も含めてgitの対象外にする場合は-r
をつける必要があります。
$ git rm --cached -r log
rm 'log/log1.txt'
rm 'log/log2.txt'
上手く行きました。では.gitignore
にlog
ディレクトリを設定しておきましょう
secret.txt
log
logディレクトリが薄くグレーアウトしています。これはgitの管理から外れていることを意味しています。
それでは現在の状態をクラウドに反映してlogディレクトリを消しましょう
$ git add .
$ git commit -m "logを削除"
$ git push origin main
GitHubからも消すことができました。
9. 履歴を確認する
時々過去にどんなコミットを行ったのか見たくなることがあります。
私達はこのハンズオンで最初にどんなコミットを行ったか覚えていますか?
そこで利用できるのがgit log
コマンドです。
$ git log
commit 536c9467b8a1781cd7bfd00bc760909841923593 (HEAD -> main, origin/main)
Author: jinwatanabe <jin.watanabe.6g@gmail.com>
Date: Sat Sep 28 18:18:29 2024 +0900
logを消した
commit 607cbb242a63cb32fe2b26ba49b5a607e18d8a12
Author: jinwatanabe <jin.watanabe.6g@gmail.com>
Date: Sat Sep 28 18:14:14 2024 +0900
ログ追加
commit 7c25e8c12330e7e53f6f7ba75d7ebbbc9ecdde7b
Author: jinwatanabe <jin.watanabe.6g@gmail.com>
Date: Sat Sep 28 18:09:44 2024 +0900
秘密のファイルを削除
commit 9f13ec22333fb03aa593ca1582012a40241755d9
Author: jinwatanabe <jin.watanabe.6g@gmail.com>
Date: Sat Sep 28 17:58:01 2024 +0900
色々開発した
このように過去のコミットを一覧で見ることが可能です。(:qで戻ることができます。jで上、kで下を表示します)
詳細を見る場合はgit log -p [コミットID]
でみれます。
$ git log -p 9f13ec22333fb03aa593ca1582012a40241755d9
commit 9f13ec22333fb03aa593ca1582012a40241755d9
Author: jinwatanabe <jin.watanabe.6g@gmail.com>
Date: Sat Sep 28 17:58:01 2024 +0900
色々開発した
diff --git a/index.js b/index.js
index bb8ec33..5e022a9 100644
--- a/index.js
+++ b/index.js
@@ -1 +1 @@
-console.log("Hello Git");
+console.log("change");
diff --git a/secret.txt b/secret.txt
new file mode 100644
index 0000000..ccae75b
--- /dev/null
私はgitコマンドとは別にtig
というライブラリをいれています。
このライブラリを入れてtig
と打つだけで、リポジトリのログを簡単に見ることができるのでおすすめです。
10. コンフリクトの解消
リモートリポジトリに変更を加えられるのは私だけでなくチームのメンバーもできます。
今回はチームのメンバーの誰かが修正をしたとして、GitHubの画面上でコード編集をしてみます。
index1.js
を開いて、右上の鉛筆マークをクリックします
function greet() {
console.log("Hello from the main branch!");
}
このように変更して、右上の緑のボタン「Commit changes...」をクリックします。
Commit messageに「チームの誰かが変更」としてCommit changesボタンを押します。
ここはローカルでgitコマンドを叩いているのと変わりません。
この操作はチームの誰かがやっていると仮定して、私達もindex.js
に修正をしていたとします。
function greet() {
console.log("Hello from the local branch!");
}
それでは私達の修正をリモートリポジトリに反映したいと思います。
$ git add .
$ git commit -m "私達の修正"
$ git push origin main
To github.com:jinwatanabe/git_full_course.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:jinwatanabe/git_full_course.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
git push
でエラーが発生しました。
リモートリポジトリが私達の手元にあるものとバージョンが変わったので、まずはリモートリポジトリの最新バージョンを手元に取得してくれと言われました。
そこでまずはpull
コマンドでリモートリポジトリの最新のコードを手元に持ってきます。
$ git pull -r origin main
From github.com:jinwatanabe/git_full_course
* branch main -> FETCH_HEAD
Auto-merging index.js
CONFLICT (content): Merge conflict in index.js
error: 9e3ead0を適用できませんでした... 私達の修正
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply 9e3ead0... 私達の修正
するとCONFLICT (content): Merge conflict in index.js
という文章が出ました。
これこそがコンフリクトという現象です。VSCodeでindex.js
をみます。
誰かが修正したコードと私が修正したコードがかぶってしまっているために、gitではどちらが正しい修正なのか判断ができずにコンフリクトが発生しました。
この場合手元でコンフリクトの解消をおこな必要があります。
正しいコードを今回は私達のコードの方として、リモートのほうのコードを消しましょう
「Accept Current Change」をクリックすることで私達の修正を採用できます。
それではリモートリポジトリにpushまで行いましょう。
$ git add .
$ git commit -m "修正"
$ git status
interactive rebase in progress; onto 8e508ca
Last command done (1 command done):
pick 34782ce test
No commands remaining.
You are currently editing a commit while rebasing branch 'main' on '8e508ca'.
(use "git commit --amend" to amend the current commit)
(use "git rebase --continue" once you are satisfied with your changes)
nothing to commit, working tree clean
git statusをみるとYou are currently editing a commit while rebasing branch 'main' on '8e508ca'.
とでています。
rebaseに関しては後で説明しますのでここは以下のコマンドでrebaseを終わらせます
$ git rebase --continue
$ git push origin main
無事修正を反映することができました!
11. ブランチを作ってプルリクを作ろう
gitにはブランチという履歴を分岐する機能があります。
これまでにできているmainブランチというのが中心のブランチでそこから派生してブランチを作ることになります。
例えば、コミットCの地点でfeatureブランチ
を作るとします。
ここのブランチで機能Aの開発をしたとします。(コミットD, コミットE)
mainブランチでは別の作業が行われていて、コミットF、コミットGが作られました。
このときfeatureブランチの機能A開発で大きなバグが起きたとします。
しかし、ブランチが別れていればmainブランチに影響は起きません。リリースも問題なくできます。
最終的にはmainブランチに、featureブランチの内容をマージ(合わせる)ことで機能Aをmainブランチに取り込むことが可能です。
それでは実際にブランチを作成してみましょう。
$ git branch
* main
$ git branch -M feature
$ git branch
* feature
これでfeatureブランチをはやして見ているブランチを切り替えることができました
ちなみにmainブランチに戻りたい場合は、git switch main
で可能です。
それではfeatureブランチで追加の開発を行います。
function greet() {
console.log("Hello from the main branch!");
}
greet();
関数を呼び出すようにしてみました。
それではこのブランチの変更をGitHubに反映させましょう
$ git add .
$ git commit -m "関数を呼び出した"
$ git push origin feature
ここでのポイントはpush時にfeatureブランチに対してpushしていることです。
こうすることでmainブランチに影響を与えずに開発ができます。
mainをクリックするとfeatureが表示されるようになりました。
ではこの修正をmainブランチにマージするためにプルリクエストを作ります。
「Compare & pull request」をクリックします。
プルリクエストのタイトルに概要を書きます。ここでは「関数の呼び出しを追加しました」とします。
その下のフォームに実装の詳細などを本来書いておきますが、省略します。
もう一つポイントは、その上にあるmain←featureです。
これはfeatureブランチをmainブランチに取り込むことを表しています。
プルリクを作成するために「Create pull request」をクリックします。
そしたら「Merge pull request」→「Confirm Merge」をクリックします。
もうブランチは不要なので「Delete branch」をクリックして消しておきます。
それでは実際にmainに変更が取り込まれたかを確認します。
$ git switch main
$ git pull -r origin main
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (1/1), 961 bytes | 961.00 KiB/s, done.
From github.com:jinwatanabe/git_full_course
ae5b6e4..b999746 main -> origin/main
Updating ae5b6e4..b999746
Fast-forward
index.js | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
無事反映することができました。
プルリクを活用することで大人数での開発も簡単に行うことが可能です。
またブランチをあえて作らない開発方式も存在しており、それを「トランクベース開発」と呼びます。
12. コミットをなかったことにする
ここでとある問題が発生して、先程マージしたコミットを取り消さないといけなくなりました。
コミットを取り消すものとしてrevertとresetの2つがあります。
revert
リバートは対象のコミットを取り消すコミットを作成することでなかったことにします。
取り消したいコミット自体はちゃんと残り続けるのがポイントです。
実行のコマンドを紹介します。
$ git revert [コミットID]
reset
resetはコミット自体をなかったことにします。履歴が消えてしまうため1度消してしまうと後戻りができません。
$ git reset --hard [コミットID]
前回のコミットを取り消す
取り消し方には2通りありますが、基本的にはrevert
を利用するようにしましょう
まずは適当なコミットを作成します。
function greet() {
console.log("Hello from the main branch!");
}
greet();
greet();
$ git add .
$ git commit -m "不要なコミット"
$ git log
commit 1638301f2d59a47c256f53641064fbfe4454e9d9 (HEAD -> main)
Author: jinwatanabe <jin.watanabe.6g@gmail.com>
Date: Sat Sep 28 19:38:28 2024 +0900
不要なコミット
$ git revert [git logでみた最新のコミットID]
すると、直前のコミットを取り消すコミットのメッセージをどうするかを聞かれるので、
「Ctrl + X」で抜けます。(nanoエディタが開きます)
取り消しのコミットの詳細をみてみると、great()をなくすような変更が確認できます。
コードもしっかり戻っています。
13. マージとリベース
先程マージの挙動を解説しました。
これに似た仕組みにリベースがあります。
このようなブランチの状況だった時に、featureブランチ
でgit rebase main
とすると以下のようになります。
ここでmainブランチとfeatureブランチがコンフリクトを起こした場合は、ステージングに修正を反映させたら、コミットではなくgit rebase --continue
を実行します。
merge
とrebase
の違いは、コミットを作るか作らないかの差があります。
mergeであれば、2つを合わせるためのコミットをわざわざ作成していました。(作成したプルリクにcommitメッセージを書いていたのはそのためです)
git pull -r
というのは、git pull
をして持ってきた最新の情報をrebase
でブランチに取り込むということを表していました。
おわりに
今回は業務でよく使うコマンドから、使う回数は少ないけど必ず利用するコマンドを一通り紹介しました。
この記事をすべて行って理解することができれば仕事は安心して行うことが可能です。
使いながら1回理解しておいて、Gitを使う中で忘れてしまった時にこの記事に戻ってきていただけると良いかなと思います。
より詳細に説明した動画も用意していますのでご覧ください!
ここまで読んでいただけた方はいいねとストックよろしくお願いします。
@Sicut_study をフォローいただけるととてもうれしく思います。
また明日の記事でお会いしましょう!
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページからお気軽にご連絡ください!
▼▼▼