20200714のGitに関する記事は17件です。

Gitコマンド

コマンドでgit使うときによくすること
随時追記

ブランチを最新に

git fetch --prune
git checkout -b temp
git branch -D hoge/fuga
git checkout hoge/fuga
git branch -D temp

ローカルに残ってしまうブランチをきれいに消して最新にチェックアウト
プルと比べると余計なマージがされず安全

プッシュ

git status
git add .
git commit -m "コメント"
git push origin HEAD

プッシュするブランチにいるのをちゃんと確認

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

過去のコミット pushまで

はじめに

gitで過去バージョンに戻ってpushまでの方法です。
詳しい内容までは書けていませんので、ご注意ください、、

バージョンの確認

git log  (qで終了)

対象のバージョンを確認

対象のバージョンに戻る

git reset -—hard commitのID

これで戻れます。

リモートリポジトリにpush

git push -f origin master  

リモートリポジトリを上書きするので1人で開発している時が良いと思います。

★参考
https://qiita.com/ijm/items/8cec0a5653b5e53f7f60

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

Gitってなんだろう??

こんばんは?

今日は、「Git」についてまとめたいと思います。

私が、Gitを学び始めた時に、

「そもそもGitって何ができて、どのように使うのだろう…」と思いました

学ぶ中で得た知識をまとめたいと思います☺︎

:open_mouth:ずばり!Gitとは

”無駄なく効率的にファイルのバージョン管理ができるツール”  

