20190411のGitに関する記事は16件です。

【チートシート】目的別GitHubの使い方【初心者用】

当記事の目的

以下の悩みを解決

  • GitHubのコマンドが書いてあるページはたくさんあるけど、現状に合わせてどう組み合わせて使ったらいいか分からない
  • はじめてGitHub触るけどぶっちゃけ何から手を付けたらいいか分からない

前提条件

  • 構成管理システムの概念的な話は一切触れません
  • GitHubのコマンドをインストール済みで、Linux上でGitHubにアクセスすることを想定
  • fetchとは何か、mergeとは何か、ローカルリポジトリとは?originとは?みたいな話は別のまとめを見てください。気が向いたら参考ページ張ります
  • 筆者がGitHubに慣れていくにつれ加筆されていきます

GitHubコマンド手順

case1:開発チームに入ったぞ!早速ローカルのフォルダにリモートのソースコードをクローンしてこよう!

手順

  • 自分のリポジトリにアクセス
    画像

  • Clone or downloadをクリックし、表示されたURLを控える(https://github.com/自分のリポジトリ.gitとする)

  • ローカルリポジトリを作成したいフォルダに移動

  • $ git clone https://github.com/自分のリポジトリ.git -b branch_name local_folder_name

    • branch_nameは、リモートのどのブランチをクローンするか指定
    • local_folder_nameは、作成するローカルリポジトリの名称(デフォルトはリモートURL-ブランチ名
  • ユーザID、パスワード入力を求められるため、GitHubにログインする際のユーザ名とパスワードを入力する

詰まりそうな点

case2:ブランチを分けてカスタマイズをするぞ!まずはブランチを分けよう!

手順

  • gitクローンされた、ローカルリポジトリ下にいることを確認
  • $ git branchでブランチの状態を確認
shun@shun-VirtualBox:~/xxx/yyy$ git branch
* original_branch_name
  • $ git checkout -b new_branch_name original_branch_nameで新ブランチ作成
    • new_branch_nameは、作成する新しいブランチの名称
    • original_branch_nameは、基にするローカルのブランチ名称
  • $ git branchでブランチの状態を確認
shun@shun-VirtualBox:~/xxx/yyy$ git branch
  original_branch_name
* new_branch_name

case3:カスタマイズが終わったから、分岐したローカルブランチに対してコミットしよう!

  • gitクローンされた、ローカルリポジトリ下にいることを確認
  • $ git statusでチェックアウトしてからの変更情報を確認
    • deleted: moved_file.pyは、消去されたファイル(実際にはファイル移動)
    • modified: changed_file.pyは、変更が加えられたファイル
    • deleted: deleted_file.pyは、消去されたファイル
    • new_file.pyは、新規で作成されたファイル
    • new_folder/moved_file.pyは、新規で作成されたファイル(実際にはファイル移動)
shun@shun-VirtualBox:~/xxx/yyy$ git status
ブランチ new_branch_name
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    deleted:    moved_file.py
    deleted:    deleted_file.py
    modified:   changed_file.py


追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

    new_folder/moved_file.py
    new_file.py

no changes added to commit (use "git add" and/or "git commit -a")
  • この状態を想定して、まずはaddしていく
    • $ git add moved_file.py
    • $ git add deleted_file.py
    • $ git add changed_file.py
    • $ git add new_folder/moved_file.py
    • $ git add new_file.py
  • $ git statusでaddした後の状態を確認
    • それぞれがrenamed, modified, deleted, new fileとしてコミット予定の発射台に乗っていることを確認する
shun@shun-VirtualBox:~/xxx/yyy$ git status
ブランチ new_branch_name

コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    moved_file.py -> new_folder/moved_file.py
    modified:   changed_file.py
    deleted:    deleted_file.py
    new file:   new_file.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)


追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

no changes added to commit (use "git add" and/or "git commit -a")
  • $ git commit -m 'message'でコミットを実行
    • messageは任意のコミットメッセージを入力

詰まりそうな点

  • 間違えてaddして、取り消したい場合は$ git reset HEAD added_fileを実行。$ git reset HEADまでは固定。renameの場合は、変更前のファイルと変更後のファイルに対して両方resetする必要がある
  • commit時にメッセージは必須で、-m以降を入力しないとvimが開いてしまう

case4:ローカルのブランチにコミットしたぞ!リモートブランチにも反映しよう!

手順

  • $ git push origin new_branch_name
    • originは固定値
    • new_branch_nameはリモートに反映させたいブランチ名称

詰まりそうな点

  • リモートに同一名称のブランチがない場合は、new_branch_nameが新規作成される

case5:ローカルのブランチを、リモートのブランチの状態に合わせたい!

手順

  • $ git fetch origin
    • [new branch]となっているブランチは、ローカルには無いけどリモートに存在するブランチ
    • original_branch_nameは、ローカルにもリモートにも存在するブランチ
shun@shun-VirtualBox:~/xxx/yyy$ git fetch origin
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From https://github.com/自分のリポジトリ
 * [new branch]      new_branch   -> origin/new_branch
   c5996a4..47d6cc0  original_branch_name    -> origin/original_branch_name
  • $ git reset --hard origin/original_branch_name
    • git reset --hard origin/までは固定、original_branch_nameは、合わせたいブランチ名称
    • fetchしてきたリモートのブランチを、ローカルの同一名称ブランチに反映させますよ!という命令
  • $ git checkout original_branch_nameで、reset後のブランチに移動する
  • $ git clean -df .で余分なファイルを削除する
    • ここまでの命令では、あくまで更新情報/新規作成情報のみをリモートから取得できるが、不要ファイルの削除をしてあげる必要がある
    • ここまで実行することで、リモートブランチと全く同じ状態になる

詰まりそうな点

  • fetchって何?と思う人は、リモートリポジトリとローカルリポジトリの中間層があると思えばよい。そこを「origin」と呼んでおり、リモートをoriginに反映させる処理をfetchと呼ぶ。originを使ってローカルリポジトリをどうするかが、reset以降のコマンド【入門者向け】Gitのfetchコマンドについて図を用いて解説

続く

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

【チートシート】目的別GitHubの使い方

当記事の目的

以下の悩みを解決

  • GitHubのコマンドが書いてあるページはたくさんあるけど、現状に合わせてどう組み合わせて使ったらいいか分からない
  • はじめてGitHub触るけどぶっちゃけ何から手を付けたらいいか分からない

前提条件

  • 構成管理システムの概念的な話は一切触れません
  • GitHubのコマンドをインストール済みで、Linux上でGitHubにアクセスすることを想定
  • fetchとは何か、mergeとは何か、ローカルリポジトリとは?originとは?みたいな話は別のまとめを見てください。気が向いたら参考ページ張ります
  • 筆者がGitHubに慣れていくにつれ加筆されていきます

GitHubコマンド手順

case1:開発チームに入ったぞ!早速ローカルのフォルダにリモートのソースコードをクローンしてこよう!

手順

  • 自分のリポジトリにアクセス
    画像

  • Clone or downloadをクリックし、表示されたURLを控える(https://github.com/自分のリポジトリ.gitとする)

  • ローカルリポジトリを作成したいフォルダに移動

  • $ git clone https://github.com/自分のリポジトリ.git -b branch_name local_folder_name

    • branch_nameは、リモートのどのブランチをクローンするか指定
    • local_folder_nameは、作成するローカルリポジトリの名称(デフォルトはリモートURL-ブランチ名
  • ユーザID、パスワード入力を求められるため、GitHubにログインする際のユーザ名とパスワードを入力する

詰まりそうな点

case2:ブランチを分けてカスタマイズをするぞ!まずはブランチを分けよう!

手順

  • gitクローンされた、ローカルリポジトリ下にいることを確認
  • $ git branchでブランチの状態を確認
shun@shun-VirtualBox:~/xxx/yyy$ git branch
* original_branch_name
  • $ git checkout -b new_branch_name original_branch_nameで新ブランチ作成
    • new_branch_nameは、作成する新しいブランチの名称
    • original_branch_nameは、基にするローカルのブランチ名称
  • $ git branchでブランチの状態を確認
shun@shun-VirtualBox:~/xxx/yyy$ git branch
  original_branch_name
* new_branch_name

case3:カスタマイズが終わったから、分岐したローカルブランチに対してコミットしよう!

  • gitクローンされた、ローカルリポジトリ下にいることを確認
  • $ git statusでチェックアウトしてからの変更情報を確認
    • deleted: moved_file.pyは、消去されたファイル(実際にはファイル移動)
    • modified: changed_file.pyは、変更が加えられたファイル
    • deleted: deleted_file.pyは、消去されたファイル
    • new_file.pyは、新規で作成されたファイル
    • new_folder/moved_file.pyは、新規で作成されたファイル(実際にはファイル移動)
shun@shun-VirtualBox:~/xxx/yyy$ git status
ブランチ new_branch_name
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    deleted:    moved_file.py
    deleted:    deleted_file.py
    modified:   changed_file.py


追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

    new_folder/moved_file.py
    new_file.py

no changes added to commit (use "git add" and/or "git commit -a")
  • この状態を想定して、まずはaddしていく
    • $ git add moved_file.py
    • $ git add deleted_file.py
    • $ git add changed_file.py
    • $ git add new_folder/moved_file.py
    • $ git add new_file.py
  • $ git statusでaddした後の状態を確認
    • それぞれがrenamed, modified, deleted, new fileとしてコミット予定の発射台に乗っていることを確認する
shun@shun-VirtualBox:~/xxx/yyy$ git status
ブランチ new_branch_name

コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    moved_file.py -> new_folder/moved_file.py
    modified:   changed_file.py
    deleted:    deleted_file.py
    new file:   new_file.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)


追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

no changes added to commit (use "git add" and/or "git commit -a")
  • $ git commit -m 'message'でコミットを実行
    • messageは任意のコミットメッセージを入力

詰まりそうな点

  • 間違えてaddして、取り消したい場合は$ git reset HEAD added_fileを実行。$ git reset HEADまでは固定。renameの場合は、変更前のファイルと変更後のファイルに対して両方resetする必要がある
  • commit時にメッセージは必須で、-m以降を入力しないとvimが開いてしまう

case4:ローカルのブランチにコミットしたぞ!リモートブランチにも反映しよう!

手順

  • $ git push origin new_branch_name
    • originは固定値
    • new_branch_nameはリモートに反映させたいブランチ名称

詰まりそうな点

  • リモートに同一名称のブランチがない場合は、new_branch_nameが新規作成される

case5:ローカルのブランチを、リモートのブランチの状態に合わせたい!

手順

  • $ git fetch origin
    • [new branch]となっているブランチは、ローカルには無いけどリモートに存在するブランチ
    • original_branch_nameは、ローカルにもリモートにも存在するブランチ
shun@shun-VirtualBox:~/xxx/yyy$ git fetch origin
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From https://github.com/自分のリポジトリ
 * [new branch]      new_branch   -> origin/new_branch
   c5996a4..47d6cc0  original_branch_name    -> origin/original_branch_name
  • $ git reset --hard origin/original_branch_name
    • git reset --hard origin/までは固定、original_branch_nameは、合わせたいブランチ名称
    • fetchしてきたリモートのブランチを、ローカルの同一名称ブランチに反映させますよ!という命令
  • $ git checkout original_branch_nameで、reset後のブランチに移動する
  • $ git clean -df .で余分なファイルを削除する
    • ここまでの命令では、あくまで更新情報/新規作成情報のみをリモートから取得できるが、不要ファイルの削除をしてあげる必要がある
    • ここまで実行することで、リモートブランチと全く同じ状態になる

詰まりそうな点

  • fetchって何?と思う人は、リモートリポジトリとローカルリポジトリの中間層があると思えばよい。そこを「origin」と呼んでおり、リモートをoriginに反映させる処理をfetchと呼ぶ。originを使ってローカルリポジトリをどうするかが、reset以降のコマンド【入門者向け】Gitのfetchコマンドについて図を用いて解説

続く

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

GitHub Flow で master を汚さない開発を

GitHub Flow を取り入れた背景

私は SIer で小規模チームを取りまとめています。ソースリポジトリは Git を使っていたのですが、ブランチを切らずに master のみで運用していました。

課題

master のみの運用だと正常動作しないコードが混入することもありました。

対応

なので、新機能開発やバグフィックスの際にはブランチを切って、レビューの通ったコードのみ master にマージするようにしました。マージ後はすぐにデプロイします。

GitHubFlow.png

成果

master をクリーンな状態に保てています。また、レビューにより若手メンバの育成にもなります。

できていないこと

  • プルリクエスト → 席が近いので、口頭で対応しています。
  • テストコードを書くこと → 今後、ソースが大きくなると不可欠なのですが、現時点ではテストコードをかけてないです。
  • デプロイの自動化 → 手作業が混ざってます。

品質や費用対効果を見ながら施策を打つ必要がありますが、テストコードくらいは書かないとなーと思っています。

コマンド

よく忘れるので、いつどのようなコマンドを実行するかも一通り書いておきます。

新機能の開発やバグフィックスをする時

branch を切って開発します。ブランチ名は何をするかがわかるような名前にします。次のコマンドでブランチを切りつつ、ブランチに移動します。

$ git checkout -b ブランチ名

定期的に push します。一通り書けたらレビューアに声がけする運用にしています。

$ git push origin リモートブランチ名

他の開発者やレビューアが pull する時

まず、ブランチを切り、ブランチに移動します。

$ git checkout -b ブランチ名

そのブランチ上で pull します。

$ git pull origin リモードブランチ名

なお、この状態からコミットを行なって push したい場合は次のようにローカル、リモートの両ブランチを指定する必要があります。

$ git push origin ブランチ名:リモートブランチ名

レビューが通って、マージする時

master に移動します。

$ git checkout master

マージします。

$ git merge ブランチ名

master を push します。

$ git push origin master

最後に

上記の施策は何ちゃって GitHub Flow ではあるのですが、以下の効果が出ています。

  • master をクリーンに保つ
  • レビューにより、若手メンバの育成

シンプルなフローなので、覚えることが少なくすぐ取り入れられる施策でした。とはいえ、開発効率をスケールさせつつ品質を保つにはその他の自動化も推進しなければ!と思っています。

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

git merge squash と rebase

merge の形式(メモ代わり)

merge pr の時、選択は三つあります

  • 普通の merge
  • rebase merge
  • squash merge

この三つ何か違うのは、ローカルブランチ使って説明していきます

masterブランチモデル

例えばのこブランチに幾つのcommitあったとして
5332460-f04ea0e936855609.jpg

そして、また新しいブランチを作って、開発し幾つのコミットをします、そうすると、全体図はこういうふうになります
5332460-5783bb63684fafcb.jpg

普通の Merge

ブランチを合併する時、よくあるのは以下の操作になります

masterブランチにcheckoutして,合併
:git merge devel
そして用済みのブランチを削除
:git branch -D devel
リモートブランチへpush
:git push origin master

一見何の問題もないけど、でも実際どんな結果になったのでしょうか,合併前のブランチは以下の様です
5332460-5783bb63684fafcb.jpg
操作後は
5332460-589ec8b823f545ee.jpg

一見悪くない、真っ直ぐなcommitラインになってます,develブランチ内のコミットも全部masterブランチに記録されている、でも、果たしてこんなに多くのコミット記録する必要があったのでしょうか
例えば数十人も参加するおおきなプロジェクトがあったとして、一つ修正の」ために、ちょっとしたミスで数十個のコミットをPRしてしまい、しかもmergeされました,その時、このプロジェクトのヒストリーにどうでもいいcommit数十個増えてしまう、マネージャーそれを見ると困惑するでしょ、しかも何回も繰り返しをすれば、rollbackも大変な作業になるでしょ

squash merge

複数のcommitを一つに合併する時、 git commit --amend,使えば 自分のcommit履歴が確認出来,pick で選び,squash 合併など。同様に,merge の時も出来ます、手順は二つだけ

ブランチを切り替え:git checkout master

squash 形式でmerge merge:git merge --squash devel

この時masterブランチで未提出のcommitが出てきます、注意すべきのは、それが自分のcommitであること,つまりcommitのauthorを変えた、結果、以下の様になります
5332460-c7ff7af5ba03d268.jpg
普通のmargeよりはいい、今commitは一つになった,サブブランチでいくらcommitしたとしてもここは一つしかない!

rebase merge

もし合併して更に作者のデータを残したければ、rebaseを使ってみましょう

まず devel ブランチへcheckout:git checkout devel

リベース:git rebase -i master

master ブランチへ戻る :git checkout master

合併: git merge devel

二番目の操作は、develでmasterを参照にリベース、リベースはつまり、ふたつのブランチの共通の先祖に移動して、現在のブランチで先祖から今までのcommitを合併,なので二番目の操作ではこのcommitたちの処理方法が選べる、この時masterにmergeしても、commit記録は一つしか残らない、以下の様に

5332460-3f1336dea5fe04ac.jpg

現在のcommit historyはよくなったが、注意すべき点は元のcommit historyを変換したければブランチの開発者は自分でリベースしなければならない

この三つの方式を比較すれば、いくつの結論が得られます:

  • rebase masterを綺麗な状態にし、author の識別もしやすい
  • squash もmasterを綺麗な状態にたもてるが,masterのauthorは全部maintainerであって、元のownerではない
  • merge masterの履歴汚しますが、全てのcommit historyが記録された
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git addを取り消したいとき

以下のコマンドで、git addを取り消せる。
git reset HEAD

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

【チートシート】GitHubコマンド手順【やりたいこと別】

当記事の目的

以下の悩みを解決

  • GitHubのコマンドが書いてあるページはたくさんあるけど、現状に合わせてどう組み合わせて使ったらいいか分からない
  • はじめてGitHub触るけどぶっちゃけ何から手を付けたらいいか分からない

※重要 前提条件

  • 構成管理システムの概念的な話は一切触れません
  • GitHubのコマンドをインストール済みで、Linux上でGitHubにアクセスすることを想定
  • fetchとは何か、mergeとは何か、ローカルリポジトリとは?originとは?みたいな話は別のまとめを見てください。気が向いたら参考ページ張ります
  • 筆者がGitHubに慣れていくにつれ加筆されていきます

GitHubコマンド手順

case1:開発チームに入ったぞ!早速ローカルのフォルダにリモートのソースコードをクローンしてこよう!

手順

  • 自分のリポジトリにアクセス
    画像

  • Clone or downloadをクリックし、表示されたURLを控える(https://github.com/自分のリポジトリ.gitとする)

  • ローカルリポジトリを作成したいフォルダに移動

  • $ git clone https://github.com/自分のリポジトリ.git -b branch_name local_folder_name

    • ※branch_nameは、リモートのどのブランチをクローンするか指定
    • ※local_folder_nameは、作成するローカルリポジトリの名称(デフォルトはリモートURL-ブランチ名
  • ユーザID、パスワード入力を求められるため、GitHubにログインする際のユーザ名とパスワードを入力する

詰まりそうな点

case2:ブランチを分けてカスタマイズをするぞ!まずはブランチを分けよう!

手順

  • gitクローンされた、ローカルリポジトリ下にいることを確認
  • $ git branchでブランチの状態を確認
shun@shun-VirtualBox:~/xxx/yyy$ git branch
* original_branch_name
  • $ git checkout -b new_branch_name original_branch_nameで新ブランチ作成
    • new_branch_nameは、作成する新しいブランチの名称
    • original_branch_nameは、基にするローカルのブランチ名称
  • $ git branchでブランチの状態を確認
shun@shun-VirtualBox:~/xxx/yyy$ git branch
  original_branch_name
* new_branch_name

case3:カスタマイズが終わったから、分岐したローカルブランチに対してコミットしよう!

  • gitクローンされた、ローカルリポジトリ下にいることを確認
  • $ git statusでチェックアウトしてからの変更情報を確認
    • deleted: moved_file.pyは、消去されたファイル(実際にはファイル移動)
    • modified: changed_file.pyは、変更が加えられたファイル
    • deleted: deleted_file.pyは、消去されたファイル
    • new_file.pyは、新規で作成されたファイル
    • new_folder/moved_file.pyは、新規で作成されたファイル(実際にはファイル移動)
shun@shun-VirtualBox:~/xxx/yyy$ git status
ブランチ new_branch_name
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
    deleted:    moved_file.py
    deleted:    deleted_file.py
    modified:   changed_file.py


追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

    new_folder/moved_file.py
    new_file.py

no changes added to commit (use "git add" and/or "git commit -a")
  • この状態を想定して、まずはaddしていく
    • $ git add moved_file.py
    • $ git add deleted_file.py
    • $ git add changed_file.py
    • $ git add new_folder/moved_file.py
    • $ git add new_file.py
  • $ git statusでaddした後の状態を確認
    • それぞれがrenamed, modified, deleted, new fileとしてコミット予定の発射台に乗っていることを確認する
shun@shun-VirtualBox:~/xxx/yyy$ git status
ブランチ new_branch_name

コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    moved_file.py -> new_folder/moved_file.py
    modified:   changed_file.py
    deleted:    deleted_file.py
    new file:   new_file.py

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)


追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

no changes added to commit (use "git add" and/or "git commit -a")
  • $ git commit -m 'message'でコミットを実行
    • messageは任意のコミットメッセージを入力

詰まりそうな点

  • 間違えてaddして、取り消したい場合は$ git reset HEAD added_fileを実行。$ git reset HEADまでは固定。renameの場合は、変更前のファイルと変更後のファイルに対して両方resetする必要がある
  • commit時にメッセージは必須で、-m以降を入力しないとvimが開いてしまう

case4:ローカルのブランチにコミットしたぞ!リモートブランチにも反映しよう!

手順

  • $ git push origin new_branch_name
    • originは固定値
    • new_branch_nameはリモートに反映させたいブランチ名称

詰まりそうな点

  • リモートに同一名称のブランチがない場合は、new_branch_nameが新規作成される

case5:ローカルのブランチを、リモートのブランチの状態に合わせたい!

手順

  • $ git fetch origin
    • [new branch]となっているブランチは、ローカルには無いけどリモートに存在するブランチ
    • original_branch_nameは、ローカルにもリモートにも存在するブランチ
shun@shun-VirtualBox:~/xxx/yyy$ git fetch origin
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (1/1), done.
From https://github.com/自分のリポジトリ
 * [new branch]      new_branch   -> origin/new_branch
   c5996a4..47d6cc0  original_branch_name    -> origin/original_branch_name
  • $ git reset --hard origin/original_branch_name
    • git reset --hard origin/までは固定、original_branch_nameは、合わせたいブランチ名称
    • fetchしてきたリモートのブランチを、ローカルの同一名称ブランチに反映させますよ!という命令
  • $ git checkout original_branch_nameで、reset後のブランチに移動する
  • $ git clean -df .で余分なファイルを削除する
    • ここまでの命令では、あくまで更新情報/新規作成情報のみをリモートから取得できるが、不要ファイルの削除をしてあげる必要がある
    • ここまで実行することで、リモートブランチと全く同じ状態になる

詰まりそうな点

  • fetchって何?と思う人は、リモートリポジトリとローカルリポジトリの中間層があると思えばよい。そこを「origin」と呼んでおり、リモートをoriginに反映させる処理をfetchと呼ぶ。originを使ってローカルリポジトリをどうするかが、reset以降のコマンド【入門者向け】Gitのfetchコマンドについて図を用いて解説

続く

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

SourcetreeでBeyondCompareをDiffツールに設定する

ExcelやUnity特有のアセット比較など、なにかと便利だったので設定しました。
すぐ設定できます!:baby:

環境情報

  • macOS Mojave 10.14.4
  • Beyond Compare 4.2.9
  • Sourcetree 3.1.1

設定方法

  1. ここからBeyondCompareをダウンロードする
  2. BeyondCompareを開き、メニューバーからBeyondCompare > インストールコマンドラインツール...を選択する
  3. Sourcetreeの環境設定からDiffを選択し、「差分表示ツール」、「マージツール」にBeyond Compareを設定する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitくん「全部変更されとるやで」ワイ「!? 一箇所も変更しとらんが!」

git statusをかけると、何故か大量の変更(modified)が発生した時の設定について。
サーバーがUNIX系なんだから、改行コードはLFだけにしてくれ。

TL;DR

windows以外は以下でなんとかなるかも

$ git config core.filemode=false
$ git config core.autofrlf=false

--globalにするかはご自由に

原因さがし

当方の環境

OS: Windows10 Home
- WSL(Ubuntu 18.04 LTS)

状況

差分が大量に出た状況としては、
1. WSL(Ubuntu)でいつも管理していたgitのブランチをキレイに見たかった
2. SourceTreeでローカルのリポジトリ追加してみた
3. なんか全ファイルが黄色になってステージング求めてきた。ヤバない?これ
4. modified大量発生。
5. 頭をかかえる

といった具合。
git diffでみると、

  • 全ファイルのパーミッション 0755 -> 0644
    Windowsで触っちゃったからかな
  • 改行コード LF -> CRLF
    ^Mって大量にでてた。

という有様。
なんとなくだが、Windows側のGitが悪い気がしている。

Gitが複数ある

Windowsや仮想マシンを使っている場合、Gitの実行ファイルが2つ以上ある可能性が高い。
ので、今どのGitが使われているのか、を意識する必要がある。
いくつgitがあるか調べてみた。

WSLで実行
$ where git

これはわかる。WSL(Ubuntu)のほうのgitだ。
いつもコマンドで呼んでるのはこれ。

で、問題はGit Bash(Git for Windows)の方。

GitBashで実行
$ where git
C:\Program Files\Git\mingw64\bin\git.exe
C:\Program Files\Git\cmd\git.exe

$ which git
/mingw64/bin/git

えぇ…。
whereはPowerShell叩いたのと同義でGit for Windowsで入ったgit.exe、
whichはmingwのgit、ということですかね。

正味3つのgitがありました。まじか。

で、おそらくSourceTreeやGithub for Desktopなんかで使ってるgitは、
PowerShellと同じgit.exeだと思う。

対処

ひとまず、WSL側は冒頭と同じく以下のように--globalに対して設定。

$ git config --global core.autocrlf=false
$ git config --global core.filemode=false

cloneやcommit時に自動でcrlfに変換しない設定、
ファイルのパーミッションを気にしない設定にした。

結論

いつも使っているgitを見極め、
globalで余計な差分を出さない設定にする。

あと、怖かったらlocalの.gitでも逐一設定する。

今はそれしかわからない。いい方法あるんですかね。

参考

git config の core.safecrlf って何のためよ? - 必ず隣あり

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

Git 超入門(Gitの理解を深めよう)

はじめに

初投稿です。学習したことの備忘録置き場として投稿していきたいと思います。本日は使いこなすのに苦労しているGitについて(随時、修正・追加していきます。)

Git ってなに?

Git を使うとこんな利点が

  • 変更履歴を記録することができる
  • 誰が、いつ、どこで、何のためにどこを変更したか管理できる
  • 以前の状態に少ない作業で戻ることができる
  • ソース内のコメントアウトが不要になり見やすい
  • 余計なファイルを増やす必要がなくなる

最高ですね。
そしてGitHubは、このgitの仕組みを利用したWebサービスです。

3つのデータ領域

  • 作業ディリクトリ
    → git 管理下で実際に作業をするディリクトリ

  • Git ディリクトリ
    リポジトリのすべての変更履歴を保持する場所

  • インデックス
    →次回のコミット対象となるファイルを記録する場所

用語メモ

リポジトリ:変更履歴を管理する場所(データの貯蔵庫)
- ローカルリポジトリ:自分のパソコン上のリポジトリ
- リモートリポジトリ:GitHubのリポジトリ(サーバに配置して複数人で共有できる)

commit :編集したファイルをローカルリポジトリに記録すること
(予約内容の実行)

push:ローカルにあるものをリモートに送ること

clone:リポジトリの複製
(リモートリポジトリの内容をそのままローカルリポジトリとして作成できる)

branch:分岐して個別に作業ができるディレクトリ
(他からの影響を受けないため、同じリポジトリのなかで複数の変更を同時進行できる)

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

git submodule update --init --recursive --remote --merge

git submoduleのupdate時に、初期化と、再帰化と、masterブランチをfetch&mergeする。

--merge をつけ忘れると、submoduleを指定ブランチに変更して作業中に、勝手にmasterに切り替わって悲劇

git submodule update --init --recursive --remote --merge

https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB

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

変更中にgit checkoutしたい

結論:git stashでローカルbranchに一時保存

$ git stash save

保存ファイルの復活

`$ git stash list

stash@{0}: WIP on contacts: 86fcb66 contacts mailer`
<stash名>: WIP on <stashを行ったブランチ名>:

参考
https://qiita.com/fukajun/items/41288806e4733cb9c342

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

【初心者必見!?】git rebaseを使うタイミング?

結論

git merge の代わりに使いましょう!

序章

本記事では、rebase初心者の「rebaseってどこでどう使えば良いんだ?」という疑問に答えていきます。

rebaseは超汎用的なコマンドなので
Gitマスターの皆さんには物足りないかと思いますが、ご了承ください。?

詳しい説明

git rebaseとは

解説記事です。

要はブランチの歴史改ざんコマンドです。

git mergeとは

解説記事です。

要はブランチとブランチを統合するコマンドです。

なんでわざわざrebase使うの?

前提条件

今親ブランチmasterと子ブランチdevelopがあるとします。

画像の数字は時系列順でのコミット順番です。

時系列が master → develop → master になっているのがわかると思います。

masterブランチ

スクリーンショット 2019-04-11 11.18.05.png

developブランチ

スクリーンショット 2019-04-11 11.18.14.png

コミットログが汚くなる

git mergeは超強力なブランチ合体コマンドですが、
コミットログがぐちゃぐちゃになっていく、という問題があります。

要素1:作業ブランチの持つコミットの間に他ブランチのコミットが挟まる

これはdevelop から $ git merge master を実行した結果です。

スクリーンショット 2019-04-11 11.20.09.png

developコミットの間にmasterブランチのコミットが来ていますね。

git mergeだとコミットを時系列順に並べて合体させるので仕方ないのですが、

なんとなくdevelopのコミットはまとまって表示されてほしくはないですか?

要素2:mergeメッセージが生成される

上画像の一番上にcommitした覚えのないコミットがあります。
これはmergeした時必ず生成されるコミットです。

mergeするたび生成されるため、結構な頻度で入ってきます。

レビュアーやコーダーがコミットの履歴を追う際には一切必要ないですよね?

なるべく減らしたくはないですか?

だからrebaseを使おう!

ここで、mergeではなく$ git rebase masterを実行した場合の結果を見てみると・・・

スクリーンショット 2019-04-11 11.24.32.png

コミットがまとまる

画像のように、masterブランチのコミットが下に行き、

developのコミットがすべて上に配置されるようになりました。綺麗ですね!?

マージコミットが出来ない

git mergeのときは生成されていたマージコミットがありません!美しい・・・

使ってはいけないrebase

こんなに美しいコミットログを生成するrebaseですが、使ってはいけないシーンが存在します。

それは複数人が参照しているブランチに変更を取り込む場合です。

下は某ページの画像を拝借したものですが、
開発ブランチ(develop)から機能開発ブランチ(feature)が2つ切られています。

スクリーンショット 2019-04-10 19.33.23.png

このようなブランチ構造でrebaseをして良いのは各featureブランチのみです!

developブランチでは複数のfeatureブランチに参照されているため、
rebaseを控えたほうが懸命です。

なんで使っちゃいけないの?

自分より詳しく説明しているサイトがたくさんあります!
例えばこのサイトとか。

簡単に言うと、rebaseは歴史を作り変える処理です。

なのでfeatureブランチがdevelopの古い歴史に
依存しているときにdevelopの歴史を全く違うものにした場合、

次にfeatureブランチをdevelopブランチに取り込むとコンフリクトの雨あられになります。?

じゃあどこで使うべき?

機能追加や修正等、
自分がリポジトリでなにか作業をする場合は必ずブランチを切りますよね?

このような1人しか見ていない、参照していないブランチにrebaseを使ってやると良いです。

例えば自分の作業ブランチはrebaseを使うようにすることで、
小さくきれいなコミットを作ることが出来、かつマージコミットを量産せずに済みます。

じゃあrebaseはmergeのときだけ使えば良いんだね!

実は、rebaseの本当の意味はgitの歴史を書き換えるコマンドであり、
イコールmergeの代用なわけではありません。

rebaseはそれ以上の可能性を持っているので、ぜひ他の使い所を見つけてみてください。

結論

というわけでrebaseは自分ひとりが参照しているような末端のブランチで行いましょう!
masterやdevelopなど、複数のコーダが参照するブランチにはmergeで対処しましょう!

良いGitライフを〜?

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

git push -n でドライランが実行できるんですってよ

どうもこんにちは。今日は僕の好きな Git の記事です。
難しいことは書いてないのでお立ち寄りの方は気軽に読んでいってください。
(※いつも難しいことは書けていない\(^O^)/)

概要

git push のドキュメント眺めてたらこんなオプションを見かけました。

Git - git-push Documentation

-n
--dry-run
Do everything except actually send the updates.

dry run ...だと?
言葉の響き的には 実際の push は実行せずにどういう push が行われるのかだけの確認 ができそうな気配ですね:smile:

実験

-n オプション付きで push してみます

# ブランチを作成
$ git checkout -b proj/pushingTest

# 適当なファイルを作成
$ echo 'hoge' > hoge.txt

# commit
$ git commit
[proj/pushingTest 760da1e] create hoge.txt
 1 file changed, 1 insertion(+)
 create mode 100644 hoge.txt

# -n 付きで push
$ git push -nu origin proj/pushingTest
To https://github.com/Jpsern/TestRepo.git
 * [new branch]      proj/pushingTest -> proj/pushingTest
Would set upstream of 'proj/pushingTest' to 'proj/pushingTest' of 'origin'

push すると 新しい branch が作成される、upstream branch がセットされる という2点の変更が行われることがわかります。
github 上で確認しましたが もちろんこの変更は push されていません。 さらに、ローカル環境内に origin/proj/pushingTest も作成されていません。

$ git branch -r
  origin/HEAD -> origin/master
  origin/master

まさしく期待していたドライランの挙動だと言えると思います。
(ちなみに -u オプションは --set-upstream と同じです。)

オプションなしで push してみます

$ git push -u origin proj/pushingTest
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes | 70.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote:
remote: Create a pull request for 'proj/pushingTest' on GitHub by visiting:
remote:      https://github.com/Jpsern/TestRepo/pull/new/proj/pushingTest
remote:
To https://github.com/Jpsern/TestRepo.git
 * [new branch]      proj/pushingTest -> proj/pushingTest
Branch 'proj/pushingTest' set up to track remote branch 'proj/pushingTest' from 'origin'.

実際の push はこのようになります。これはいつも見るやつですね。

実験2

前述は新しいブランチの作成を伴うものでしたが、では単純にファイルが更新されたり、新しいファイルを作成しただけの場合はどうでしょうか。

-n 付きで push してみます

# 更新
$ echo 'hogehoge' > hoge.txt

# 新規ファイル
$ echo 'newfile' > newfile.txt

# commit
$ git add hoge.txt
$ git commit
[proj/pushingTest 06aabac] update hoge.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git add newfile.txt
$ git commit
[proj/pushingTest c861aa1] create newfile.txt
 1 file changed, 1 insertion(+)
 create mode 100644 newfile.txt

# -n 付きで push
$ git push -n
To https://github.com/Jpsern/TestRepo.git
   760da1e..c861aa1  proj/pushingTest -> proj/pushingTest

push されるコミットのハッシュと、ブランチが表示されますね。
このへんは見たまんまのようです。

オプションなしで push してみます

$ git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 544 bytes | 136.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To https://github.com/Jpsern/TestRepo.git
   760da1e..c861aa1  proj/pushingTest -> proj/pushingTest

こちらも実際 push した場合の出力も載せておきます。

検証済み Git バージョン

  • 1.8.3
  • 2.19.0

バージョン1系の古い環境でも使えました。man git-push コマンドの出力結果から OPTIONS の欄を確認すると -n オプションの使用可否を確認できますので、気になる方はお使いの環境下で試してみてください。

まとめ

どのようなものが push されるか、大雑把につかむには十分だと思います。慎重派にはこういうオプションはうれしいですね。よかったらみなさまも試してみてください。お気に召すようでしたら、開発チームの運用などに導入してみるのもありかも?しれませんよ。

他にもドライランオプションが使える Git のコマンドありそうなのでそのうちもう少しまとめて記事にしてみたいと思います。(予定)

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

git push -n なんてものがあるらしいですよ

どうもこんにちは。今日は僕の好きな Git の記事です。
難しいことは書いてないのでお立ち寄りの方は気軽に読んでいってください。
(※いつも難しいことは書けていない\(^O^)/)

概要

git push のドキュメント眺めてたらこんなオプションを見かけました。

Git - git-push Documentation

-n
--dry-run
Do everything except actually send the updates.

dry run ...だと?
言葉の響き的には 実際の push は実行せずにどういう push が行われるのかだけの確認 ができそうな気配ですね:smile:

実験

-n オプション付きで push してみます

# ブランチを作成
$ git checkout -b proj/pushingTest

# 適当なファイルを作成
$ echo 'hoge' > hoge.txt

# commit
$ git commit
[proj/pushingTest 760da1e] create hoge.txt
 1 file changed, 1 insertion(+)
 create mode 100644 hoge.txt

# -n 付きで push
$ git push -nu origin proj/pushingTest
To https://github.com/Jpsern/TestRepo.git
 * [new branch]      proj/pushingTest -> proj/pushingTest
Would set upstream of 'proj/pushingTest' to 'proj/pushingTest' of 'origin'

push すると 新しい branch が作成される、upstream branch がセットされる という2点の変更が行われることがわかります。
github 上で確認しましたが もちろんこの変更は push されていません。 さらに、ローカル環境内に origin/proj/pushingTest も作成されていません。

$ git branch -r
  origin/HEAD -> origin/master
  origin/master

まさしく期待していたドライランの挙動だと言えると思います。
(ちなみに -u オプションは --set-upstream と同じです。)

オプションなしで push してみます

$ git push -u origin proj/pushingTest
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 281 bytes | 70.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
remote:
remote: Create a pull request for 'proj/pushingTest' on GitHub by visiting:
remote:      https://github.com/Jpsern/TestRepo/pull/new/proj/pushingTest
remote:
To https://github.com/Jpsern/TestRepo.git
 * [new branch]      proj/pushingTest -> proj/pushingTest
Branch 'proj/pushingTest' set up to track remote branch 'proj/pushingTest' from 'origin'.

実際の push はこのようになります。これはいつも見るやつですね。

実験2

前述は新しいブランチの作成を伴うものでしたが、では単純にファイルが更新されたり、新しいファイルを作成しただけの場合はどうでしょうか。

-n 付きで push してみます

# 更新
$ echo 'hogehoge' > hoge.txt

# 新規ファイル
$ echo 'newfile' > newfile.txt

# commit
$ git add hoge.txt
$ git commit
[proj/pushingTest 06aabac] update hoge.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

$ git add newfile.txt
$ git commit
[proj/pushingTest c861aa1] create newfile.txt
 1 file changed, 1 insertion(+)
 create mode 100644 newfile.txt

# -n 付きで push
$ git push -n
To https://github.com/Jpsern/TestRepo.git
   760da1e..c861aa1  proj/pushingTest -> proj/pushingTest

push されるコミットのハッシュと、ブランチが表示されますね。
このへんは見たまんまのようです。

オプションなしで push してみます

$ git push
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 544 bytes | 136.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To https://github.com/Jpsern/TestRepo.git
   760da1e..c861aa1  proj/pushingTest -> proj/pushingTest

こちらも実際 push した場合の出力も載せておきます。

検証済み Git バージョン

  • 1.8.3
  • 2.19.0

バージョン1系の古い環境でも使えました。man git-push コマンドの出力結果から OPTIONS の欄を確認すると -n オプションの使用可否を確認できますので、気になる方はお使いの環境下で試してみてください。

まとめ

どのようなものが push されるか、大雑把につかむには十分だと思います。慎重派にはこういうオプションはうれしいですね。よかったらみなさまも試してみてください。お気に召すようでしたら、開発チームの運用などに導入してみるのもありかも?しれませんよ。

他にもドライランオプションが使える Git のコマンドありそうなのでそのうちもう少しまとめて記事にしてみたいと思います。(予定)

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

【Git】切り離されたHEAD(detached HEAD)

切り離されたHEADとは

通常、チェックアウトではブランチ名を指定することにより。ブランチの先頭(HEAD)をチェックアウトします。
しかし、任意のコミットのチェックアウトも可能です。そうした状況では、Gitは切り離されたHEAD(detached HEAD)と呼ばれる無名ブランチを作ります。

切り離されたHEADが作成される条件

Gitは、次のような場合に切り離されたHEADを作ります。

  • ブランチの先頭でないコミットのチェックアウト。
  • 追跡ブランチのチェックアウト。
  • タグで参照されたコミットのチェックアウト。
  • git bisect操作の開始。
  • git submodule updateコマンドの使用。

このような場合、Gitは切り離されたHEADに移動したことを通知します。

切り離されたHEAD上での操作

新しいコミットが必要になったら、まず最初に新しいブランチを作成してください。
作業状態を廃棄したければ、git checkout branchで名前付きのブランチに切り替えてください。

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

Git学習メモ

ProgateのGit編をやったのでメモ。
Command Line編同様Rails Tutorialの1章で使用したコマンド
ばかりだったが復習になった。

レポジトリの新規作成(初期化)
$ git init

共有ファイルの追加
$ git add [対象名]

コミット
$ git commit -m”コメント”

リモートの名前は一般的にoriginとつけられることが多い

リモートの登録
$ git remote add origin [URL]

リモートへアップロード
$ git push origin master

リモートからプル
$ git pull origin master

ステータスの確認
$ git status

変更差分の確認
$ git diff

git logでコミットメッセージを見る

$git log -p

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