(`・ω・´)プログラマーは多くのコードを編集しますが、不具合が起こると元に戻したりといった作業が日常茶飯事。

それを1つ1つ保存して、また新しくコードを書いて……

そんな時間もなければ、効率が悪すぎる!!!!

       ⇩

  こんな問題がGitを使うと!!!

٩( ᐛ )وコンピュータ上でファイルの編集履歴と管理ができるので、編集前のファイルを残したまま、新しく編集したファイルを保存することができる!
   古いバージョンから新しいバージョンまでの管理が簡単

◉Gitができること

・古いバージョンに簡単に戻せる

・新旧のファイルを管理できる

・編集履歴を複数の人が管理、共有できる

。複数人で修正した内容を1つにまとめることができる

こんなことができるのだなと学びました。
まだ学び始めたばかりなので、間違っていたら教えてくださいm(._.)m

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

Git:リモートリポジトリの指定のブランチをローカルに持ってくるコマンド

実務上で、バックエンドとフロントエンドでリポジトリのブランチが分かれていて、フロント部分との結合テストの際に、ローカルリポジトリ(自分のリポジトリ)にフロントエンドのブランチを持ってきたいと思った時に使ったコマンド。

手順1:リモートブランチをfetch

git fetch (リモート名) (リモートのブランチ名)

※リモート名はgit remote -vで確認→originだった。

例)
git fetch origin develop_front

手順2:ローカルで新しいブランチをを作成

git checkout -b (ローカルで作成する新しいブランチ名) (リモート名)/(リモートのブランチ名)

(リモート名)/(リモートのブランチ名)を調べるためには、git branch -aで調べられる。
→remotes/以降の名前が該当

例)
git checkout -b develop_front origin/develop_front

確認作業

git log

リモートリポジトリの最新のコミットと、ローカルリポジトリの最新のコミットが同じか確認。
※リモートリポジトリはGitHub、GitLabなどでGUIで確認。

もしリモートリポジトリの方が進んでいた場合はgit fetcnとmergeを行う

git fetcn (リモート名) (リモートのブランチ名)
git merge (リモート名)/(リモートのブランチ名)

※mergeする前に、自分が現在いるブランチが、mergeしたいブランチにいるか必ず確認する
→git branch

例)
git fetch origin develop_front
git merge origin/develop_front

以上。

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

Git Reference

SSH認証キーをGitLabに登録・設定手順 覚書

SSH認証キーをGitlabに登録するまでの手順をざっくりまとめました。
随時、更新していきたいと思います。

SSH認証の公開鍵と秘密鍵を作成

ターミナルでssh keyを作成

* アドレス@example.comの部分に自分のメアドを登録
* 途中でパスフレーズ(passphrase)を求められますが、Enterを押すだけ

ターミナルでSSH Keyを作成するコマンド

cd ~/.ssh
ssh-keygen -t rsa -C アドレス@example.com
Generating public/private rsa key pair.
Enter file in which to save the key (/home/.ssh/id_rsa):    ← なにも入力せずに[Enter]
Enter passphrase (empty for no passphrase):    ← 好きなパスワードを入力
Enter same passphrase again:        ← 確認のためにもう一度入力
Your identification has been saved in /home/.ssh/id_rsa.
Your public key has been saved in /home/.ssh/id_rsa.pub.
The key fingerprint is:
e8:ae:60:8f:38:c2:98:1d:6d:84:60:8c:9e:dd:47:81 foo@hoge.com

鍵の生成が完了したら2つのファイルが生成

id_rsa: 秘密鍵、他人には見られないようにする
id_rsa.pub: 公開鍵、Bitbucket/GitHub/GitLabに渡す

※ 秘密の鍵のセキュリティを強化するために以下のコマンドを実行

コマンド

chmod 600 id_rsa

クライアント側へのSSHキーの設定

鍵の管理を簡単にするために、~/.ssh/configに設定を追加

vim ~/.ssh/config

~/.ssh/configのファイル以下を追加

Host gitlab.example.com
  User git
  Port 指定のポート番号
  HostName gitlab.example.com
  TCPKeepAlive yes
  identitiesonly yes
  identityFile ~/.ssh/id_rsa  →key(id_rsa)秘密鍵までのパスを記述

GitLabへ公開鍵の登録

  1. 右上のアイコンをクリック
  2. Edit Profile settingをクリック
  3. SSH Keysをクリック

gitlab01.jpg

フォームのTitleにssh keyの名前をセットして、ターミナルで以下のコマンドを実行。

※タイトルは任意

pbcopy < ~/.ssh/id_rsa.pub

クリップボードにsshキーの中身がコピーされます。

gitlab02.jpg

コマンドでクリップボードに保存したKeyをKey入力枠へペースト

Add Keyを押して、GitLabへの登録は完了になります。

Branch削除したいときあるよね

git branch -d [ブランチ名]

マージ済みのブランチのみ削除ができる
マージされていないブランチを削除しようとすると下記のようなエラーがでます
error: Cannot delete the branch 'ブランチ名' which you are currently on)
マージされていないブランチを削除したいときは以下のコマンドを

git branch -D [ブランチ名]

どんなローカルブランチも削除できる

diffはファイル名だけにしたいよね

git diff 比較ブランチ名 --name-only

特定のコミットに戻りたいときあるよね

git reset --hard HEAD@{N}

もうそのままremote のmasterの情報に変えたいときあるよね

git reset --hard origin/master

.gitignore の設定を反映させる

すでにリポジトリにignoreファイルを追加していると、
キャッシュが残っており.gitignoreファイルの内容が反映されない。
.gitignore

git rm -r --cached .
git add .
git commit -m ".gitignore is now working"
git push origin master

コミットの取り消し

git reset HEAD

Addのログ表示

add だけしていた人は反省してちゃんとvorboseつけよう
git add . -v

commitしてある場合は
git pull origin master
してから
git push origin master
commitしていない場合は
git push origin master

ここから下はメモ

初回のコミットを取り消したいときにはgit update-refを使う

git update-ref -d HEAD

addしたあとcommit前に差分を確認する方法

git diff --cached ファイル名

さらにaddしたものをキャンセルする場合は

git reset HEAD ファイル名

いまのブランチのすべてのコミット歴史を表示

git reflog

リモートの master 参照を強制に戻す

$ git push -f origin master

branch delete

git push --delete origin branch_name

cleanup

git filter-branch --index-filter 'git rm --cached --ignore-unmatch Binaries/*' HEAD
git push origin master --force

stashについて

git stashの基本

stashコマンドは変更を一時的にしまっておけるコマンド。

$ git stash # 変更をスタックにプッシュする
$ git stash list # スタックにある変更を一覧表示する
$ git stash drop # スタックの一番上にある変更を削除する
$ git stash pop # スタックから変更を一つポップする

スタックにある変更差分を確認したい時

git stash listでstash@{N}の番号を確認する。

$ git stash list
stash@{0}: WIP on branch_name: commit_id2 commit_comment2
stash@{1}: WIP on branch_name: commit_id1 commit_comment1

中身を見たい番号を指定して、以下のコマンドでHEADとの差分を確認できる。

$ git diff stash@{0}

ファイル指定もできる。

$ git diff stash@{0} hoge.txt

ALLOW MERGE UNRELATED HISTORIES

git merge --allow-unrelated-histories origin/master

最後に

様々なサイトを参考にさせていただきました。
ありがとうございます!

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

チーム開発のためのGit入門 (7) コンフリクト 後編

HEADとは

後編ではtax.rbで起きたコンフリクトを解消していきます。
コンフリクトが起きたtax.rbを見てみましょう。

tax.rb
tax = {
    'jp' => 0.1,
<<<<<<< HEAD
    'fr' => 0.2,
=======
    'dk' => 0.25,
>>>>>>> master
}

zeinuki = 1000
price = zeinuki + zeinuki * tax['jp']

書いた覚えのない<<<===>>>の文字でコードが区切られています。

細かい説明はさておき、簡単な覚え方を説明します。

上にあるのが自分が行った修正、下にあるのが別の人が行った修正です。

上の部分が自分で追記したもので、

tax.rb
<<<<<<< HEAD
    'fr' => 0.2,
=======

下の部分は別の人が追記したものです。
denmarkブランチの作業は別の人が行った想定です。

tax.rb
=======
    'dk' => 0.25,
>>>>>>> master

右にHEADmasterと書かれており、おそらくブランチ名のことだろうと推測はできます。

しかしmasterは分かりますが、HEADというブランチは作った覚えがありません。
このHEADというのは端的にいうとカレントブランチのことを意味します。
つまりはfranceブランチです。
HEADは厳密にはカレントブランチの先頭(最新)を意味しますが、最新のカレントブランチにmasterをマージしようとしているわけですから、カレントブランチとほぼ同義と言えます。

コンフリクトの解消

コンフリクトが起きていた箇所はGitからするとこのような状況です。

HEAD(franceブランチ)では'fr' => 0.2,で、masterブランチでは'dk' => 0.25,なのでどちらが正しいか分かりません。

Gitがお手上げ状態になっているわけです。

tax.rb
<<<<<<< HEAD
    'fr' => 0.2,
=======
    'dk' => 0.25,
>>>>>>> master

Gitがお手上げなら、こちら側で正しいコードはこうだよと伝えれば良いのです。
これがコンフリクトの解消になります。

そしてコンフリクトの解消のコツは、自分が行った編集と別の人が行った編集を統合して完成させるイメージを持つことです。

最初にやるべきは、別の人が行った編集の目的を考えることです。
つまりは'dk' => 0.25,を追加した目的です。

この時にデンマークの消費税率を追加するという課題があることを自分が知っていればそれを実行したんだなと思うだけですが、別の人の課題なので知らない場合もあります。

実際のチーム開発では全ての課題を把握しているとは限りませんので、このような時はコードから意図を汲み取ることが大事になってきます。

もちろんこれだけでは全体として何がしたいのかは分かりませんが、日本とフランスとデンマークの消費税率が必要になることくらいは分かります。
意味もなくデンマークの税率を追加するとは考えられません。

ですのでコンフリクトが起きたこの箇所を

tax.rb
tax = {
    'jp' => 0.1,
<<<<<<< HEAD
    'fr' => 0.2,
=======
    'dk' => 0.25,
>>>>>>> master
}

統合して完成させるとしたら、下記のようにすれば良いのではないでしょうか。

tax.rb
tax = {
    'jp' => 0.1,
    'fr' => 0.2,
    'dk' => 0.25,
}

これなら自分が行った編集と別の人が行った編集が統合されています。

そうとわかれば、tax.rbにある<<<<<<< HEADのような区切りを消して、tax.rbを完成させましょう。

tax.rb
tax = {
    'jp' => 0.1,
    'fr' => 0.2,
    'dk' => 0.25,
}

zeinuki = 1000
price = zeinuki + zeinuki * tax['jp']

これでコンフリクトは解消されました。

結果的には<<<<<<<=======>>>>>>>を消しただけですが、コンフリクトの解消のイメージはつかめたと思います。

後はコミットすれば完了です。

$ git add .
$ git commit -m "コンフリクトを解消"

これで最新のmasterのマージが完了したことになります。

コンフリクト発生のおさらい

流れをおさらいしましょう。

フランスの消費税率を追加するためにfranceブランチを作って、tax.rbに'fr' => 0.2,を追記する。
masterに変更があるかもしれないので、最新のmasterをマージしようとする。
しかしtax.rbでコンフリクトが起きたので解消してくださいとGitに警告される。
tax.rbのコンフリクトを解消することでマージを完了させる。

ここまできたら、あとはmasterブランチにfranceブランチをマージするだけです。
そうすればこの課題は完了します。

$ git checkout master
$ git merge france

これで2つの課題を別々の人が行ってmasterにマージすることができました。

コンフリクトの再現 part2

もうひとつ例を出してコンフリクトの解消に慣れていきましょう。
少し難易度を上げます。

また新しく2つの課題を用意します。
・税込価格の計算の記述をシンプルにする
・税込価格はデンマークの税率で計算する

同じようにこれを別々の人が担当することにします。

自分が担当するのは、税込価格の計算の記述をシンプルにするという課題です。

課題ごとにブランチを作るのが基本なので、simple-calcというブランチを作ります。

$ git checkout -b simple-calc
Switched to a new branch 'simple-calc'

課題の中身についてですが、計算するときにzeinukiを2回使っています。

tax.rb
# ...(略)
price = zeinuki + zeinuki * tax['jp']

これを一回で済むように修正します。

tax.rb
# ...(略)
price = zeinuki * (1 + tax['jp'])

これなら計算結果は変わらず、zeinukiを1回使うだけで済みました。
少しはシンプルになったと言えるでしょう。

修正はこれだけなのでコミットします。

$ git add .
$ git commit -m "税抜き価格の計算をシンプルにする"

続いてもう一方の課題を行います。

ここからはまた別の人が行っていると想定してください。

いったんmasterに戻って、税込価格はデンマークの税率で計算するためにdenmark-rateブランチを作成します。

$ git checkout master
$ git checkout -b denmark-rate
Switched to a new branch 'denmark-rate'

masterからブランチを作ったので、価格計算はこのようになっています。

tax.rb
# ...(略)
price = zeinuki + zeinuki * tax['jp']

デンマークの税率を使うにはtax['jp']tax['dk']に変えるだけでOKです。

tax.rb
# ...(略)
price = zeinuki + zeinuki * tax['dk']

修正は完了したのでコミットします。

$ git add .
$ git commit -m "デンマークの税率を使用"

これをmasterにマージしていきます。
ただしmasterに変更がある可能性があるので、いったん最新のmasterをカレントブランチにマージすることがルールでした。

$ git merge master
Already up to date.

denmark-rateブランチが作成されてからmasterは何も変更されていないので、こういうときは何も起こりません。

コンフリクトは起きなかったので普通にmasterにマージします。

$ git checkout master
$ git merge denmark-rate

これでデンマークの税率を使用するという課題を別の人が完了させました。

ここからはまた自分が行う作業です。

simple-calcブランチに切り替えます。

$ git checkout simple-calc

simple-calcブランチでは価格計算をシンプルにしてコミットするところまでは終わりました。
価格計算はこのように記述されています。

tax.rb
# ...(略)
price = zeinuki * (1 + tax['jp'])

ルール通り、masterにマージする前に最新のmasterを取り込む必要があります。
実際に別の人が税率をデンマークに変更しているので、masterはsimple-calcブランチ作成時から更新されています。

$ git merge master
Auto-merging tax.rb
CONFLICT (content): Merge conflict in tax.rb
Automatic merge failed; fix conflicts and then commit the result.

コンフリクトが発生しました!

コンフリクトの解消 part2

コンフリクトが起きた箇所を見てみましょう。

tax.rb
# ...(略)
<<<<<<< HEAD
price = zeinuki * (1 + tax['jp'])
=======
price = zeinuki + zeinuki * tax['dk']
>>>>>>> master

説明した通りHEADはカレントブランチのことで、自分が編集した部分になります。
下のmasterの方は別の人が編集した内容です。

これを解消したいのですが、先ほどのようにどちらも残してしまうと、おかしなコードになってしまいます。

tax.rb
# ...(略)
price = zeinuki * (1 + tax['jp'])
price = zeinuki + zeinuki * tax['dk']

価格を2回計算しているし、計算結果も違います。

これを解消するのに思い出して欲しいのがコンフリクト解消のイメージです。

自分が行った編集と別の人が行った編集を統合して完成させる

自分が行った編集は計算の記述をシンプルにするだけで、計算結果には影響が及びません。
一方、別の人が行った編集は使用する税率を日本からデンマークに変更しています。

コンフリクト解消のイメージ通り、両者の編集を統合するためにはこう考えれば良いのではないでしょうか。

使用する税率はデンマークで、記述はシンプルにする。

これを踏まえれば、価格を計算するコードはこのようにするのが正しいと分かるでしょう。

tax.rb
price = zeinuki * (1 + tax['dk'])

これなら、価格はデンマークの税率で計算されているし、記述もシンプルです。

修正の手順はHEADの中のtax['jp']tax['dk']に変えて、その他は削除すればOKです。

tax.rb
tax = {
    'jp' => 0.1,
    'fr' => 0.2,
    'dk' => 0.25,
}

zeinuki = 1000

price = zeinuki * (1 + tax['dk'])

これでコンフリクトが解消ができました。

コンフリクトの原因は様々ですので、解消の仕方もそれぞれのケースに応じた対処が必要になります。
しかし両者の編集を統合して完成させるという認識があれば自ずとどう対処すれば良いかは分かってくるものです。
コンフリクト解消のイメージを忘れないようにしてください。

コミットして最新のmasterのマージを完了します。

$ git add .
$ git commit -m "コンフリクトを解消"

masterに切り替えてsimple-calcをマージすれば課題は完了です。

$ git checkout master
$ git merge simple-calc

これで2つの課題が完了されました。

コンフリクト解消もひと段落したので終わりにしたいところですが、一つ小話を。

勘の良い方なら気づくかもしれませんが、最後にmasterでgit merge simple-calcした時にはなぜコンフリクトが起きないのでしょうか。
masterとsimple-calcで価格計算の記述が違うわけですから、コンフリクトが起こりそうなものです。

これは細かく説明するとややこしくなるので、感覚的に説明させてください。

masterの視点に立って考えます。
simple-calcは最新のmasterをマージしています。
ですのでmasterからすればsimple-calcは信頼できるブランチと言えます。
simple-calcは最新のmasterの内容を取り込んでくれて、その上で新たな編集をしてくれたブランチだとmasterは判断しているのです。
つまりはmasterとsimple-calcで違う記述があれば、simple-calcの記述を採用することができます。

あくまで信頼というのは例えですが、この辺の管理はGitがうまいことやってくれているので、慣れるまでは深く追求する必要はないと思います。

まとめ

前編と後編に分けてコンフリクトについて解説しました。
コンフリクトはチーム開発で起こる厄介な問題の一つなので、発生のメカニズムと解消のイメージをしっかりと理解しましょう。

実際にチーム開発ではGitHubを使って連携していきますので、今後はそちらの解説記事も上げていこうと思います。

ここまで読んでくださりありがとうございました。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

チーム開発のためのGit入門 (6) コンフリクト 前編

コンフリクトについて

これから前編、後編に分けてコンフリクトについて解説していきます。
Gitでチーム開発をする上でコンフリクトは避けては通れない問題なので、必ず理解するようにしましょう。

※連載記事ですが、この章からコンフリクトだけを学習することも可能です。

前編では4つのポイントに分けて説明します。
・コンフリクトとは
・なぜ起きるのか
・いつ起こるのか
・コンフリクトを再現

コンフリクトとは

コンフリクトとはファイルのある箇所がブランチによって異なるので、マージ(結合)ができない状態のことです。
直訳すると競合を意味する言葉です。

具体例で示すとこのような状況です。
誕生日が書かれているbirthday.txtがあったとして、2行目がAブランチではこうなっていて、

birthday.txt
私の誕生日は
3月3日です

Bブランチではこうなっている。

birthday.txt
私の誕生日は
7月7日です

birthday.txtの2行目がどちらが正しいのか分からないので、マージ(結合)できない。
このような状態をコンフリクトが起きていると言います。

なぜ起きるのか

異なるブランチで、同じファイルの同じ行を修正したことが原因で起こります。
この例ではAさんがAブランチでbirthday.txtの2行目を3月3日と編集し、BさんがBブランチで7月7日と編集してしまったのです。

いつ起きるのか

マージしようとした時です。
上記の例で言うとbirthday.txtの2行目が異なっている状態で、AブランチにBブランチをマージしようとした時に起こります。
(BブランチにAブランチをマージしようとした時も同様です)

コンフリクトを再現

概念だけでは分かりづらいですので、コンフリクトを意図的に起こしてみます。

まずコンフリクトを起こすファイルを用意します。
税込価格を計算をするtax.rbを作りましょう。
Rubyファイルを例に使いますが、Rubyの経験は必要ありませんし、Rubyが実行できない環境でも全く問題ありません。

基本的にmasterでは作業はしないので、ちょっと面倒ですがtax.rbを作るためにtaxブランチを作ります。

$ git checkout master
$ git checkout -b tax

ファイルを作ります。

$ touch tax.rb

作成したtax.rbにこのように記載してください。

tax.rb
tax = {
    'jp' => 0.1,
}

zeinuki = 1000
price = zeinuki + zeinuki * tax['jp']

Rubyの知識はなくても理解できる内容だと思います。

一応説明すると、taxにjpというkeyで日本の消費税率が格納されています。
zeinukiに税抜き価格を代入し、次の行で税込価格を計算しています。
出力はしていませんがpriceは1100になリます。

これをコミットして、masterにマージします。

$ git add .
$ git commit -m "税込価格の計算"
$ git checkout master
$ git merge tax

これでmasterブランチにtax.rbができたので、この状態からスタートします。

ちょっと唐突ですが、ここで2つの課題があるとします。
・tax.rbのtaxにフランスの消費税率を追加する
・tax.rbのtaxにデンマークの消費税率を追加する

そしてこの2つの課題をそれぞれ別の人が別のブランチで作業することになったとします。
自分はフランスを担当して、別の人がデンマークを担当することにして進めていきます。

課題自体は難しくないので、さっそく取り掛かりましょう。
franceブランチを作って、そこでフランスの消費税率を追加します。

$ git checkout -b france

課題としてはtax.rbの3行目に'fr' => 0.2,を追加すればOKです。
フランスは20%らしいです。

tax.rb
tax = {
    'jp' => 0.1,
    'fr' => 0.2,
}
...()

コミットします。

$ git add .
$ git commit -m "フランスの消費税率を追加"

修正はこれで完了です。
これをmasterにマージすれば、この課題は完了です。

しかし、ここで別の人がデンマークの消費税率を追加する課題を行い、自分より先にmasterにマージした場合を想定してみます。
チーム開発では十分起こりうることです。

それを再現したいので、ここからは別の人が作業している仮定で進めてください。

$ git checkout master
$ git checkout -b denmark

当然、denmarkブランチではフランスの消費税率は記載されていませんので、tax.rbの3行目にデンマークの消費税率を追加することになります。

tax.rb
tax = {
    'jp' => 0.1,
    'dk' => 0.25,
}
...()

ここで同じファイルの同じ行を異なるブランチで修正する状況が生まれます。

$ git add .
$ git commit -m "デンマークの消費税率を追加"

今の状況を整理します。
フランスの税率がfranceブランチで追記されていて、デンマークの税率がdenmarkブランチで追記されている。
そしてどちらもmasterにはマージされていません。

2つの課題は平行して行われているので、どちらが先に終わるかは分かりません。
今回はdenmarkブランチで作業をしていた別の人が自分よりも作業が早かったため、先にmasterにマージすることになったとしましょう。

$ git checkout master
$ git merge denmark

これは今まで通りマージができます。

ここからはまた自分の作業になります。

続いて自分が行ったfranceブランチの修正もmasterにマージしたいのですが、一つ問題があります。
それはブランチを作った時とマージする時でmasterブランチの状態が変わっていることです。
今までのマージはブランチを作った時とマージする時でmasterの状態は同じでした。

今までの流れを図にするとこのようになります。

flow_1d.png

denmarkブランチは上図のB地点で作られ、C地点でマージされています。
B地点とC地点の間でmasterブランチには何も変更はありません。

一方、franceブランチはA地点で作られ、D地点でこれからマージしようとしています。
A地点とD地点の間でdenmarkブランチがマージされているので、masterブランチには変更が加わっています。
具体的にはtax.rbの3行目に'dk' => 0.25,が追記されました。

ここでいったん自分が担当することになった課題を確認します。
・tax.rbのtaxにフランスの消費税率を追加する

課題自体は単純ですが、チーム開発では最新のmasterブランチに対してフランスの消費税率を追加するという暗黙の前提が存在します。

今のfranceブランチはブランチを作ったA地点のmasterに対してフランスの消費税率を追加しています。
ですからこの状態でmasterにマージするのは好ましくないのです。

それを解決するためには、D地点のmasterブランチをfranceブランチにマージする必要があります。
D地点のmasterブランチに対しての差分だけを抽出するようなイメージを持てば、今やろうとしていることの意味が掴めるかもしれません。

ややこしい説明に感じると思いますが、Gitに慣れていくうちに自然なことだと理解できますので、とりあえず進めていきます。

最新のmasterを取り込むために、franceブランチに移動して、masterをマージします。

$ git checkout france
$ git merge master
Auto-merging tax.rb
CONFLICT (content): Merge conflict in tax.rb
Automatic merge failed; fix conflicts and then commit the result.

ついにコンフリクトが起きました。
出力からもそのことが感じとれます。

出力内容はさっくり訳せばこのような意味です。
「マージしようとしたけどtax.rbにコンフリクトがあるので完了できません。コンフリクトを解消してください。」

ではそのtax.rbを見てみましょう。

tax.rb
tax = {
    'jp' => 0.1,
<<<<<<< HEAD
    'fr' => 0.2,
=======
    'dk' => 0.25,
>>>>>>> master
}

zeinuki = 1000
price = zeinuki + zeinuki * tax['jp']

わけの分からない区切り文字が勝手に追記されています。
初めてこれを見たときは戸惑うかと思いますが、コンフリクトが起きるとこんな風になってしまうのです。

起きた現象を理解するために、この章の冒頭で述べたコンフリクトはなぜ起きるのか、そしていつ起きるのかをおさらいします。

なぜ起きたのかについては、franceブランチとmasterブランチでtax.rbの3行目が違うことが原因です。
franceブランチでは'fr' => 0.2,と書かれており、masterブランチでは'dk' => 0.25,と書かれています。
tax.rbの3行目がどちらが正しいのか分からずマージできませんとGitに警告されてしまったわけです。

いつ起きたのかについては、もちろんマージしようとした時です。

起きるタイミングは重要なので、もう一度この図を使って経緯をおさらいします。

flow_1d.png

franceブランチはA地点で作られました。
フランスの税率を追加する作業が終わってD地点でマージしようとしたけど、その間にmasterブランチにはデンマークの税率が追記されてしまいました。
あくまでD地点のmasterブランチにフランスの税率を追記したいので、franceブランチはD地点のmasterをマージしようとしました。
しかしtax.rbの3行目が違っていたためコンフリクトが起きてしまった。

この経緯を理解することはとても重要です。
なぜならチーム開発で起こるコンフリクトはほとんどがこのようなケースだからです。

まとめ

チーム開発ではたくさんの課題を複数人で取り組んでいます。
自分がある課題に取り組むためにmasterブランチから新しいブランチを作り、ファイルを編集する。
その間に別の人が行っていた課題が完了し、masterブランチにマージされる。
自分は最新のmasterに対して変更を加えたいので、作ったブランチに最新のmasterをマージする。
この時、自分が修正したファイルの同じ行を別の人が修正していたためコンフリクトが起こる。

開発中はこんなことが多々起こります。

コンフリクトでつまづくと軽いパニックになってしまうので、原理をきちんと理解しましょう。
コンフリクトの解消は次章で解説します。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

チーム開発のためのGit入門 (5) .gitignoreとは

.gitignore

この章ではGitでバージョン管理する上で特殊なファイルである.gitignoreについて解説します。

たいていの場合.gitignoreは必要になるので、まずは作りましょう。
先頭に.があったり、拡張子がなかったりとしっくりこないファイル名かもしれませんが、こういったファイルも作成可能です。

作業するブランチは前回と同じくhalcブランチを使います。

$ git checkout halc

touch ファイル名で作成できます。

$ touch .gitignore

復習も兼ねてgit statusで確認します。

$ git status
...(略)
  .gitignore
...(略)

これで.gitignoreが作成されていることが分かります。

.gitignoreというのはGitのバージョン管理から除外したいファイルまたはディレクトリを定義するためのものです。

ignoreは無視するという意味なので、ここに記載されているファイルやディレクトリはGitが無視しますと解釈できます。

試しにsecret.txtというファイルを作ります。

$ touch secret.txt

適当に文章を記載します。

secret.txt
.gitignoreを学習

それからgit statusをしてみてください。

$ git status
...(略)
  .gitignore
  secret.txt
...(略)

当然、作ったファイルは表示されます。

しかし、このsecret.txtを何らかの理由でGitのバージョン管理から除外したいとします。

こういう時は.gitignoreにファイル名を書けば実現できます。
.gitignoreにこのように記載してみてください。

secret.txt

今度はどうでしょうか。

$ git status
...(略)
  .gitignore
...(略)

secret.txtが表示されなくなりました。

Gitは.gitignoreというファイルがあれば、そこに記載されているファイルはバージョン管理から除外してくれるわけです。

もちろんディレクトリごと除外することもできます。
確認のためにexclusionというディレクトリを作って、その中にhidden.txtを作ります。

$ mkdir exclusion
$ touch exclusion/hidden.txt
$ git status
...(略)
  .gitignore
  exclusion/
...(略)

exclusionを.gitignoreに追記します。

secret.txt
exclusion

これでexclusionは除外されます。

$ git status
...(略)
  .gitignore
...(略)

ファイル単体での除外もできるし、あるディレクトリ下の全てのファイルを除外対象にすることもできるわけです。

ではこれをmasterにマージしましょう。

$ git add .
$ git commit -m ".gitignoreを作成"
$ git checkout master
$ git merge halc

.gitignoreの用途

.gitignoreの仕組みは分かっていただけたと思うので、用途についても説明します。

用途は主にこの3パターンです。

・環境特有の設定ファイル
・各環境で行う操作によって生まれるファイル(ログやキャッシュなど)
・ライブラリ

アプリケーション開発では、それぞれの環境で独自に設定したい定数のようなものがあります。
その定数が記載されたファイルは環境によって異なるため、全員で共有することはしません。
そういった理由から設定ファイルはGitの管理から除外します。

ログやキャッシュなどの各環境で行う操作によって生まれるファイルは、開発中の副産物のようなものですので、そもそも共有する意味はありません。

ライブラリに関しては、基本的には全員が同じファイルを持つことになるので、共有したらダメというわけではありません。
しかしライブラリはファイル数が膨大なので、共有するには不都合が多すぎます。
その代わりに必要なライブラリを記載したファイルを用意して、それを共有します。
あとはそのファイルに沿って、それぞれの環境でダウンロードしてくださいといった方式を取ります。

まとめ

.gitignoreは頻繁に編集するファイルではないので、仕組みがわかっていれば特に問題になることはないでしょう。
RailsやLaravelなどのフレームワークを導入すると、最初から.gitignoreが作られているので一度中身を覗いてみることをお勧めします。

次章からはチーム開発で大きな課題となるコンフリクトについて解説していきます。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

チーム開発のためのGit入門 (4) git checkoutの別の使い方

git checkoutの別の使い方

この章ではgit checkoutのもう一つの使い方を解説します。

git checkout ブランチ名でブランチ切り替えができますが、実はgit checkoutにはもう一つの使い方があります。

それは修正したファイルを元に戻す機能です。
git checkout ファイル名でそれが可能です。

それでは確認していきましょう。
作業はhalcブランチで行います。

$ git checkout halc

このcheckoutはブランチ切り替えです。

ファイルの内容を変更したいのでsummary.txtに記述を追加します。

summary.txt
git statusは修正したファイルが表示される。
git diffは修正した内容が表示される。
git checkoutはブランチ切り替えだけではない。

git statusで修正したことが分かります。

$ git status
...(略)
  modified:   summary.txt
...(略)

ではここで、このコマンドを打ってください。

$ git checkout summary.txt
summary.txt
git statusは修正したファイルが表示される。
git diffは修正した内容が表示される。

summary.txtが元に戻りました。

何とも不思議ですが、git checkoutにはこのような使い方があるのです。
正直、別のコマンドがあった方が分かりやすいのですが仕方ありません。
そういうものだと覚えましょう。

ファイルだけでなく、ディレクトリごと元に戻すこともできます。
git checkout ディレクトリ

全てのファイルを元に戻したい時は.をつければできます。
git checkout .
git add .でも説明しましたが、.には全てのという意味があります。

色々とファイルを編集したけど、結局元に戻したいという時に使えるコマンドです。

git help

Gitにはたくさんコマンドがあるので、その一覧を見れるコマンドも紹介します。
git helpにオプションの-aで全てのコマンドを確認できます。

$ git help -a

おそらくターミナルからはみ出すので、十字キーの↓でスクロールできます。
あまりにも多いので面食らうかもしれませんが、ほとんどは使いませんので心配いりません。
最後までスクロールするのが面倒な時はqをタイプすれば抜けられます。

git helpで表示されるcheckoutの説明を見ると、2つの用途があることが確認できます。
Switch branches or restore working tree files

Switch branchesがブランチ切り替えで、restore working tree filesがファイルを元に戻すことを指しています。

ワーキングツリーやインデックスといった用語はGitを学習される中で聞いたことがあるかもしれません。
これらは必ず理解しなければならないものではありません。
Gitは奥が深いのでエンジニアですら表面的な理解で使っていることも珍しくありません。
これは必ずしも悪いわけではなく、裏側の処理を理解しなくても使えることが優れたツールの証でもあります。

深入りするより使いこなすことが先決ですので、一通り学習した後に興味があれば内部の仕組みを学ぶことをお勧めします。

まとめ

この章ではgit checkoutでファイルを元に戻す方法を解説しました。

使う場面としては先述したように、色々と編集した後に最初からやり直したいと思った時です。
それ以外でたまにあるのが、間違ったブランチで作業してしまった時です。

ブランチを作るのを忘れてmasterで作業してしまったとか、前の課題のブランチをそのまま使っていたとかはやりがちです。
十分気をつけましょう。

次章ではGitのバージョン管理から除外するファイルを定義できる.gitignoreについて解説します。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

チーム開発のためのGit入門 (3) git statusとgit diff

2つの定番のGitコマンド

この章では開発中によく使うgit statusgit diffを説明していきます。
この2つはおそらくGitで一番使うコマンドでしょう。

どちらも目的は同じで、どんな修正をしたのかを表示してくれるコマンドです。

作業用ブランチを作成

これを学習するためにhalcという名前のブランチを作成します。
前回と同じようにgit branch halcでもブランチを作成できますが、もっと便利なコマンドがあります。
せっかくなのでそちらを使いたい思います。

ブランチを作ったら大体はそのブランチに移動するので、こちらの方がよく使われます。
git checkout -b ブランチ名
これでブランチを作って、そのブランチに切り替えることができます。

masterブランチから作成しますので、カレントブランチがmasterになっていなければブランチを切り替えてください。

$ git checkout master

halcブランチを作って、halcブランチに移動します。

$ git checkout -b halc
Switched to a new branch 'halc'
$ git branch
* halc
  master
  pablo

カレントブランチが新しく作ったhalcブランチに切り替わりました
ちなみにブランチ一覧は作った順ではなく、アルファベット順で表示されます。

git status

git statusは変更したファイルが表示されるコマンドです。
statusというからには状態を示してくれそうです。
何はともあれコマンドを打ってみます。

$ git status
On branch halc
nothing to commit, working tree clean

何やら出力されましたが、nothingやcleanという単語が出てきたことから分かるように何も変更はされていないことを示しています。

何か変更を加えたいので、explain.txtにgit checkout -b ブランチ名の説明を追記します。

explain.txt
Gitとはソースコードのバージョン管理システムである。
git branch # ブランチ一覧を表示
git branch ブランチ名 # ブランチを作成
git checkout ブランチ名 # ブランチ切り替え
git checkout -b ブランチ名 # ブランチを作成して切り替え

次はどうでしょうか。

$ git status
...略
  modified:   explain.txt
...略

先ほどと違いファイル名が表示されました。
modifiedは「修正された」という意味ですので、explain.txtが修正されたことを表しています。

このようにgit statusは編集したファイルを表示してくれますので、確認するためによく使います。

git diff

続いてgit diffについて説明します。
git diffは差分を表示するコマンドです。
diffはdifferenceの略です。

実際にコマンド打って確認してみましょう。

$ git diff
...(略)
 git checkout ブランチ名 # ブランチ切り替え
+git checkout -b ブランチ名 # ブランチを作成して切り替え

修正した内容が表示されているのが分かります。
どこを修正したのかが分かるように、追加した行の上の数行もあわせて出力してくれます。
左の+は追加されたという意味です。

察しがつくと思いますが、削除した場合は-になります。
確認のために、explain.txtのこの2行を削除しましょう。

explain.txt
...(略)
git branch ブランチ名 # ブランチを作成
git checkout ブランチ名 # ブランチ切り替え
...(略)

このようになります。

$ git diff
...(略)
-git branch ブランチ名 # ブランチを作成
-git checkout ブランチ名 # ブランチ切り替え
+git checkout -b ブランチ名 # ブランチを作成して切り替え

git diffは修正した部分だけを表示してくれますので非常に便利です。

たくさん編集した場合はターミナルからはみ出してしまうので、十字キーの↓でスクロールすれば確認できます。
途中で抜けたい時はqをタイプして終わりにできます。

git statusとgit diffの使い分け

両者のコマンドを比べると、ファイルだけでなく編集内容も出力してくれるgit diffの方が良さそうに見えますが、そんなこともありません。
編集内容が多くなってくるとgit diffでは、出力される行数が多すぎて使いづらいこともあります。
そんな時は変更したファイルだけが表示されるgit statusが便利です。

それともう一つ大きな違いがあります。
それは新たにファイルを作成した時です。

touchコマンドでsummary.txtを作成します。

$ touch summary.txt

軽く文章を書きます。

summary.txt
git statusは修正したファイルが表示される。
git diffは修正した内容が表示される。

summary.txtを作ってから、git statusすると

$ git status
...(略)
  modified:   explain.txt
...(略)
  summary.txt
...(略)

summary.txtが作成されたことが表示されています。

git diffはというと

$ git diff
...(略)
-git branch ブランチ名 # ブランチを作成
-git checkout ブランチ名 # ブランチ切り替え
+git checkout -b ブランチ名 # ブランチを作成して切り替え

summary.txtを作成する前と変わりません。

git diffは新しいファイルに関しては表示してくれないのです。
削除した時も同様です。

編集内容をマージ

git statusgit diffの違いがわかったところで、halcブランチで行った修正をmasterブランチにマージしましょう。

まずはaddとcommitをします。

$ git add .
$ git commit -m "summary.txtにgit statusとgit diffの違いを記載"

そしてカレントブランチがmasterの状態でgit merge halcをすればOKです。

$ git checkout master
$ git merge halc

これでmasterブランチにexplain.txtの変更とsummary.txtが取り込まれました。

まとめ

この章では開発中によく使う2つのGitコマンドを解説しました。
このコマンドを使うことで関係ないファイルを変更してしまったり、仮で記載していた内容をそのままコミットしてしまうのを防ぐことができます。

コミットする前にはgit statusgit diffで修正した内容を確認する習慣をつけましょう。

次章はgit checkoutの別の使い方を解説します。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

チーム開発のためのGit入門 (2) ブランチ作成してマージ

ブランチ作成

前章でGitでバージョン管理する準備が整いました。
explain.txtを作りコミットしたことで、自動でmasterブランチが作成されました。

現状はブランチはmasterしかありません。

$ git branch
* master

masterブランチが作成された後は、手動でブランチを作ることができます。

早速ブランチを作りましょう。
ブランチ名は自由に決めて良いので、pabloという名前のブランチを作ります。
git branch ブランチ名で作成が可能です。

$ git branch pablo

ブランチ一覧を表示します。

$ git branch
* master
  pablo

pabloブランチが作成されました。
masterにだけ左に*があることに気づいたかもしれませんが、これは今いるブランチのことを表しています。
これをカレントブランチと呼びます。
当然バージョン管理するわけですから色んなブランチを作成します。
その時に今どのブランチにいるのかは、この*で確認すればいいわけです。

ブランチ切り替え

ここで今までのブランチの流れをおさらいしましょう。

masterブランチが作成されるカレントブランチはmasterpabloブランチを作成するカレントブランチはmasterのまま

お分かりのようにブランチを作っただけでは、カレントブランチは変わりません。
ブランチを切り替える時はgit checkout ブランチ名を使います。

$ git checkout pablo
Switched to branch 'pablo'

カレントブランチを確認しましょう。

$ git branch
  master
* pablo

ブランチが切り替わりました。

ここでブランチの関係性について解説します。
先ほど、カレントブランチがmasterの状態でpabloブランチを作成しました。
masterブランチとpabloブランチの違いは何でしょうか?

結論を言うと違いはありません。

explain.txtを見ればわかるように、何も違いはないです。

explain.txt
Gitとはソースコードのバージョン管理システムである。

ブランチを作成すると、その時のカレントブランチと同じ状態のブランチが作られるということです。
pabloブランチの派生元ブランチはmasterであると言ったりもします。

派生元ブランチという考え方は重要なので理解しておきましょう。
どのブランチから作られたのかを言っているだけなので難しく考える必要はありません。

せっかくpabloブランチを作ったので、explain.txtにgitコマンドの説明を追記しましょう。

explain.txt
Gitとはソースコードのバージョン管理システムである。
git branch # ブランチ一覧を表示
git branch ブランチ名 # ブランチを作成
git checkout ブランチ名 # ブランチ切り替え

ファイルを保存したら、前回と同じようにGitにコミット(保存)します。
Gitにコミットするにはaddとcommitです。

$ git add .
$ git commit -m "ブランチ表示、作成、切り替えのコマンドを追記"
... 略
1 file changed, 3 insertions(+)

これでexplain.txtにgitコマンドの説明が追記されてことをGitが保存しました。
しかしこれはあくまでpabloブランチで行ったものだということを忘れないでください。
それを確認するために、masterブランチに移動してみましょう。

$ git checkout master
Switched to branch 'master'

explain.txtはどうなるかというと元に戻ります。

explain.txt
Gitとはソースコードのバージョン管理システムである。

pabloブランチで行ったexplain.txtへの追記はmasterブランチには反映されないのです。

当然、pabloブランチに移動すればGitコマンドの説明はいつでも見ることができます。

$ git checkout pablo
Switched to branch 'pablo'
explain.txt
Gitとはソースコードのバージョン管理システムである。
git branch # ブランチ一覧を表示
git branch ブランチ名 # ブランチを作成
git checkout ブランチ名 # ブランチ切り替え

これで同じファイルでもブランチによって中身が違うということをGitを通じて実現できました。

マージ(結合)

次はマージ(結合)を学習します。
マージとは2つのブランチ間で行なわれるものです。
どういう時に行うかというと、別のブランチで編集されたファイルを取り込みたい時です。

具体例で説明すると分かりやすいので、masterブランチとpabloブランチの関係で説明します。
いったんmasterブランチに切り替えましょう

$ git checkout master
Switched to branch 'master'

masterブランチからpabloブランチが作られて、explain.txtにGitの説明が追加されました。
masterブランチはこれを取り込みたいとします。
このような時にpabloブランチをマージするのです。

マージはgit merge マージするブランチ名でできます。
pabloブランチをマージするにはこのコマンドになります。

$ git merge pablo

これでmasterブランチにpabloブランチがマージされました。
explain.txtにpabloブランチで行ったGitの説明が追加されたことでしょう。

まとめ

この章で行った作業はこの2つです。

・ブランチを作ってファイルを編集する
・それをmasterにマージする

単純な2つの作業ですが、チーム開発では常にこの繰り返しです。

基本的にmasterでファイルの編集はしません。
何か取り組みたい課題があれば、そのためのブランチを作ります。
編集が完了したら、それをmasterにマージします。
そうすることでmasterは常に正しい状態を保つことができるのです。

次章では開発中によく使うGitコマンドを解説します。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

チーム開発のためのGit入門 (1) バージョン管理とmasterブランチ

最初に

何回かに分けてチーム開発で必要なGitの基礎を解説していきます。
Gitを網羅的に解説するのではなく、チーム開発する上で理解しておくべきポイントに絞ります。
なるべく難しい用語は使わず、Gitを始めたての方でも分かるように説明していきます。

こんな方にオススメ

・Gitを1から学習したい
・勉強はしたけどイマイチ理解できない
・チーム開発に加わるのが不安

前提の知識や環境

・何らかのプログラミング言語に触れたことがある
・Gitがインストールされている
・ターミナルでLinuxコマンドが実行できる
 (cdでディレクトリ移動ができることが分かるくらいでOK)

PCはMacを前提にしていますが、WindowsでもLinuxコマンドが使える環境があれば問題ないと思います。

Git学習の注意点

プログラミング学習には慣れが必要だと聞いたことがあると思いますが、Gitもその通りでむしろ言語やフレームワークよりも慣れるまでに時間がかかります。
ですので「理解した。もうバッチリ」とはなりづらいです。
しかしチーム開発でGitはほぼ必ず使うので、なかなか厄介な存在です。

チーム開発に入ってGitでつまずくと、なんとも言えない辛さがあります。
そうならないために高度な知識は必要ないので、Gitの概念とコマンドを一つづつ理解していきましょう。

Gitについて

Gitがバージョン管理をするツールだということはすでにご存知だと思います。
まずはバージョン管理とは何かについて簡単に説明します。
例えばtest.txtがあったとして、このテキストファイルには、あるバージョンではあいうえおと書かれており

test.txt
あいうえお

別のバージョンではかきくけこと書かれている。

test.txt
かきくけこ

どちらも同じファイルだけど、バージョンによって中身が違う。
このようなことがバージョン管理によって実現できるのです。

そしてGitではバージョンのことをブランチと呼びます。
ブランチと言われたらバージョンのことなんだなと考えてください。
そのうちブランチと言われた方がしっくりくるようになります。

Git環境

Gitがインストールされているかの確認です。

$ git --version
git version 2.21.1

バージョン情報が出ればGitがインストールされています。
2.以降の値は違っていても大丈夫です。

バージョン管理の開始

お使いのPCにはGitがインストールされているとします。
しかし、これだけでは何も起こりません。

Gitにこのディレクトリを管理してほしいと伝えなければなりません。
Gitはディレクトリ単位でバージョン管理を行います。

なので学習用にdevelopというディレクトリを作りましょう。
もちろん右クリックでフォルダを作ってもいいですが、コマンドでも作れます。
(ディレクトリとフォルダは同じ意味だと考えてください)

$ mkdir develop

作ったdevelopに移動します。

$ cd develop

ここでファイル一覧を表示するlsコマンドを打ちます。
-Aは全てのファイルを表示するためのオプションです。

$ ls -A

もちろん空なので何も表示されません。

ではこの状態からdevelopをGitで管理します。
このコマンドを打てばGitでバージョン管理が始まります!

$ git init
Initialized empty Git repository in ...(略)

Gitでバージョン管理されたので、ファイル一覧を表示するコマンドをもう一度打ってみます。

$ ls -A
.git

今度は.gitが表示されました。
これはGitがこのディレクトリを管理するために使うものです。
Gitが何かやってくれるんだなと感じてもらえればOKです。

ちなみに.gitというのはディレクトリで、中にファイルがたくさん入っています。
テキストエディタでは.gitは表示されない設定になってることが一般的なので、おそらく見れないと思いますが、存在していることは覚えておきましょう。

masterブランチ

次はブランチの一覧を表示するコマンドを打ちましょう。
先述した通りブランチとはGitにおけるバージョンのことです。
git branchでブランチの一覧を見ることができます。

$ git branch

何も出力されません...
しかし本来はこのコマンドでブランチの一覧が表示されます。

つまり今はブランチがないのです。

ではブランチを作ろうといきたいところですが、ここでルールがあります。
Gitでは最初にmasterというブランチが作られるというものです。

masterは直訳すれば主人という意味なので、全ての基準になるブランチが最初に作られると覚えましょう。

どうすればmasterブランチが作られるかというと、何らかのファイルを作成してそれをGitに保存するだけです。

ファイルは何でも良いので、explain.txtを作ってGitの説明文を記載することにします。
ファイルは普通にテキストエディタで作っても良いですし、touchコマンドで作成することも可能です。

$ touch explain.txt

このように記載して、ファイルを保存してください。

explain.txt
Gitとはソースコードのバージョン管理システムである。

addとcommit

explain.txtを作りましたが、まだGitには保存されていません。
Gitに保存するにはaddとcommitが必要です。
addは追加、commitは渡すという意味なので、Gitに追加して渡すと解釈できます。

ニュアンス的にはaddは仮保存でcommitは正式な保存です。
一般的にGitでは「保存する」という言い方はしないので、「コミットする」と記載します。
コミットと言われたらGitに保存していると考えてください。

特定のファイルをaddするにはgit add ファイル名でできます。
ただ、ファイル名を書くのは面倒なのでgit add .としてください。
ちなみに.はディレクトリ下の全てのファイルという意味です。

$ git add .

次はcommitです。
commitは正式な保存なのでメッセージをつけるのがルールになっています。
git commitの後に-m "記載したいメッセージ"でメッセージがつけれます。
メッセージはなるべく他人が見ても分かるようにするのがポイントです。

$ git commit -m "explain.txtにGitの説明を書いた"
... 略
1 file changed, 1 insertion(+)
create mode 100644 explain.txt

お使いの環境によっては警告っぽい文章が表示されるかもしれませんが、最後にこれが出力されていれば大丈夫です。

1 file changed, 1 insertion(+)
create mode 100644 explain.txt

explain.txtが作成されたことをGitが保存しましたというような意味です。

これでコミットができたので、改めてブランチ一覧を表示してみます。

$ git branch
* master

今度はmasterと出力されるので、masterブランチが作成されたことが分かります。

まとめ

この章ではGitでディレクトリをバージョン管理して、masterブランチが作成されるところまでを解説しました。
Gitにコミット(保存)するためにはaddとcommitが必要で、これは今後何回も出てきます。
次章は自分でブランチを作成して、それをmasterにマージすることを解説します。

目次

(1) バージョン管理とmasterブランチ
(2) ブランチ作成してマージ
(3) git statusとgit diff
(4) git checkoutの別の使い方
(5) .gitignoreとは
(6) コンフリクト 前編
(7) コンフリクト 後編

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

pushしたらrejectされた話

pushしてrejectされた時の対応

$ git push origin master
 ! [rejected]         
error: failed to push some refs to 
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

エラーが出た理由

リモートでRead.meを編集してコミットしたから。ローカルでそのコミットが反映されていなくて、gitが「最新をfetchしなさい」と、天の声で教えてくれている

ちなみにのちなみにfetchって?

fetchを実行するとリモートの最新の履歴を持ってきてくれる。
pullとは違い、fetchはmergeまでしない。単にリモートの内容を確認したい時に便利なコマンド

それでは解決していこう

$ git fetch

remote: Enumerating objects: 110, done.
remote: Counting objects: 100% (73/73), done.
remote: Compressing objects: 100% (30/30), done.
remote: Total 30 (delta 16), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (30/30), 10.28 KiB | 214.00 KiB/s, done.
From github.com:xxxx-xxx/sample-app
   cc1d0e43..5d7ec9f7  master            -> origin/master


$ git merge origin/master

色々とmergeされてく




$ git push origin feature/views_top
Enumerating objects: 68, done.
Counting objects: 100% (56/56), done.
Delta compression using up to 8 threads
Compressing objects: 100% (34/34), done.
Writing objects: 100% (36/36), 3.78 KiB | 1.89 MiB/s, done.
Total 36 (delta 22), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (22/22), completed with 18 local objects.
To github.com:xxxxxx-xxxx/sample-app
   05ea3e05..616a067f  master -> master

pushできない時は色んな理由があるから、エラー出てもめげずに解決していこう。

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

Dockerの開発環境でGitHubを使用する方法

環境

macOS 10.15.5

コンテナの中に入る

コンテナを起動し指定のコンテナの中に入ります。

terminal
$ docker ps
$ docker exec -i -t コンテナ名 bash

Gitをインストール

terminal
apt-get update && apt-get install -y git

ソースコードのダウンロード

terminal
git clone https://github.com/〇〇/〇〇.git

(必要に応じて)vimのインストール

terminal
apt-get install y vim

例に倣いGitHubと連動

わたしが以前にブログをあげていますのでこちらを参照ください!
GitHubの大まかな全体的な操作方法

pushの際にUsenameとPasswordが求められますので下記の内容を入力します。
Username for 'https://github.com': (GitHubのユーザー名)
Password for 'https://〇〇@github.com': (GitHubアカウントのパスワード)

これで完成になります!Dockerの開発環境の構築のやり方も紹介していますので下記をご覧ください^_^

DockerでRuby on Railsの環境開発を構築

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

AブランチからBブランチまでの差分をリセット(同期する)

staging ブランチにをパブリッシュブランチとして使用していて
検証が終わったら、masterブランチと同じ状態に戻すのですが、毎回やり方忘れるので残しておきます:santa:

TL;DR

  • A ブランチから B ブランチまでの差分をリセット(同期)
  • git diff branchB..branchA > ファイル名(B を A に同期するファイルを作成)
  • git apply ファイル名 (B を A に同期する)

結論

git diff branchB..branchA > git.patch
git apply git.patch

stagingブランチ => masterブランチに合わせる場合

git diff staging..master > git.patch
git apply git.patch

導入例

上記にrm -rf git.patchgit push.circleci/config.ymlに追加して、定期的にstagingのお掃除させる(月曜AM9時)

sync-master-with-staging.sh
#!/bin/bash -eu

git diff staging..master > git.patch
git apply git.patch
rm -rf git.patch
git push
circleci/config.yml
version: 2.1

jobs:
   sync-master:
    executor: container
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run: ./scripts/sync-staging-with-master.sh

workflows:
   sync-master-every-monday:
    triggers:
      - schedule:
          cron: '0 0 * * 1' # 月曜日 AM9時
          filters:
            branches:
              only:
                - staging
    jobs:
      - sync-master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

本番運用しているサーバーにgit/GitHubを導入するときのベストプラクティスとマサカリ

本番運用しているphp/Laravelサーバーにgitを入れたいんだけどこれであってるのかな。

こんにちは! @ykhirao です!本番サーバーにFTPでぽちぽちアップロードしている現状ですが、 ssh production git pull origin master とかで本番コードを反映させたいなと夢みたいなことを考えています。適当に考えたベストプラクティス(たたき台ともいう)を投稿するのでマサカリください!!!!!

手順の大まかなながれ

だいたいこんな状況を仮定すると

  • ローカルブランチにgitを導入して、GitHubにpushする
  • GitHubのレポジトリがあるし、masterブランチで最新になっている
  • 本番コードはだいたいmasterブランチと同じ、一部デプロイ忘れとかある

こんなものかなと思う。それに対してやることは

  • サーバー上で ssh key-gen して公開鍵・秘密鍵を作成する
  • GitHubでデプロイキーを登録する(GitHubにデプロイユーザーとか作らなくていいよ!)
  • .gitignoreが適切に設定されているか確認する
  • 特に.envファイルとか、storageフォルダとか、DB以外に本番とローカル環境で違うものがないかよく確認する

とかでしょうか。

実際の動作で確認する

GitHubにレポジトリ作るのを省略するためにlocalにremote addする。
GitHubとして読み解いてほしい。

yk@yk local % git remote add origin /Users/yk/server/project.git
yk@yk local % cd ..                 
yk@yk server % ls
local   prod
yk@yk server % git clone --bare local project.git 
Cloning into bare repository 'project.git'...
done.
yk@yk server % cd local 
yk@yk local % git push origin master                            
Everything up-to-date

prodフォルダにcloneしてくる!!で .git フォルダを削除して、git管理下に置かれてない状況に戻す。

yk@yk server % cd prod
yk@yk prod % ls
yk@yk prod % git clone /Users/yk/server/project.git .
Cloning into '.'...
done.
yk@yk prod % ll
total 8
drwxr-xr-x   5 yk  staff  160  7 11 01:54 .
drwxr-xr-x   5 yk  staff  160  7 11 01:51 ..
drwxr-xr-x  12 yk  staff  384  7 11 01:54 .git
-rw-r--r--   1 yk  staff   16  7 11 01:54 .gitignore
-rw-r--r--   1 yk  staff    0  7 11 01:54 README.md

yk@yk prod % rm -fr .git

# 本番ではstorageフォルダに画像がたくさん溜まっていることを仮定
yk@yk prod % mkdir storage
yk@yk prod % touch storage/image-prod.jpg
yk@yk prod % touch storage/image-prod2.jpg
yk@yk prod % touch storage/image-prod3.jpg

# .envファイル を本番用に書き換え
yk@yk prod % vim .env
yk@yk prod % cat .env 
APP=prod

いろいろlocalで作業した!

yk@yk server % cd local 

yk@yk local % echo "# README.md を追記" >> README.md 

yk@yk local % git diff
diff --git a/README.md b/README.md
index e69de29..7039b84 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1 @@
+# README.md を追記

yk@yk local % git commit -am "Update"
[master 1b9e11d] Update
 1 file changed, 1 insertion(+)

yk@yk local % git push origin master
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 298 bytes | 298.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /Users/yk/server/project.git
   cf9a63e..1b9e11d  master -> master

さてこの状況で本番にgitを導入しようと思います。

  • 少しlocalのほうが進んでいる
  • .envファイルが書き換わるとまずい
  • storage配下に画像たくさんあるけど.gitignoreしているから大丈夫なんだっけ?

とかそんな感じの疑問を抱えつつ、見てみます。

サーバーで ssh-keygen をして 公開鍵を GitHubのこのあたりhttps://github.com/XXXXX/XXXXX/settings/keys に登録すると、privateレポジトリでも、いい感じにpullとかできるようになります。デプロイユーザーとかをGitHubに登録しなくても大丈夫です。

本番のプロジェクトにはgit initされていない状態を確認する。

yk@yk prod % git log
fatal: not a git repository (or any of the parent directories): .git
yk@yk prod % git init 
Initialized empty Git repository in /Users/yk/server/prod/.git/
yk@yk prod % git log
fatal: your current branch 'master' does not have any commits yet

masterブランチもないし、操作できない状態なので、remoteでGitHubとかを指定して、pullしてきましょう。

yk@yk prod % git remote add origin /Users/yk/server/project.git 
yk@yk prod % git pull origin master
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 7 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (7/7), 516 bytes | 103.00 KiB/s, done.
From /Users/yk/server/project
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
error: The following untracked working tree files would be overwritten by merge:
    .gitignore
    README.md
Please move or remove them before you merge.
Aborting

いい感じ。

yk@yk prod % git log
fatal: your current branch 'master' does not have any commits yet
yk@yk prod % git status                   
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
    .gitignore
    README.md

nothing added to commit but untracked files present (use "git add" to track)

まだlogも見れないのでブランチを切り替えて一旦コミットする

yk@yk prod % git checkout -b master-backup
Switched to a new branch 'master-backup'
yk@yk prod % git add .
yk@yk prod % git commit -m "マスターのバックアップ"
[master-backup (root-commit) a6fd38c] マスターのバックアップ
 2 files changed, 3 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 README.md

yk@yk prod % git branch
* master-backup

大丈夫そう。masterにチェックアウトしてみる

yk@yk prod % git checkout master
Branch 'master' set up to track remote branch 'master' from 'origin'.
Switched to a new branch 'master'

yk@yk prod % git log
commit 1b9e11d15bda2ecdec75a8d205bdbdec185a9388 (HEAD -> master, origin/master)
Author: Yuki <yuki.dees39th@gmail.com>
Date:   Sat Jul 11 02:01:05 2020 +0900

    Update

commit cf9a63ebb4676faa949aa29a9fdf56244ed313d0
Author: Yuki <yuki.dees39th@gmail.com>
Date:   Sat Jul 11 01:48:36 2020 +0900

    init

Update という変更はまだ prod フォルダには適応させてなかったのに、きちんとpullされていることがわかりますね!
これで最新ブランチの適応はOKかと思います。

yk@yk prod % cat .env 
APP=prod
yk@yk prod % ls storage 
image-prod.jpg  image-prod2.jpg image-prod3.jpg

.env ファイルとか storege/ とか .gitignore に記述しているものは書き換わってないことがわかります。
もちろんlocalファイルは AA=local ときちんとなったままです。

yk@yk prod % cat ../local/.env 
APP=local

まとめ

こんな感じでサーバー上で git init して remote add checkout -b git add . git commit git checkout master って流れでいい感じにgit適応できる気がしたのです。

あまりこのあたりちゃんとまとめられてなかったので、サーバー運用得意な方いたら編集リクエスト、
コメント欄記入、自分なりのやつを投稿、何でも構いませんので後世に残せるいいドキュメントになればと思ってます。

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

Git:コンフリクトを無視して git pull を強制する

ローカルの変更とコンフリクトしたりしてエラーが発生している状態で、強制的に pull したいとき。

git fetch master
git reset --hard origin/master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む