20200603のGitに関する記事は24件です。

Rails Tutorial 第6版 学習まとめ 第3章

概要

この記事は私の知識をより確実なものにするためにRailsチュートリアル解説記事を書くことで理解を深め
勉強の一環としています。稀にとんでもない内容や間違えた内容が書いてあるかもしれませんので
ご了承ください。
できればそれとなく教えてくれますと幸いです・・・

出典
Railsチュートリアル

これからやること

TwitterライクなサンプルアプリSample_appの作成を通してRailsアプリの作成方法を総合的に学習していく
本章では新しいプロジェクトSample_appの作成から始める。

第2章まではかなり詳細まで記事を書いたが第3章以降
コードの量がかなり増えてくるのでRailsチュートリアルを読めばできるところは
省略して書くことにします…

セットアップ

初期設定

新規でSample_appを作成し、
Gemfileを更新する。今回も本番用のpg gemをインストールしたくないので--without productionは忘れずに。
新規アプリなのでGitリポジトリを初期化する。
READMEもここで書き換えておく。
READMEを書き換えたらとりあえずコミットしておく。
GithubのSample_app用リモートリポジトリも作成しておく。
リモートリポジトリを作成したらプッシュしておく
Cloud9環境の場合はdevelopment.rbを編集し、アプリをローカル起動できるようにしておく。
とりあえず2章と同じようにhello,world表示のコードだけ追加してherokuにもプッシュしておく。

演習

1.Githubのリポジトリのトップページのサイト下部にREADMEが自動表示されている。
もちろんファイルを開いて直接覗いてもいい
image.png
2.hello,world!が表示されているのが確認できる。
image.png
ここで豆知識
herokuにデプロイしたアプリのドメイン名はheroku domainsで確認できる。

静的ページ

開発の習慣として常にmasterブランチ上で作業するのではなく何かを実装するタイミングで都度トピックブランチを作成
して作業するのがいい習慣と言われている。そうすることで作業の分担がしやすい。作業のくくりが見えやすいなど
様々な利点がある。
癖付けに今回から都度トピックブランチを作って作業する

$ git checkout -b static-pages
静的ページの生成

さっそく静的ページ用のコントローラから作成していく

$ rails g controller StaticPages home help 

generateは省略形のgでも良い
他にも短縮形があり、そちらを覚えるのをお勧めする。

完全なコマンド 短縮形
$ rails server $ rails s
$ rails console $ rails c
$ rails generate $ rails g
$ rails test $ rails t
$ bundle install $ bundle

Railsチュートリアル第6版より
https://railstutorial.jp/chapters/static_pages?version=6.0#table-shortcuts

とりあえず今の段階でstatic-pagesブランチをリモートにプッシュしておく
-uオプションを使ってoriginをstatic-pagesのアップストリームに設定すると
以降はgit pushだけで同じプッシュができる。

generateコマンドでコントローラを自動生成するとroutes.rbファイルも自動更新される。
今回の場合generateでhomeアクションとhelpアクションを作成したので

routes.rb
Rails.application.routes.draw do
  get 'static_pages/home'
  get 'static_pages/help'
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root "application#hello"
end

homeアクションとhelpアクションのルーティングルールが自動設定されている。
さっそくローカルサーバーを立ち上げstatic_pagesのhomeページを表示してみる。
image.png

RailsはURLを指定すると(今回は/static_pages/home)ルーターを参照し、
対応するコントローラのアクションを実行する。(StaticPagesコントローラのhomeアクション)
そのあとにそのアクションに対応するビューを出力する。
静的ページのコントローラでは都度内容が変わることはないので(ページの内容が同じ)アクションは空になっている。

演習

1.

$ rails g controller Foo bar baz

2.destroyも短縮形dが使える。

$ rails d controller Foo

静的なページの調整

現在の状態だと作成されたhomeページ、helpページはHTMLで完結しており、完全に静的なページ
つまりRailsの知識がなくても編集できるページになっているという状態。
ここで第2章のようにユーザーのデータを取得したり投稿のデータを取得したりしてその内容に応じて
表示内容を変える(動的)ような動作をするとRailsの知識(ERB)が必要になる。

テストから始める

最初のテスト

aboutページを追加する前にaboutページに対するテストを先行で書いてみる。
generateコマンドでhomeとhelpページに対するテストが自動生成されているので
まずはテストを実行して問題ないことを現時点で確認しておく

$ rails t

...

Finished in 6.708000s, 0.2982 runs/s, 0.2982 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips

Red

テスト駆動開発(TDD)のサイクルは
失敗するテスト(未実装の機能に対するテスト等)を書く→失敗(RED)
実際のアプリケーションコードを書いて先に書いたテストをパスさせる→成功(GREEN)
リファクタリング(REFACTOR)の3ステップ

これを踏まえてまだ作っていないAboutページのテストを書いてみる

static_pages_controller_test.rb
require 'test_helper'

class StaticPagesControllerTest < ActionDispatch::IntegrationTest

  ...

  test "should get about" do
    get static_pages_about_url
    assert_response :success
  end
end

このコードではstatic_pagesのaboutページにGETリクエストを送って
レスポンスコードが200 OK(success)になるという内容をテストしている。

もちろんまだAboutページを何も実装していないので期待通りエラーをはく

Green

先ほどのエラーメッセージをみてみる

Error:
StaticPagesControllerTest#test_should_get_about:
NameError: undefined local variable or method `static_pages_about_url' for #<StaticPagesControllerTest:0x000055b65cfc03b0>
    test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'

詳しく読み解くと
StaticPagesControllerTestのshould_get_aboutで
static_pages_about_urlなんてメソッドは定義されていないよ(AboutのURLがないよ)
と怒られている。

これはルーティングを設定していないから

さっそくルーティングを追加してみる。
routes.rbに
get 'static_pages/about'を追加する。
ルーティングを追加することでstatic_pages_about_urlというヘルパーが有効になる。

もういちどテストを流すと今度は

Error:
StaticPagesControllerTest#test_should_get_about:
AbstractController::ActionNotFound: The action 'about' could not be found for StaticPagesController
    test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'

これもシンプルなエラーで
aboutアクションが見つからないよと怒られている。
ルーティングを追加して、static_pagesコントローラのaboutアクションを参照するようにした結果である。

さっそくAboutアクションを追加してみる

  def about 
  end

これをstatic_pagesコントローラの中に書くだけ
アクションの中身はhomeやhelpと同じくまだ完全に静的ページなので空でOK

これでテストを流すと今度は

Error:
StaticPagesControllerTest#test_should_get_about:
ActionController::MissingExactTemplate: StaticPagesController#about is missing a template for request formats: text/html
    test/controllers/static_pages_controller_test.rb:15:in `block in <class:StaticPagesControllerTest>'

これはaboutテンプレート(ビュー)が見つからないよと怒られている。

これもビューを追加して対応する。
app/views/static_pages内にabout.html.erbを追加する。

この状態でテストは成功(GREEN)する

Finished in 0.976764s, 3.0714 runs/s, 3.0714 assertions/s.
3 runs, 3 assertions, 0 failures, 0 errors, 0 skips

少しだけ動的なページ

タイトルを動的に変更する。
勉強用にレイアウトを無効にしておく

$ mv app/views/layouts/application.html.erb layout_file

このコマンドでapplication.html.erbというレイアウトファイルの名前を一時的に変更し移動することで無効にしている。

先にタイトルのテストを書いておく
タイトルはページごとに変わればいいのでこのようなコードになる。

  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | Ruby on Rails Tutorial Sample App"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | Ruby on Rails Tutorial Sample App"
  end

titleタグを選択しその中身が一致することを確かめている。
もちろん未実装のためテストはRED

まずはhome,help,aboutページのビューを書き換える。

それぞれのページにタイトルを設定したのでテストはGREENになる。

Finished in 0.062407s, 48.0717 runs/s, 96.1433 assertions/s.
3 runs, 6 assertions, 0 failures, 0 errors, 0 skips

演習

1.ダブルクォーテーションで囲った部分(文字列)の中に#{}で変数を囲むとその変数を展開できる。
今回は変数の中にRuby on Rails Tutorial Sample Appという文字列を代入しているのでその文字列が展開される。
共通な部分は変数で代用して変更に柔軟に対応できるようにするのはどのプログラム言語でも変わらない基本事項。

  def setup
    @base_title = "Ruby on Rails Tutorial Sample App"
  end
  test "should get home" do
    get static_pages_home_url
    assert_response :success
    assert_select "title", "Home | #{@base_title}"
  end

  test "should get help" do
    get static_pages_help_url
    assert_response :success
    assert_select "title", "Help | #{@base_title}"
  end

  test "should get about" do
    get static_pages_about_url
    assert_response :success
    assert_select "title", "About | #{@base_title}"
  end

レイアウトと埋め込みRuby

現段階だとhome,help,aboutのどのページもHTML構造の大半(headなどの基本タグ)が重複している。
タイトルもRuby on Rails Tutorial Sample Appは共通。
こういった重複を取り除いてDRYすることが大切。

provideメソッドはビューで
provide(:シンボル,"文字列")といった指定をすることで
yieldでシンボルに結びつけた文字列を呼び出せる。
ビューでRubyのコードが使えるのは
ビューが埋め込みRuby[ERB(Embedded RuBy)]という形式のファイルでHTML内にRubyを埋め込めるようになっているから。
<% %>で囲むと中の文を実行するだけ
<%= %>で囲むと中の文を実行して結果がテンプレートに挿入されるという違いがある。

この仕組みを使ってタイトル部分を書き換えてみた結果がこちら

<% provide(:title,"Help") %>
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title) %> | Ruby on Rails Tutorial Sample App</title>
  </head>

もちろんテストも通る。

このままだと共通な部分が残ってしまうのでさっそくリファクタリングしてみることにする。
まずは先ほど無効化したレイアウトファイルを有効化する

mv layout_file app/views/layouts/application.html.erb

そしてhome,help,aboutにそれぞれ個別に入れているtitleタグを丸ごとレイアウトファイルのタイトルタグと入れ替える。

application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title><%= yield(:title)%> | Ruby on Rails Tutorial Sample App</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>

yieldの部分には各ページのビューの中身がそのまま代入される。
つまり各ページを表示しようとしたときに表示されているのは
各ページのビューを読み込んだapplication.html.erbである。

あとはhtmlタグなどの余計なものが各ページのビューに残ってしまっていて、このままだとapplication.html.erbと
重複してしまうので不要な部分を削除し、各ページのビューはコンテンツだけにする。

help.html.erb
<% provide(:title,"Help") %>
<h1>Help</h1>
<p>
  Get help on the Ruby on Rails Tutorial at the
  <a href="https://railstutorial.jp/help">Rails Tutorial help page</a>.
  To get help on this sample app, see the
  <a href="https://railstutorial.jp/#ebook"><em>Ruby on Rails Tutorial</em>
  book</a>.
</p>
演習

1.先にContactのテストを書いておく(TDD)

static_pages_controller_test.rb
  test "should get contact" do
    get static_pages_contact_url
    assert_response :success
    assert_select "title", "Contact | #{@base_title}"
  end

あとはroutes.rbにcontactのルーティングを追加し、
static_pages_controllerにcontactアクションを追加し、
contactビューを作成すれば良い。

Finished in 1.044651s, 3.8290 runs/s, 7.6581 assertions/s.
4 runs, 8 assertions, 0 failures, 0 errors, 0 skips

テストもパスする。

ルーティングの設定

とりあえずデプロイするためにhello,worldを表示するhelloアクションをルートURLに設定していたが
今回homeページを作ったのでそちらに移す
root 'static_pages/home'

演習

1.

static_pages_controller_test.rb
  test "should get root" do
    get root_url
    assert_response :success
  end

2.Rubyは行頭に#をつけることでその行をコメントアウトできる
ちなみにWindowsはCTRL+/でその行をコメントアウトできる。
rootURLをコメントアウトする。# root 'static_pages#home'

Error:
StaticPagesControllerTest#test_should_get_root:
NameError: undefined local variable or method `root_url' for #<StaticPagesControllerTest:0x000055d85cb31200>
    test/controllers/static_pages_controller_test.rb:10:in `block in <class:StaticPagesControllerTest>'

root_urlメソッドが定義されていないとエラーが出た。

rootURLを設定したことでroot_urlヘルパーが使えるようになっていることがわかる。

本章のまとめ

3章の作業が一通り終わったので
コミットしておく
デプロイするときにはテストを走らせるとデプロイ後にバグ発見なんて言うめんどくさいことにならないのでいい。

←前の章へ

次の章へ→

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

Git 現在のブランチを名前指定せずにpushする

提起

$ git push
fatal: The current branch feature/issue-xxx has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin feature/issue-xxx

リモートリポジトリと関連付いてないローカルブランチをプッシュしようとするとこのメッセージが表示されます。

$ git push --set-upstream origin feature/issue-xxx

メッセージで言われる通りのコマンドを実行すればプッシュされますが、typoも怖いし毎度ブランチ名を指定するのは億劫ですね。

解決

$ git push -u origin HEAD

現在のブランチをリモートリポジトリに同じ名前でプッシュする便利な方法です。

  • -u--set-upstream の省略オプション
    • 2回目以降は git push でok

さらに短くする

alias設定する

~/.zshrc に追記する

alias gp='git push'
alias gpo='git push origin HEAD'

使う

$ gp
$ gpo

git config

~/.gitconfig に追記する

[alias]
    p = !git push
    po = !git push origin HEAD

使う

$ git p
$ git po

参考

他に書いたGit関連の記事

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

GitとGitHubの基礎

1. GitとGitHubとGitHub Desktop

1-1. Git とは

  • アプリを時系列で、修正点を記録して、管理してくれるシステムのこと。

1-2. GitHub とは

  • Gitの仕組みを用い、複数人での開発ができるツールのこと。
  • Gitにおけるリモートリポジトリ(サーバー上のリポジトリ)の役割を担い、複数人がリモートリポジトリでプロダクトを共有して開発を行う。

1-3. GitHub Desktop とは

  • Gitはターミナル操作するが、ターミナルでの操作の代わりができる。GitHub Desktopを使うことで、ターミナルに慣れていなくてもGitが扱えることがメリット。
  • GitHub Desktopの導入:GitHub Desktopをダウンロードし、「Sign in to GitHub.com」から、メールアドレスとpasswordを入力し、gitHubにサインイン。GitHub Desktopのアカウント登録しておく。

2. GitHub Desktopの操作

2-1. GitHub Desktopでローカルリポジトリを扱えるように設定する方法

  • GitHub DesktopのAdd an Existing Repository from your Hard Drive...から、ローカルリポジトリを選択し、追加(Add Repository)する。
  • Add Repositoryがクリックできない場合は、Git管理用の入れ物(.gitディレクトリ)がないので、git initコマンドで作成する必要がある。
ターミナル
% cd ~/projects/ローカルリポジトリ名
% git init

2-2. GitHub Desktopからリモートリポジトリを作成する方法

  • GitHub Desktopでコミットメッセージ(initial commit)を入力→コミット→プッシュ を行うと、リモートリポジトリがない場合、自動的にリモートリポジトリも作ってくれる。
  • その時、非公開にする必要がない場合は、Keep this code privateのチェックは外して、Publish repositoryすると、GitHub のリモートリポジトリが作成できる。

2-3. GitHub Desktopからリモートリポジトリにプッシュする方法

  • コミットメッセージを入力→コミット→プッシュ の順。 Screenshot from Gyazo

3. GitHubの操作

3-1. GitHubのアカウント登録

  • Usename(ニックネーム)、メールアドレス、Password(15文字以上 or 8文字以上で数字を含むもの)を登録。
  • Freeプランを選択し、チェックボックスにはチェックは付けずにContinue。
  • アンケートページはスルー(skip this step)でok。

3-2. リモートリポジトリの作成方法

Alt text
名前はローカルリポジトリと同じ、Publicを選択し、リモートリポジトリを作成する。

3-3. ローカルリポジトリをリモートリポジトリに紐づける方法

ターミナル
% cd ~/projects/ローカルリポジトリ名
% git remote add origin GitHubに作成したリモートリポジトリのURL(https://github.com/GitHubのユーザー名/リモートリポジトリ名.git)

% git remote    # origin (リモートリポジトリのこと)と出れば、紐付け完了。

3-4. 他人のリモートリポジトリを自分の環境に反映する方法

  • 複数での開発時、誰かがアプリをリモートリポジトリに作成し、それを共有する。ローカルリポジトリは、各人がそのリモートリポジトリをダウンロードして作成する。
  • リモートリポジトリの URL を指定し、そのアプリのローカルリポジトリにダウンロードする。
    ※ この時、.gitディレクトリも含まれており、clone 元のリモートリポジトリが指定されてるので、プッシュは、clone 元に push される。但し、他人が勝手にプッシュできないようにする仕様として、リモートリポジトリ保有者がリモートリポジトリの Collaborators に追加することで、プッシュが可能になる。
ターミナル
% git clone https://github.com/ユーザー名/リモートリポジトリ名.git

3-5. Github Comment Trackerの導入

  • コードレビューのコメントを見落とさないためのChromeの拡張機能。
  • コードレビューのコメントに対応済みかがわかりやすくなる。
  • Github Comment Trackerダウンロード

4. ターミナルでのGit操作

4-1. Gitのインストール

今回はHomebrewを使用。

ターミナル
% brew install git   # Gitのインストール
% git --version      # インストールできたかを確認

4-2. ターミナルでのGit操作

4-2-1. ローカルリポジトリを作成

管理したいアプリを手動でprojectsに移動し、Git管理用の入れ物(.gitディレクトリ)を用意する。

ターミナル
# 最初に、管理したいアプリを手動でprojectsに移動しとく

% cd ~/projects/アプリ名  #ディレクトリ移動
% pwd                   #currentディレクトリを確認
% git init   # .gitを作成するコマンド

Git管理できているか?の確認方法

そのディレクトリに.gitという隠しディレクトリが存在しているかで判断できる。

ターミナル
% cd ~/projects/アプリ名
% ls .git    #.gitがあるかを確認
ls: .git: No such file or directory   # Git管理できていない場合
HEAD    config  hooks   objects refs  # Git管理できている場合

4-2-2. インデックスを追加する

バージョン記録したいタイミングまでの修正点を一時的に保存しておく場所(インデックス)を準備する。

ターミナル
% git status   # 現状を確認(インデックス追加できるディレクトリを確認)

Untracked files:に記載されたディレクトリがインデックス追加できるので、順番に追加していく。

ターミナル
% git add ディレクトリ名
% git status

Changes to be committed:に記載されていたら、インデックスに追加されている状態。

4-2-3. コミットする

インデックスに入っている変更点をバージョン記録すること。

ターミナル
% git status  #現状を確認

Changes to be committed:に記載されているものがコミット待ちの状態。
nothing to commitと返ってこれば、コミット待ちのものはない状態。

ターミナル
% git commit -m 'initial commit'
# 空のコミットでプルリクエスト作成する場合
% git commit --allow-empty -m 'create pull request'

4-2-4. プッシュする

ローカルリポジトリの変更点を、リモートリポジトリに反映すること。

ターミナル
% cd ~/projects/ローカルリポジトリ名
% git push origin ブランチ名

4-2-5. プルする

  • リモートリポジトリの変更点をローカルリポジトリに取り込むこと。
  • マージ後、リモートリポジトリは最新の状態、ローカルリポジトリはマージ前の状態なので、ローカルリポジトリに反映させる必要がある。
ターミナル
% git checkout master     # masterブランチに移動
% git pull origin master  # リモートリポジトリ(origin)のmasterブランチを反映

4-2-6. LGTM後、マスターにマージする

  • GitHub(リモートリポジトリ): Merge pull requestをクリックしてマージ実行。
  • GitHub Desktop: Current Branch:Masterで、Fetch originをクリックし、 History を確認し、Pull originをクリック。( Merge pull request に反映を確認)

4-3. よく使うGit管理に関するコマンド

コマンド 機能
git init 対象のディレクトリをバージョン管理できる入れ物に格納してくれるイメージ
git status インデックスに追加/追加されてない変更修正の確認
git add ●● ●●をインデックスに追加。※ git add . とすると「全て」を対象にできる
git commit -m 'メッセージ' コミット
git log コミットログの履歴確認(コミットID、コミットメッセージ、日時)
git remote add origin リモートリポジトリのURL(https://github.com/GitHubのユーザー名/リモートリポジトリ名.git) ローカルリポジトリにリモートリポジトリの情報を付与し、紐づける
git push origin ブランチ名 ローカルの変更点を、リモートに反映。ブランチ名 masterなら、マスターブランチにプッシュ。
git pull origin master リモートリポジトリ(origin)のマスターブランチをローカルリポジトリに反映。
git clone https://github.com/ユーザー名/リモートリポジト名.git リモートリポジトからローカルリポジトリにダウンロード
cd ●● currentディレクトリを●●に移動
pwd currentディレクトリの確認
ls ●● currentディレクトリの中の●●を検索

4-4. コミットメッセージ例

コミットメーセージ 意味
Create ●● class クラス作成
Add relation with ●● リレーションの追加
Add presence validation of ●● バリデーションの追加
Add #parse_body for parse body's markdown

5. よくあるトラブル・エラー

5-1. コミット時のエラー

  • コミットの時、Please tell me who you areというエラーが出た場合は、以下の作業を行う。
  • GitHub にアカウント登録、usernameとメールアドレスをコマンドで入力する。
ターミナル
% git config --global user.email "GitHubに登録したメールアドレス"
% git config --global user.name "GitHubに登録したusername"

5-2. プッシュを取り消したい

基本、プッシュした情報をローカルリポジトリに戻すことはできない。
そこで、コミットを打ち消すコミットを生成する(git revertコマンド)。プッシュ済みのコミットを消す方法もあるが、git revertでは打ち消したコミットの記録が残る。

ターミナル
% git log             # コミットログの確認
% git revert コミットID  # 最新のコミットIDを記載

ターミナルが編集できなくなるので、:qで脱出。GitHub Desktopを確認すると、git revertで生成したコミットが生成されている。これをpushすれば、リモートリポジトリで打ち消されているハズ。この時、ローカルからも消えるので、注意。

5-3. GitHubの管理をPrivate→Publicへ!

Settings から Danger Zone の Make this repository private から変更可能。

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

Git Github コマンド チートシート 〜よく使うコマンド編〜

こちらのブログに移行しました!

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

git : リモートブランチに初めてpushしたとき表示されたエラーを解決する

はじめに

bitbucketで新しいリポジトリを作って、そのリポジトリに最初にpushするときにつまづきました。その時の解決法と原因を記録しておこうと思います。

bitbucketで新しいリポジトリを作る

bitbucketで新しいリポジトリを作ります。
Screenshot from 2020-06-03 19-57-01.png

ここで自分は「READMEを含めますか?」の欄で「Yes」としてREADMEを一緒に作成しました。

作ったリポジトリに向けて最初のpushをする

ローカルリポジトリでファイルを編集、add、commitまで行って、pushをするというところでerrorとなりました。
(作業ブランチはmasterです)

sada@lynx:~/デスクトップ/training$ git push --set-upstream origin master
To bitbucket.org:***/***.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@bitbucket.org:***/***.git'
ヒント: Updates were rejected because the remote contains work that you do
ヒント: not have locally. This is usually caused by another repository pushing
ヒント: to the same ref. You may want to first integrate the remote changes
ヒント: (e.g., 'git pull ...') before pushing again.
ヒント: See the 'Note about fast-forwards' in 'git push --help' for details.

ヒントの中に「git pullをしてみろ」とあるので実行してみると、pullでもエラーとなりました。

fatal: refusing to merge unrelated histories

解決法

過去に全く同じように問題に合われていた方がいたので、参考にさせていただきました。

https://qiita.com/takanatsu/items/fc89de9bd11148da1438

pullのときのエラー文にあるように、無関係なヒストリーを持ったブランチ同士であるため、mergeができなかったようです。

ちゃんと調べてみたところ
Git 2.9から mergeコマンドとpullコマンドでは,--allow-unrelated-historiesを指定しない限り,無関係なヒストリを持つ2つのブランチをマージすることはできなくなった。
とありました。

結果的には「--allow-unrelated-histories」オプションを指定することでpullが成功でき、pushできました。

なぜ無関係なブランチだと言われたのか

参考元の記事でも同様の考察がされていますが、どうやら最初にREADMEを一緒に作ってリポジトリを作成したことが原因のようです。
bitbucketのブランチを見てみると、READMEが「initial commit」になっています。
Screenshot from 2020-06-03 20-24-33.png

  • リモートのmaster -> READMEをcommit
  • ローカルのmaster -> 別ファイルをcommit

リモートとローカルでそれぞれ別の過程でcommitが行われた結果、無関係なブランチと判断されたようです。

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

GitについてのTips

Gitリポジトリよりファイルを削除した時に変更を反映する

  • git rm filename.txt
    • filename.txtを削除する。
  • git rm --cached filename.txt
    • filename.txtをステージングから消す(フォルダ上には残ったまま)
  • git add -u
    • 全削除ファイルをステージングに反映する。

https://stackoverflow.com/questions/12373733/staging-deleted-files

Merge のコンフリクト(衝突)を一瞬で解決する

  • VScodeでコンフリクト のあるファイルを開く。コンフリクト のある箇所で「マージする側の変更を適用する」「マージされる側の変更を適用する」「両方の側の変更を適用する」という選択肢が選べる。

  • スクリプトで対処

    • https://easyengine.io/tutorials/git/git-resolve-merge-conflicts/
    • 基本アイディアとしては、>>>>>>>>などコンフリクトのある箇所の文字列で検索しコンフリクト のあるファイルを洗い出す → git checkout --ours PATH/FILEまたはgit checkout --theirs PATH/FILEでどちらかの変更を受け入れる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【git/基本編】これだけは押さえてほしいgitの仕組み&コマンド完全攻略版

git basic tutorial.png

今回やること

gitコマンドを使えることは個人開発でもチーム開発でも必須です

特にチーム開発ではgitを使う機会が非常に多くなります

かなり基本的な仕組みとコマンドのみなので実際に使って身につけていただけたらと思います

git(基本編)

gitの仕組み

①ワークツリー

下記コマンドでワークツリーでの変更をステージに記録していきます

$ git add

②ステージ

下記コマンドでステージからローカルリポジトリにコミット(記録を保存)することができます

$ git commit
$ git commit -m ""
# メッセージ付きで記録(変更)を保存
$ git commit -v 
# 変更内容を確認してからcommitが可能

③ローカルリポジトリ

下記コマンドでリモートリポジトリにプッシュ(送る)ことができます

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

④リモートリポジトリ

リモートリポジトリはGitHubなどのアプリケーションなどのファイル・ディレクトリの履歴を管理するネット上の場所のことです

リモートリポジトリにファイルなどをアップロードすることでバージョンごとに履歴を管理することができるため、開発において不本意な変更があった際に簡単に戻したいバージョンに戻すことができます

もっと詳しい仕組みを知ってちゃんとgitを使いこなしたい方は下の記事をご覧ください

スクリーンショット 2020-06-03 17.17.44.png

ブランチとは

ブランチとは現在のコミットを指しているただのポインタのことです

それでは以下のgitコマンドでブランチを新規追加していきましょう

$ git branch ブランチ名
$ git branch feature
# 作成したブランチに移動
$ git checkout feature

上の2つのコマンドを同時に行うコマンドが下のコマンドです

$ git checkout -b feature

もっと詳しくブランチについて知ってから他のgitコマンドを身につけたい方は下の記事をご覧ください

スクリーンショット 2020-06-03 17.19.01.png

開発の流れ

1. クローンを作る(コピーを作成する)

リモートリポジトリ(GitHub等)のファイルがワークツリーとローカルリポジトリ(.git directoryが)にコピーされる

$ git clone <repository url>

2. ブランチを作る

$ git checkout -b feature

3. プッシュする

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

4. 修正する

プロジェクトに変更を加える

5. 完了後にコミットする

$ git add .

コミットしていきます

$ git commit -m "First commit"

6. プッシュする

$ git push

7. Pull requestを送る

GitHub上でプルリクエストを送ります

以上がgitでの開発の流れですが説明はかなり省略しています

もっと詳しく知って実際の開発に役立てたい方は下の記事をご覧ください

スクリーンショット 2020-06-03 17.19.12.png

新規プロジェクトをGitHubで扱う

①git init

$ git init

Git に必要なファイル(.git)がダウンロードされます

②リモートリポジトリ(github)を新規で登録する

GitHubをブラウザで開き新規リポジトリを作成してください

その後下のコマンドを打ち込みます

$ git remote add origin githubのURL

③プッシュする

$ git push -u origin master

かなり端折って紹介したのでもっとわかりやすい説明は下の記事からご覧ください

スクリーンショット 2020-06-03 17.19.24.png

開発で役立つコマンド

リモートから情報を取得する

リモートリポジトリから情報を取得するには以下の2種類の方法があります

  1. フェッチ(fetch)
  2. プル(pull)

①フェッチ

以下のgitコマンドでリモートリポジトリから情報を取得できます

$ git fetch リモート名

専用に作成されたブランチのワークツリー には以下のgitコマンドを使って反映していきます

$ git merge origin/master

②プル

pullコマンドはこのコマンド1つで以下2つの役割を持ちます

$ git fetch origin master
$ git merge origin/master

実際のプルコマンドは以下です

$ git pull リモート名 ブランチ名

簡単なフェッチとプルの使い方だけだとわかりにくいと思うので下の記事もご覧ください

スクリーンショット 2020-06-03 17.19.34.png

リモート名の変更/削除

リモート名の変更

$ git remote rename 旧リモート名 新リモート名
$ git remote rename sample_app test_app

リモートの削除

$ git remote rm リモート名
$ git remote rm test_app

もっと詳しく知りたい方は下の記事が役立つと思います

スクリーンショット 2020-06-03 17.19.50.png

rebaseコマンドの使い方

*基本的な使い方

$ git rebase -I HEAD~数

修正したいコミットをpickからeditに変更して保存/ファイルを閉じます(コミット削除:pick~文を削除、コミット並び順変更:pick~文を並び替える)

$ git commit --amend

エディタが立ち上がるのでコミットメッセージを変更してください

$ git rebase -continue

*ブランチの変更を別ブランチに取り込みたい場合

$ git rebase master
$ git merge feature
$ git rebase -I HEAD~数

修正したいコミットをpickからsquashに変更して保存/ファイルを閉じます

*コミットを分割したい場合

$ git rebase -I HEAD~数

分割したいコミットをpickからeditに変更して保存/ファイルを閉じます

$ git reset HEAD^

別々にgit addでステージに上げてgit commitでコミットします

$ git add .
$ git commit -m "First commit"
$ git add .
$ git commit -m "Second commit"
$ git rebase —continue

以上がrebaseの使い方となりますがこれだけだとイメージが湧かないと思います

rebaseは開発において非常に重要な箇所なので是非詳しい説明は下の記事でご覧ください

スクリーンショット 2020-06-03 17.20.01.png

ここまででgitの基本を押さえられると思います

まだまだgitコマンドはありますが、まずは今回紹介した基礎を身につけて実際に使ってみてください

開発をする際に必ず役立つと思います

今回の元記事は下の記事になります

スクリーンショット 2020-06-03 17.20.43.png

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

【git/基本編】これだけわかれば100%オッケーなgitの仕組み&コマンド完全攻略版

git basic tutorial.png

今回やること

gitコマンドを使えることは個人開発でもチーム開発でも必須です

特にチーム開発ではgitを使う機会が非常に多くなります

かなり基本的な仕組みとコマンドのみなので実際に使って身につけていただけたらと思います

git(基本編)

gitの仕組み

①ワークツリー

下記コマンドでワークツリーでの変更をステージに記録していきます

$ git add

②ステージ

下記コマンドでステージからローカルリポジトリにコミット(記録を保存)することができます

$ git commit
$ git commit -m ""
# メッセージ付きで記録(変更)を保存
$ git commit -v 
# 変更内容を確認してからcommitが可能

③ローカルリポジトリ

下記コマンドでリモートリポジトリにプッシュ(送る)ことができます

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

④リモートリポジトリ

リモートリポジトリはGitHubなどのアプリケーションなどのファイル・ディレクトリの履歴を管理するネット上の場所のことです

リモートリポジトリにファイルなどをアップロードすることでバージョンごとに履歴を管理することができるため、開発において不本意な変更があった際に簡単に戻したいバージョンに戻すことができます

もっと詳しい仕組みを知ってちゃんとgitを使いこなしたい方は下の記事をご覧ください

スクリーンショット 2020-06-03 17.17.44.png

ブランチとは

ブランチとは現在のコミットを指しているただのポインタのことです

それでは以下のgitコマンドでブランチを新規追加していきましょう

$ git branch ブランチ名
$ git branch feature
# 作成したブランチに移動
$ git checkout feature

上の2つのコマンドを同時に行うコマンドが下のコマンドです

$ git checkout -b feature

もっと詳しくブランチについて知ってから他のgitコマンドを身につけたい方は下の記事をご覧ください

スクリーンショット 2020-06-03 17.19.01.png

開発の流れ

1. クローンを作る(コピーを作成する)

リモートリポジトリ(GitHub等)のファイルがワークツリーとローカルリポジトリ(.git directoryが)にコピーされる

$ git clone <repository url>

2. ブランチを作る

$ git checkout -b feature

3. プッシュする

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

4. 修正する

プロジェクトに変更を加える

5. 完了後にコミットする

$ git add .

コミットしていきます

$ git commit -m "First commit"

6. プッシュする

$ git push

7. Pull requestを送る

GitHub上でプルリクエストを送ります

以上がgitでの開発の流れですが説明はかなり省略しています

もっと詳しく知って実際の開発に役立てたい方は下の記事をご覧ください

スクリーンショット 2020-06-03 17.19.12.png

新規プロジェクトをGitHubで扱う

①git init

$ git init

Git に必要なファイル(.git)がダウンロードされます

②リモートリポジトリ(github)を新規で登録する

GitHubをブラウザで開き新規リポジトリを作成してください

その後下のコマンドを打ち込みます

$ git remote add origin githubのURL

③プッシュする

$ git push -u origin master

かなり端折って紹介したのでもっとわかりやすい説明は下の記事からご覧ください

スクリーンショット 2020-06-03 17.19.24.png

開発で役立つコマンド

リモートから情報を取得する

リモートリポジトリから情報を取得するには以下の2種類の方法があります

  1. フェッチ(fetch)
  2. プル(pull)

①フェッチ

以下のgitコマンドでリモートリポジトリから情報を取得できます

$ git fetch リモート名

専用に作成されたブランチのワークツリー には以下のgitコマンドを使って反映していきます

$ git merge origin/master

②プル

pullコマンドはこのコマンド1つで以下2つの役割を持ちます

$ git fetch origin master
$ git merge origin/master

実際のプルコマンドは以下です

$ git pull リモート名 ブランチ名

簡単なフェッチとプルの使い方だけだとわかりにくいと思うので下の記事もご覧ください

スクリーンショット 2020-06-03 17.19.34.png

リモート名の変更/削除

リモート名の変更

$ git remote rename 旧リモート名 新リモート名
$ git remote rename sample_app test_app

リモートの削除

$ git remote rm リモート名
$ git remote rm test_app

もっと詳しく知りたい方は下の記事が役立つと思います

スクリーンショット 2020-06-03 17.19.50.png

rebaseコマンドの使い方

*基本的な使い方

$ git rebase -I HEAD~数

修正したいコミットをpickからeditに変更して保存/ファイルを閉じます(コミット削除:pick~文を削除、コミット並び順変更:pick~文を並び替える)

$ git commit --amend

エディタが立ち上がるのでコミットメッセージを変更してください

$ git rebase -continue

*ブランチの変更を別ブランチに取り込みたい場合

$ git rebase master
$ git merge feature
$ git rebase -I HEAD~数

修正したいコミットをpickからsquashに変更して保存/ファイルを閉じます

*コミットを分割したい場合

$ git rebase -I HEAD~数

分割したいコミットをpickからeditに変更して保存/ファイルを閉じます

$ git reset HEAD^

別々にgit addでステージに上げてgit commitでコミットします

$ git add .
$ git commit -m "First commit"
$ git add .
$ git commit -m "Second commit"
$ git rebase —continue

以上がrebaseの使い方となりますがこれだけだとイメージが湧かないと思います

rebaseは開発において非常に重要な箇所なので是非詳しい説明は下の記事でご覧ください

スクリーンショット 2020-06-03 17.20.01.png

ここまででgitの基本を押さえられると思います

まだまだgitコマンドはありますが、まずは今回紹介した基礎を身につけて実際に使ってみてください

開発をする際に必ず役立つと思います

今回の元記事は下の記事になります

スクリーンショット 2020-06-03 17.20.43.png

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

NITICNoobsによるGit/GitHub講座 第5回 〜競合を解決する〜

フライさん(loxygen)です。限界開発鯖でのだのだ言っています。フライさんにおまかせなのだ!
説明はあまり得意ではありません。

※この記事は茨城高専生向けに書かれたものです。

お説明

前回使用したリポジトリを引っ張ってきて、そこでGit Bashを開いておいてください。
現在のコミット履歴は以下のようになっています。
image.png

コンフリクト

hello.txtがこれまでどのように編集されてきたかを見てみましょう。

image.png

add-new-funcブランチとadd-new-func-2ブランチの編集場所がまるっきりかぶっています
これではadd-new-funcブランチとadd-new-func-2ブランチ両方の内容を取り入れることができません
だからと言ってどちらかの変更を消し飛ばすのも人間性がありません。

通常Gitはgit merge 〇〇コマンドを打てば自動でマージしてくれますが、こうなってしまうとどうすれば良いのかわかりません。するとGitは「コンフリクト」を宣言します。

コンフリクトになると、Gitの代わりに開発者自らの手で変更内容をマージする作業が必要になります。
だから開発者はコンフリクトを忌み嫌うわけですね。

確認作業

前回、「マージする前に確認作業をするとお作法がいいよ」という話をしました。

どうして確認作業が必要なんですか

確認作業の説明の前に、存在意義を説明させてください。
ちょっとこの図をご覧ください。
image.png
さっき上に出した図の簡略版です。
前回のお練習の中でadd-new-func-2ブランチを作りましたね。
同じ要領でマージしようとしてみました。

すると、先程の理由でコンフリクトします。コミット履歴はこのようになります:
image.png

この後手動でマージ作業を行うわけですが、その作業を行うブランチは先程チェックアウトしたmasterブランチです。
前回masterブランチは品質が保証されるということを記述しましたが、そんなmasterブランチで作業をするのは極めておっかないことはわかりますよね。
マージ作業に失敗したらバグがあったり、最悪の場合全く動かない状態のものがmasterブランチにコミットされてしまいます。ああ、怖い怖い!

確認作業

そこで、masterブランチにチェックアウトした状態でのコンフリクトを防ぐために、
事前にadd-new-func-2ブランチでコンフリクトを発生させるということを行います。
これこそが確認作業です。便宜上確認作業と読んでいますが、正式なお名前はたぶんないです。

こういうことです:
image.png
masterブランチからadd-new-func-2に、逆方向にマージしてからmasterにマージしています。
こうすることでマージ作業をadd-new-func-2ブランチで行ってからmasterにマージすることができます。
masterブランチじゃないところでマージ作業ができるので、気が楽ですし、何より安全です

確認作業を行った上でマージしてみる

習うより慣れろ、と昔偉い人は言いました。実際にやってみましょう。

逆マージする

まずはadd-new-func-2masterをマージするんでしたね。
マージの方法は前回説明しました。やってみましょう。

Bash
$ git checkout add-new-func-2
Switched to branch 'add-new-func-2'.

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

…ん?failedですって?
はい。先程の理由でコンフリクトしました

git statusも見てみましょう。

Bash
$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:   hello.txt

no changes added to commit (use "git add" and/or "git commit -a")

You have unmerged paths…まだマージしきれてないやつがあるで!
と言われていますね。

現在、コミット履歴は以下のようになっています:
image.png

ファイルには何が起こっている?

hello.txtの中身を見てみましょう。
中身はcatコマンドで見れます。もちろん任意のテキストエディタで見ても大丈夫です。

Bash
$ cat hello.txt

上のコマンドを叩く、またはテキストファイルを任意のエディタで見ると以下のようになっています:

hello.txt
<<<<<<< HEAD
I am the kindest person.
=======
I am the greatest people.
>>>>>>> add-new-func-2

世界が急に混沌に包まれてしまいました。落ち着いて読み解いて行きましょう。と言っても簡単です。
image.png
これだけです。現在のブランチ(マージ先)の状態とマージ元の変更内容が一緒に書いてあるだけです。

解消する

解消方法は至って簡単で、2つのブランチの変更内容をいい感じにフュージョンしてやればOKです。1
今回の場合は、I am the kindest human.I am the greatest people.をいい感じにフュージョンしてやればいいわけです。

hello.txtをご自由に変更してみてください。


おヒント

筆者の場合は…

  • kindestgreatestについては、2つの特徴を両方取り入れて、I am the kindest and greatest ***.にしたい
  • humanpeopleという単語は不適切2なので、personに修正したい

と考えました。

というわけで、筆者であれば以下のように修正します。

hello.txt
I am the kindest and greatest person.

いい感じにフュージョンできたら、「<<<<<<< HEAD」から「>>>>>>> add-new-func-2」は消してください。

コンフリクト解消

全てのコンフリクトが解消できたら(今回の場合は一箇所だけなのでこれで終わりです)、いつものようにAddしてCommitしましょう。

Bash
$ git add --all

git statusも見ておきましょう。

Bash
$ git status   
On branch add-new-func-2
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
    modified:   hello.txt

All conflicts fixed but you are still merging…「コンフリクトは全部直ったけどまだマージ作業中やで!」と言われています。まだコミットしてないからですね。コミットをしましょう。

Bash
$ git commit -m "Resolved conflict between master and add-new-func-2"
[add-new-func-2 ef01234] Resolved conflict between master and add-new-func-2

これでコンフリクトが解消され、add-new-func-2上でコンフリクトの修正に成功しました。
コミット履歴はこうなっています:
image.png

masterにマージする

これでmasterブランチとのコンフリクトが起きない状態になったので、心に余裕を持ってマージすることができます。ちゃちゃっとやってしまいましょう。

Bash
$ git checkout master
Switched to branch 'master'

Updating 38f1b56..03eafb0
Fast-forward
 hello.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

一応hello.txtの中身も見てみましょう。例のごとくcatコマンドを使用しますが、お好みのエディタで確認しても大丈夫です。

Bash
$ cat hello.txt
I am the kindest and greatest person.

先程修正した内容が正常にmasterブランチに反映されていますね。
コミット履歴はこうなりました:
image.png

これでようやくコンフリクトした状態からのマージに成功しました。お疲れ様でした。

マージ作業を取りやめたい場合

なにか事情があって途中でマージ作業をキャンセルしたくなったとします。その時は以下のコマンドを入力してください:

Bash
$ git merge --abort

「コンフリクト起こらんやろ!」って場合

例えば小さい変更だったり、他の人が全くいじらなかったところを変更したりした場合などで、コンフリクトする確率は低いと判断できる場合があります。
その場合はちょっとお行儀悪いですが、確認作業を踏まずにmasterにマージして問題ないでしょう。

コンフリクトしてしまった場合は、そこで直さずにgit merge --abortを実行してから、マージする元のブランチにいって確認作業を踏むと世界が平和になります。

以下に「コンフリクト起こらんやろ!と信じてmasterブランチに直接マージしようとしたものの、コンフリクトしてしまい元のブランチで確認作業を行ったときの動き」を記しておきます。
(なお、すでにadd-new-func-2はマージしてしまったので以下のコマンドは動きません)

Bash(動きません)
$ git checkout master
Switched to branch 'master'

$ git merge add-new-func-2
Auto-merging hello.txt
CONFLICT (content): Merge conflict in hello.txt
Automatic merge failed; fix conflicts and then commit the result.

$ git merge --abort # 一旦マージ作業をやめる

$ git checkout add-new-func-2
Switched to branch 'add-new-func-2'

# 以下確認作業を行う

おまとめ

  • 別々のブランチで同じファイルの同じ場所を編集するとコンフリクトが起こる
  • 以下の「確認作業」を踏むのが好ましい
    • 1.masterブランチを作業中のブランチにマージする
    • 2. コンフリクトが発生したら以下の手段を踏む:
      • 1. >>>>>>> 〇〇<<<<<<< ⬜⬜の間をいい感じにフュージョンする
      • 2. 全部終わったらgit add --allしてgit commit
    • 3. masterブランチにチェックアウトする
    • 4. マージする
  • 強制ではないので、「多分コンフリクト起こらんやろ〜」と判断できる場合は飛ばしても良い

これでブランチについてはひとまず終了です。ここまで本当にお疲れ様でした!

おリンク

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 いまここ
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者


  1. 実際のプログラミングでコンフリクトに遭遇すると、フュージョンさせるのが大変だから困るんですよね…
    もちろん楽なケースもあります。場合によってはツールが自動解決してくれる場合もあります。 

  2. 主語がIなので、単数であることは確実です。単数に対してpeopleは使わないので不適切です。
    humanは良いかも知れませんが…personのほうが自然です。不適切とまでは行きませんが、personのほうが適切です。 

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

【git】SourceTreeでリモートリポジトリがクローン出来ない【SourceTree】

経緯

リモートリポジトリを新規でクローンしようとしたところ、下記のようなエラーが発生してクローンすることが出来なかった。

エラー: remote: Forbidden
fatal: unable to access 'https://username@bitbucket.org/hogehoge/hoge.git/'
: The requested URL returned error: 403

試したこと

git cloneコマンドを実行
結果:同様のエラーが発生した
パスワード入力を求められるようなこともナシ

解決方法

ユーザー名の後にパスワードを指定する→無事クローン出来た

'https://username:password@bitbucket.org/hogehoge/hoge.git/'
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

開発チームの生産性・健全性を客観的に知るためにリポジトリ履歴から機械的に可視化するツールを作った

はじめに

ソフトウェア開発のチームの生産性や健全性というものは、内部の体感的として理解できるものの、外部の人間からは見えにくいものです。こういった情報の非対称性は開発チーム外の人々との関係の中での問題の原因になってきました。

また、複数の開発チームやプロダクトを束ねるEM、CTOや、管理職にとってそれぞれの状況を客観的な数字やグラフで可視化することは、全体的な戦略を考える上でも重要な参考情報になります。ですが、アンケートやプロジェクト管理を増やすほど、どんどんと開発メンバーに負担をかけてしまうことになり、計測のし過ぎによる疲れなども誘発してしまいます。

本稿では、gitリポジトリのログ情報から、いくつかのグラフを生成し、チームの状況を可視化するためのツールgilotを作成したので、その目的と意図、そして使い方、注意点を解説します。

アプローチ方法

gilotのアプローチは、git logのデータを解析して、開発チームのアウトプットがどれだけ安定しているか、どれだけの出力があるのか、何人が実質的にコミットしているのかなどを分析して、可視化します。生産性や健全性そのものが直ちに判断できるわけではありませんが、ひとつの強力なエビデンスになることを期待しています。
image.png

バージョン管理システムのログを使う:

これまでも生産性や健全性の可視化という観点では、プロジェクト管理ツールや、アンケート調査などを通じてそれらを可視化する試みは多数あります。これらも重要な可視化のための情報ですが、もう一つの情報源としてバージョン管理システムの情報をソフトウェアプロジェクトに活かしていくという試みが近年では増えてきました。

バージョン管理システムのログは

  • 実際の開発者が意識せずとも自然な活動情報が記録されている。
  • プログラム言語の種別や環境によらず統一的に分析できる

などのメリットがあるため、実証的なソフトウェア・エンジニアリングの世界では注目されています。

これらの他にも、私自身がかつて自社のプロジェクトの技術的負債の可視化のために、「多くの人」が「多くの修正をしている」箇所を特定し、その技術的負債の重み付けをするという手法と実装し、マネジメントの改善に用いたことがありました。

Perl Hackers Hub 第8回 Perlによる大規模システム開発・設計のツボ(3) -技術的負債の可視化

当時はsvnとgitの2つを用いていましたが、それらのblameの結果から

SRP=R+U+((L/100)-5)

R:修正リビジョンのユニーク数
U:修正ユーザのユニーク数
L:モジュールのライン数

などから、単一責務原則に違反したモジュールを探索するということを行いました。

ジニ係数を用いて安定度をする

gilotでは、「チームのコミット量がどれだけ安定しているか」をジニ係数を用いて、可視化します。

ジニ係数は、不平等性をあらわす経済学の指標です。所得格差などが大きくなると1に近づき、小さくなると0に近づきます。

ジニ係数がとる値の範囲は 0 から 1 で、係数の値が大きいほどその集団における格差が大きい状態であるという評価になる。特にジニ係数が 0 である状態は、ローレンツ曲線が均等分配線に一致するような状態であり、各人の所得が均一で、格差が全くない状態を表す。逆にジニ係数が 1 である状態は、ローレンツ曲線が横軸に一致するような状態であり、たった1人が集団の全ての所得を独占している状態を表す。社会騒乱多発の警戒ラインは、0.4である。
wikipedia : ジニ係数

ここでジニ係数をもう少しイメージするために、ちょっと懐かしい「世界がもし100人の村だったら」の寓話を用いて、ジニ係数を計算してみましょう。

すべての富のうち
6人が59%をもっていて
みんなアメリカ合衆国の人です
74人が39%を
20人が、たったの2%を分けあっています
「世界がもし100人の村だったら」より引用

このストーリーから分かる通り、世界は不平等で一部の人に富が偏っているように思えます。この偏り度合いを数値化するにはどうしたら良いのでしょうか。その1つの方法としてジニ係数は用いられます。

image.png

カテゴリごとに下から並べて、富の累積比率と人口の累積比をプロットしていきます。この点を結んだ曲線をローレンツ曲線といいます。それに対して、すべての人が同じ富をもっていることを想定した場合の直線を均等分布線といいます。

ジニ係数は、ローレンツ曲線と均等分布線の差の積分を撮ったBの部分と、均等分布線を積分したAの部分の比率で表されます。不平等なほど格差が増えていくわけです。この村の例だと、0.59になります。

ジニ係数を用いたソーシャルゲームの健全状況の予測

このようなジニ係数は、ソーシャルゲームの健全さを測るためにも用いられてきました。一部のコアユーザのみが重課金をしていて、ライトユーザーの割合が少ないという状況が続き、格差が広がってくるとゲームは面白くなくなっていきます。健全なコミュニティでは、強いユーザーに勝ったり逆転できるかもという期待があるものです。あまりに差が付きすぎてしまうと、面白くなくなってしまいます。

コミット量の単位時間ごとの格差が大きいチームと小さいチーム

gilotで注目するのは、経済格差ではありません。また、個々人のコミット量の格差でもありません。注目するのは、「あるタイムスロットごと」の「コミット量全体」がどのようにばらついているかです。

たとえば、この1年間のうち、ある2週間には10万行位以上書き換えられたのに、その他の2週間はほとんどソースコードに触れることはなかったというケースを考えてみましょう。このような状況は、開発サイクルが重く、健全さにかけるリリースプロセスや自動テストが充実していないことによる手動テストの手間などの影が見え隠れします。

あるいは、企画フェーズと開発フェーズが極端に分かれていたり、年末・年度末に向けての開発といったロードマップ志向の開発プロセスを行うためにその時期に向けて大量の変化起こるといった場合にもジニ係数は大きく、格差が拡大していきます。

一方、継続的改善を繰り返す安定したチームは、masterなどの「本番」「リリース」ブランチへのマージが早く、ブランチの生存期間が短い傾向があります。継続的インテグレーションやデプロイメントが充実しているほど、安定してソースコードを改善していくことができます。

このように安定したアウトプットができる状態はチームが一定健全に回っていることの1つのエビデンスになりえます。開発者の生産性について、ソースコードの量自体は、なんら直接的なファクトにはなりませんが、全体に対する割合や修正の度合い、ある期間ごとのでの変化などは見る価値のある統計指標になると考えます。

gilot (ジロー)の使い方

今回開発したツールの使い方を紹介します。
GitHubはこちらです:https://github.com/hirokidaichi/gilot

インストール

pip install git+https://github.com/hirokidaichi/gilot

簡単な使い方

gilotは、3つのサブコマンド持っています。それをパイプで組み合わせて使います。
あるリポジトリから、グラフを作成するには単純に以下のように行います。

gilot log REPO_DIR | gilot plot

gilot logは対象リポジトリからcsvを生成します。gilot plotはそのCSVからグラフを生成します。
gilot logは時間がある程度かかりますので、一度CSVをファイル出力して保存し、その上でgilot plotを行うことをおすすめします。

gilot log REPO_DIR > repo.csv
gilot plot -i repo.csv -o graph.png

画像ではなく単に、統計情報が欲しい場合は

gilot log REPO_DIR | gilot info > stats.json

のように、infoサブコマンドが使えます。出力はjson形式です。

gilot log REPO_DIR | gilot info | jq .gini

jqコマンドと組み合わせれば、ジニ係数のみ表示するなど必要な統計情報のみを取得することもできます。

期間の指定、ブランチの指定

git logの情報取得にあたって期間を指定することができます。
2つの指定方法があり、何ヶ月間のデータを取得するかの--monthといつからのデータを取得するのかを指定できる--sinceの2つのオプションがあります。デフォルトは6ヶ月間です。

gilot log REPO --since 2020-01-20 -o REPO.csv
gilot log REPO --month 18 -o REPO.csv

また、ログを取得するブランチも指定することができます。デフォルトではorigin/HEADを参照してmasterに相当するものを指定するようにしていますが、開発チームのブランチ運用の方法に応じて指定をしてください。できるかぎり多くの人が触れる可能性があり、リリースされていたり、運用されているシステムと同じコードベースのbranchがツールの特性上は望ましいです。

gilot log REPO --branch develop -o REPO.csv

複数のリポジトリにまたがって、チーム運営している場合

現代的なチームでは、1つのシステムを提供するのに複数のリポジトリを1つのチームが管理していることが度々あるかと思います。
モノレポ構成になっていないようなマイクロサービスアーキテクチャではなおさら、多くのリポジトリに1つのチームが手を加えることがあるでしょう。

このような場合にもそれぞれのリポジトリの結果を結合して評価することができます。単純には以下のような方法です。

gilot log repo-a > repo-a.csv
gilot log repo-b > repo-b.csv
gilot plot -i repo*.csv

Pythonのライブラリとして用いてnotebookで使う

image.png
https://github.com/hirokidaichi/gilot/blob/master/sample/sample.ipynb

4つのグラフとその見方

image.png

fig.1:ジニ係数とローレンツ曲線のグラフ

image.png
タイムスロットごとのコミット行数量のローレンツ曲線とジニ係数を表示しています。

ジニ係数がどの値以下であれば、安全かそうでないかという統一的指標はありません。個人的な観察としては、0.5以下であれば安定したチームのアウトプットがあり、大きければ何らかのファクターが安定したコード出力を妨げているのではないかというのが所感です。

この値は、絶対値に注目するよりも、複数の事業システムがある場合に比較してみるのがよいかもしれない。いわゆるレガシーと呼ばれるものと、最近作ってチームで開発しているものには、大きな差がでてくることがあります。

fig.2:タイムスロット(2週間)あたりのコミット量の分布

image.png
あるタイムスロットのコード出力量のヒストグラム。ピークのなだらかな山なりになると、チームの活動の安定がよりわかりやすい。

外れ値がいくつもある場合、大きな機能改修・リファクタリング・棚卸しなどの削除等の影響の可能性もあります。

fig.3:タイムスロット(2週間)あたりの実際の追加・削除行数とその差

image.png
タイムスロットごとの削除行数・追加行数・総変更行数の推移。緑のエリアが多いほど、機能追加がされており、赤いエリアがリファクタリングや棚卸しなどが行われている可能性を示しています。
総変更行数における削除行数の割合をリファクタ指数として表示しています。とはいえ、単なる割合なのでリファクタリングとは限らないため注意が必要です。

fig.4:タイムスロット(2週間)あたりのコミットした開発者の人数

image.png
大規模な組織での開発が進むほど、一体何人くらいが実際にはソフトウェアの開発にたずさわっているのかわかりにくくなります。
それらの実態を可視化するため、ある二週間にコミットしたひとの平均値と推移を表示している。兼務などで一部の人数しか関われていない場合なども含めて、おおよそ定常的にリポジトリに手を入れている人間(ボットも含んでしまうが。。)の数がわかる。

より詳細な情報が取得したい場合には、次のようにinfoコマンドを用いてデータを取得することができる。

gilot info -i.csv | jq .authors                                                                              
{
  "mean": 13.357142857142858,
  "std": 4.70036238958302,
  "min": 4,
  "25%": 10,
  "50%": 15,
  "75%": 16,
  "max": 21
}

標準偏差が大きくなったり、maxとmeanの差が激しくなる場合も不健全な状態を暗喩している可能性があります。

注意点と実態把握のための手段

gilotの出力は、あくまでリポジトリに対するアクティビティの統計データでしかありません。チームやシステムの実態を、健康診断的にあるいは、毎朝の検温と同じレベルに手軽に観察・アセスメントするためのものです。これを持って病気であるとか、不健全であるとするためのツールではありません。

より詳しい実態についての評価や比較を行いたい場合は、日本CTO協会で公表しているDX Criteriaの調査項目を利用するのがよいでしょう。こちらは、システムと企業全体の人間ドックにあたります。

ビジネスインテリジェンスのためのデータ活用が叫ばれていますが、今後エンジニアリングインテリジェンス(ソフトウェア開発のデータ分析と見える化)も重要になってきています。そのための1ツールとしてご利用ください。

活用への期待

このツールは何しろ手軽にリポジトリの状態を可視化します。情報の中にほとんど機微な情報が含まれないため、外部に公開しても問題はないのではないでしょうか。むしろ、現在我々はこんなかんじでシステム開発をしているよということがわかるようにリアルタイムで採用ページに乗ってくれたりすると、ああ、こんなかんじなんだーとわかって便利ですね。

サンプルケース

以下、著名なOSSプロジェクトのこの半年間のgilot結果を掲載します。

facebook/react

image

microsoft/TypeScript

image

tensorflow/tensorflow

image

pytorch/pytorch

image

optuna/optuna

image

あわせて読みたい

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

HerokuのビルドインサーバーGit管理

Herokuとは。

無料でWEBサービスを開発&公開できるサービスで
ApacheやPHP、データベースのインストールが不要(WEBサーバーのデフォルトはApache、DBはpostgres)。
クラウドサービスで初期費用を抑え開発可能になり、環境構築が容易である。

初期設定

Herokuで無料アカウントを作成する。

$ brew install heroku/brew/heroku

Herokuへログインする。

$ heroku login

編集するディレクトリを作成し移動する。

$ mkdir myapp
$ cd myapp //アップロードしたいアプリのディレクトリ

gitのリポジトリとアクセスURLを作成する。
Anynameは任意のリポジトリ名で入力する。

$ heroku create {Any}name //プロジェクトフォルダへアプリの作成
Creating ⬢ eriapptest... done
https://your-app-name.herokuapp.com/ | https://git.heroku.com/{アプリ名}name.git //ドメインとgitのURLが発行される。


リポジトリの新規作成し管理するフォルダでgitの初期化を行う。

$ git init //リポジトリ作成
$ git remote add heroku https://git.heroku.com/{アプリ名}.git //サーバと紐付けするコマンド

PHPファイルを作成。

<?php
echo 'Hello, world!!';

リポジトリの変更内容を確認。

$git status

変更したファイルをHerokuのリポジトリにpushする。
masterはブランチ名。

コミットするファイルの指定。

$ git add . //すべてのファイル・ディレクトリ

ファイルをコミットする。

$ git commit -m"first commit" //mオプションで単一コメントが可

Herokuへソースコードの更新。

$ git push heroku master

pushするとデプロイした画面が表示される。

heroku コマンド一覧

コマンド一覧

DBの作成

Heroku postgresでDBを作成する。

Heroku 2

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

【Git】新しいブランチを作成する。

メモとして残します。

■やり方

0.作成前にカレントブランチを確認

git branch --contains=HEAD

注)分岐させたい場所にいなかったら、ブランチまたはコミットレベルで移動する。

1.ローカルにブランチ作成

git branch <作成するブランチ名>

2.リモートに作成したブランチを反映

git push -u origin <作成したブランチ名>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CodeCommitでプルリクエスト作成したら変更点が多すぎてマージできなくなった

タイトルにもある通り、CodeCommitのコンソール上でプルリクエストを作成し、マージができない状態に陥ったのでメモ。

今回は開発ブランチ(develop)をmasterブランチにマージしようとしたときに、コンソール上に下記のエラーが発生してマージすることができませんでした。

Tips Divergence Exceeded Exception The merge cannot be completed because the divergence between the branches is too great. If you want to merge these branches, use a Git client.

上記のエラーをそのまま簡単に訳すと「差分が多すぎるからマージできないよ。マージするならGitクライアント使ってね」といった感じでしょうか。

え、差分多いと(コミット数なのかな・・?)コンソール上でマージできないとかあるんですか・・・。

原因

この記事を見に来ていただいた方、すみません。
いろいろ調べては見てみたものの、具体的にこのエラーになる原因というものがつかめなかったです。

もし原因や解消方法がわかる方がいらしたらコメントいただけますと幸いです

回避策

根本的な解決策にはなっていないと思いますが、いったんエラー内容に書いてある通り、ローカル上でマージして、プッシュする形でやりたかったことはできました。

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

NITICNoobsによるGit/GitHub講座 第3回 ~実際に使ってみよう~

自己紹介

こるくといいます。
限界開発鯖 とかいうヤバい開発者コミュニティに所属している茨城の高専生です。
前回に引き続き、私と他3人が今回もGitの使い方を説明していきます。
前回の記事が読み終わっている前提で話を進めます。

はじめに

今回は、実際にGitを使っていきながら、Gitの使い方や概念を覚えます。
ここからが本番です。

この記事は、茨城高専の2I向けに執筆された記事です。
実際に手を動かしなら読み進めてください。

リポジトリとは?

Gitでは、1つのプロジェクトを、「リポジトリ(Repository)」といいます。
基本的に「リポジトリ」内にあるすべてのファイル・フォルダがGitによって管理されることになります。

つくってみよう

百聞は一見にしかず、さっそくリポジトリをつくってみましょう。
まず、ファイルエクスプローラーで、リポジトリを作成したい場所(どこでも構いません)でGit Bashを起動します。
042f36f8a4f8dac0930ae891f0985512.gif
起動できたら、以下のコマンドを実行してください。

$ git init <作成したいリポジトリの名前>

今回はmy-first-repositoryとでもしておきましょう。
そうすると、先程開いたフォルダの中に、リポジトリ名と同じフォルダが出来ていると思います。
image.png
これがリポジトリです。
しかしこのままでは、リポジトリを操作することが出来ません。
操作できるようにするために、カレントディレクトリをリポジトリのフォルダに移しましょう。
以下のコマンドを実行してください。

$ cd <作成したリポジトリの名前>

これで作成したリポジトリに入って、操作できるようになりました。

▼ カレントディレクトリとは
カレントディレクトリ (current directory)とは|
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典

コミットとは?

Gitの基本的な考え方であり、いちばん重要なものがこの「コミット」になります。
ここで一旦、そもそもGitがどんなツールだったかを考えます。
Gitとは、バージョン管理ツールです。
ここでいう「バージョン」とは、作業の区切り区切りを意味しています。
Gitでは、バージョンのことを「コミット(Commit)」と呼び、管理しています。
現在の状態を保存して、コミットとして記録することをコミットするといいます。(まんまですね)

▼ コミットのイメージ (青丸がコミット)
thankyou.png
それぞれのコミットには、ID編集者日時変更内容編集者のコメント編集内容などがそれぞれ保存されています。
図のように、プロジェクトが進行していくにつれて「コミット」が積み重なっていくイメージです。
作業中のコミットのことを、HEADとよびます。

やってみよう

それでは実際にコミットしてみましょう。
先程の、「リポジトリに入った状態」で、次のコマンドを実行するとコミットできます。

$ git add --all
$ git commit -m "<コメントの内容>"

実行すると、以下のように表示されるはずです。

On branch master
nothing to commit, working tree clean

どうやら失敗してしまったようです。
「コミットするものが登録されていません」と怒られてしまいました。
それでは、リポジトリ内に何かしらファイルをつくってみましょう。

hello_git.txt
Hello, Git!

今回は試しに、hello_git.txtというファイルをつくってみました。
そのうえで、同じコマンドをもう一度実行してみましょう。

$ git add --all
$ git commit -m "<コメントの内容>"
[master (root-commit) e1883d2] test
 1 file changed, 1 insertion(+)
 create mode 100644 hello_git.txt

と表示されました。どうやら成功したようです。

コメントについて

コメントは、そのコミットで具体的にどんな変更をしたかわかりやすく書きましょう。
日本語でも英語でも構いませんが、共同開発の場合、プロジェクト単位で書き方を統一しましょう。

コミットの方法まとめ

実際にコミットをする際には、

$ git add --all
$ git commit -m "<コメント>"

というコマンドを使うことが多いです。
このコマンドを実行すると、前回のコミットから変更のあったすべてのファイルをコミットすることが出来ます。
試しに、ファイルを適当に編集して、もう一度コミットしてみましょう。

確認しよう

git log

実際にコミットの履歴を確認してみましょう。
以下のコマンドで確認できます。

$ git log

image.png
いかがでしょうか。このように表示されるはずです。
上から、コミットのID、編集者、日時、コメントが記録されているのがわかると思います。

Column

コミット数が増えていくと、単なるgit logでは見づらくなることがあります。
そういうときは、--onelineオプションを使うことがあります。

$ git log --oneline

image.png
情報量は少なくはなりますが、非常にスッキリした表示になります。

git diff

次は、ファイルの差分(変更された部分)を見てみましょう。
以下のコマンドで確認できます。

$ git diff HEAD^

image.png
最新のコミットと、1つ前のコミットの間でどこが変更されたかがわかります。

ワークツリーとインデックス

先程、「基本的にリポジトリ内のすべてのファイルやフォルダが管理対象になる」と書きましたが、実際には間違いです。
Gitの管理対象になるすべてのファイルとフォルダが登録されている場所を、「ワークツリー」と呼びます。(覚えなくても構いません)
また、今からコミットするファイルが登録されているところを、「インデックス」と言います。
そして、インデックスにファイルを登録することを、「ステージング」と言います。
ステージング

ワークツリーとインデックス|サル先生のGit入門【プロジェクト管理ツールBacklog】
https://backlog.com/ja/git-tutorial/intro/04/

ステージングされていないファイルは、コミットされません。
そのため、変更をコミットする際には、必ず「ステージング」を行う必要があります。

先程からコミットのときに実行しているgit addは、実はステージングをするコマンドです。
このgit addコマンドは、

$ git add <ステージング(今からコミットしたい)ファイル名>

という構成になっています。
前回のコミットから変更のあったすべてのファイルをステージングしたい、という時は、

$ git add --all

実行すると、前回のコミットから変更のあったすべてのファイルをステージングします。

git status

現在のインデックスの状態や、変更されたファイルを確認するためのコマンドがあります。

$ git status

git status -s でちょっと幸せになれる - Qiita より

サンプルですが、このように表示されます。

このコマンドは、コミットをする前にインデックスを確認する用途に使えます。
そうすることで、コミットされてほしくないファイルがコミットされることを未然に防げます。
(個人情報とか認証情報とか。)
認証情報が含まれたコミットをpush(後述します)すると大変なことになります。
筆者は何度かやらかしています

▼ 参考
GCPで約800万円の請求がきた話|mun|note

共同開発やリモートリポジトリ(後述)を用いた開発を行う場合、git statusを確認するクセをつけましょう。

ここだけ覚えて!今回のまとめ!

✅ Gitでは、1つのプロジェクトを「リポジトリ」という。
✅ リポジトリを操作するときには、そのフォルダにcdする。
✅ Gitでは、作業履歴を「コミット」として保存する。
✅ 変更したファイルをすべてコミットする時 → git add .git commit -m "コメント"
git statusを確認するクセをつけよう。

リンク

次回

NITICNoobsによるGit/GitHub講座 第4回 〜並行世界を創世する〜

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者

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

NITICNoobsによるGit/GitHub講座 第2回 ~設定しよう~

自己紹介

こるくといいます。
限界開発鯖 とかいうヤバい開発者コミュニティに所属している茨城の高専生です。
前回に引き続き、私と他3人が今回もGitの使い方をに説明していきます。
前回の記事が読み終わっている前提で話を進めます。

はじめに

今回は、GitHubアカウントの取得Gitの設定です。
難しいことはありませんので、一緒に設定していきましょう。

この記事は、茨城高専の2I向けに執筆された記事です。
実際に手を動かしなら読み進めてください。

GitHubアカウントを取得する

20180716105653.png
アカウントは、こちらから取得できます。
リンクに飛ぶとこんな画面が開きます。
image.png
UsernameEmail addressPasswordそれぞれに入力してください。
一番最後のチェックボックスは、ニュースレターを受け取るかどうかです。
お好みでどうぞ。

image.png
あなたの属性を聞かれます。
学生ならばStudentを選択しましょう。

image.png
プログラミングの経験について聞かれます。
該当するものを選びましょう。

image.png
GitHubの利用目的について聞かれます。
こちらも該当するものを選びましょう。
最大3つまで選択できます。

image.png
最後に何に興味があるか聞かれます。
Pythonmachine learningC languageHTML...みたいな感じで良いでしょう。

アンケートの記入が終わったら、入力したメールアドレスに確認のメールが届きます。
メールの指示に従ってメールアドレスを確認してください。
これでGitHubアカウントの取得は完了です。

GitHubの概要やメリットは、第6回でkoが説明します

Gitの設定

いよいよGitの設定です。
まず、インストールしたGit Bashを開きます。
デスクトップの適当なところで右クリックしてください。
その後、Git Bash Hereを選択すると開けます。
open-git.gif
これがGit Bashです。
以降、基本的にGit Bashを使って作業をしていきますので、覚えておいてください。

ユーザー情報の登録

Git Bashが開けたら、以下のコマンドをそれぞれ入力した後、Enterを押下してください。

$<>は入力しないでください。
""は入力してください。
名前にはGitHub登録時に入力したユーザー名を入力してください。
mailaddress@sample.comにはGitHub登録時に入力したメールアドレスを入力してください。

$ git config --global user.name <"名前">
$ git config --global user.email <mailaddress@sample.com>

短いですが、今回はこれで終わりです。
お疲れさまでした!

ここだけ覚えて!今回のまとめ!

✅ Gitは、共同開発の際に、GitHubと共に用いられることが多い。

リンク

次回

NITICNoobsによるGit/GitHub講座 第3回 ~実際に使ってみよう~

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者

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

NITICNoobsによるGit/GitHub講座 第6回 GitHub入門編

どうも

ko と申します。
春からぷよぐやみんぐを始めた身ながら未だなんもできません。
限界開発鯖の底辺でクソBotを作ったりしています。

今回はGitHubの解説を担当させていただきたいと思います。対戦よろしくお願い致します。

※この記事は茨城高専生2I向けに書かれたものです。

 実際に手を動かしながら読み進めてくれると嬉しいです。

お説明

※前回までの説明を理解していること前提で説明をしていきます

今回の記事では、

  • GitHubについて
  • リモートリポジトリとは
    • ローカルリポジトリと何が違うの?
  • pushについて
  • GitHubにリモートリポジトリを作成し、pushするまでの流れ
    • cloneとは
    • push コマンドの詳細
    • .gitignoreについて

主に以上の点について説明していきます。

※以下でGit Bashと出てきますが、コマンドプロンプトでも同様の操作ができます。

GitHubとは

GitHubとは、Gitリポジトリをインターネット上に共有し、
様々な利点とともに開発を行えるリポジトリホスティングサービスとなっています。
類似のサービスとしてはGitLabなどが挙げられます。
image.png

GitHubを使用する利点

  • ローカル(自分のパソコンにある)リポジトリを何らかの理由で破壊してしまった場合、
    GitHub下で管理されているリモートリポジトリの内容を持ってくることで修復することができる
  • 共同開発者と簡単にコードを共有できる
  • 他の開発者にソースコードのレビュー(精査)をしてもらえる
  • 機能追加のリクエスト(issue)を受けられる

無条件でこれらのを得られるので、Gitを使えてGitHubを使わない理由はないと思います。
というかプログラマ業界において、基本的にGitHubは人権です。

GitHubの基本的な要素

repo.png
GitHubでは、Commit履歴やBranchなどの情報を視覚的に扱うことができます。
ファイル名やディレクトリ名をクリックすることでソースコードの内容を見たりできます。
Commit履歴では、diff(変更内容)を見やすく表示してくれたりします。

※ここの情報は誰でも見れるので、くれぐれも個人情報を載せることのないようにしてください。

リモートリポジトリについて

リモートリポジトリとは、GitHubなどのホスティングサービス側で管理されるリポジトリのことです。
ローカルのリポジトリをGitHubにアップロードし、それを共同開発者や協力者と共有することができます。

image.png

通常、リモートリポジトリ内のファイルを直接書き変えたりすることはありません。
ではどうするかというと、まずローカルリポジトリの内容を変更し、変更後のファイルの状況を
リモートリポジトリに渡してあげる必要があります。
GitHubにリポジトリをアップロードするには「push」というコマンドを使用します。

ローカルリポジトリとの違い

ローカルリポジトリは自分しか見えませんが、リモートリポジトリは「インターネット上にいる誰でも」見ることができます。
つまり、パスワードやtoken(識別情報)、API Key、本名などの重要な個人情報を載せてしまうと
悪質なハッキングに遭ってしまう危険性があります。くれぐれも気を付けてください。
その他にも共有したくないファイルがある場合があります。
(例: プロジェクトで使用しているパッケージをまとめたディレクトリなど)

Gitでは、そんなファイルをpushコマンドから無視(ignore)するように設定することができます。
  詳細は下記(.gitignoreについて)で説明しています

もしもリモートリポジトリに上げたくないファイルがある場合、.gitignoreファイルを記述するといいでしょう。

また、リモートリポジトリ内のファイル状態がおかしくなってしまうと共同開発者に迷惑なので取り扱いには少し注意が必要となってきます。

pushとは

pushとは、ローカルの変更内容をリモートリポジトリに報告するコマンドです。
コミットなどの作業をローカルで行うだけでは、その変更内容はリモートに反映されません。
image.png
(上の丸一つ一つがコミットを表しています)
Aさんがpushをすることによって初めて、Bさんは変更を取り寄せることができますし、コードレビュアーはソースコードを読むことができます。
変更を取り寄せる方法は次回で出てきます。

リモートリポジトリ作成からpushするまでの流れ

事前準備
自分のパソコンの任意の場所にリポジトリを作成しておいて、任意のファイルを追加しておいてください
image.png
.gitというディレクトリはgit initをすると自動的に作成されるので後から作成する必要はありません
(.git隠しファイルになっているので利用している環境によっては見えない場合がありますが問題ありません。)

ローカルリポジトリ内でGit Bashを起動しておいてください
(またはコマンドプロンプトを起動しリポジトリのディレクトリまで移動しておいてください。)

※ディレクトリを移動する方法についてはこるくが第2回で説明しています。


  1. GitHubアカウントページにアクセスします
     https://github.com
     ログインしてあればこのような画面が表示されます
    image.png

  2. 左のRepositoriesから、Newを選択します

  3. 新しいリモートリポジトリの情報を入力します
    image.png
    以下はオプションです
    initialize this repository with a README
     このオプションはREADME(説明書)を生成するので、リモートリポジトリの中身が空ではなくなり、
     後述するgit cloneの使用を余儀なくされてしまいます。今回は最初にgit remote add URLの方から
     紹介する予定なのでオフにしておいてください。
    public or private
     GitHubにはprivate ripositoryという機能があり、機密性を保ちたいコード(会社のプロジェクトや
     大会などのコード) を書くときなどにリポジトリをプライベートにして非公開にする
     機能があります。今回は特に隠す理由が無いと思いますので、オフにしておきましょう。

 上記以外にもadd .gitignoreやらadd a licenseやらオプションがありますが、
 今回はオフにしておいてください。

  1. Create repository をクリックします

  2. リモートリポジトリとローカルリポジトリを紐づけます。ここのやり方は主に二通りあります

一つ目

一つ目は、あなたのパソコンに先にリモートリポジトリの場所を覚えさせておいて、そこにpushできるようにする方法です。
Git Bashで、git remote add origin URL(URLは自分のリモートリポジトリのURLに置き換えてください)と入力します。
image.png

$ git remote add origin <"リモートリポジトリのURL">



これで、ローカルリポジトリのremoteという情報にoriginという名前のリモートリポジトリURLが追加されました。(なぜoriginなのかは後ほど)

この方法では、ローカルリポジトリが既に存在しており、変更を与えてしまっている場合に役立ちます。二つ目の方法ではリモートリポジトリの内容をダウンロードしてくるためローカルのファイルを移動させてpushしないといけないという二度手間になってしまいます。
それに対し、この方法(git remote add origin URL)では、ローカルに与える影響は「リモートリポジトリURLの追加」なので、既にローカルにリポジトリを作ってある場合においても実行できます。
では、コミットして、先ほど行った任意のファイル作成を記録します。

Bash
$ git add --all
$ git commit -m "<コミットメッセージ>"

次にその変更内容をリモートにpushしましょう。

Bash
$ git push origin master

(このコマンド文の詳細については下で説明します。)

二つ目

この方法では、ローカルにファイルを作る前にリモートリポジトリを作成して行うので今回のような事前準備は必要ありません。
二つ目は、先ほど作成したリモートリポジトリをcloneしてくる方法です。
知らないコマンドが出てきました。

cloneとは何か

リモートリポジトリの情報、内容のコピーををあなたのパソコン上にダウンロードしてくるコマンドです。ダウンロードしてきたリモートリポジトリの情報にはURLも含まれているので、cloneするとその後はpushを行うことができます

先ほどのinitialize this repository with a READMEのオプションをオンにしていた場合や
共同開発を行うとき、最初にリポジトリを初期化した人以外などの場合はこちらの方法を使うことが多いです。

コマンド

リポジトリを保存したいディレクトリに移動して
git clone URL (ここのURLもリモートリポジトリのURLに置き換えてください。) と入力します。

Bash
$ git clone <"リモートリポジトリのURL">

(ここで、warning: You appear to have cloned an empty repositoryと警告が出ることがありますが、
これは「リポジトリをクローンしてきたけどこれ空っぽだよ?間違ってたりしない?」と心配してくれているだけなので問題ありません。)
(ちなみにここのコマンドにはoriginという単語が含まれていませんが、その説明も後ほど行います。)
git cloneでダウンロードしてきたリポジトリは、既にGitリポジトリとして初期化されているのでgit initをする必要はありません
任意のファイルを追加して一連の流れを執り行いましょう。
image.png

Bash
$ git add --all

$ git commit -m "<任意のメッセージ>"
[master (root-commit) 96f6293] <ここにコミットメッセージが表示されます>
 1 file changed, 1 insertion(+)
 create mode 100644 <追加したファイル>

$ git push origin master                                           
Username for 'https://github.com': <ユーザー名>
Password for 'https://<ユーザー名>@github.com': (パスワードを入力)← 表示はすべて「*」になってしまいますが問題ありません。
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 392 bytes | 392.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To <"リモートリポジトリのURL">
 * [new branch]      master -> master

上記の二種類の操作(remote addclone)のうちどちらかを実行することで紐づけは完了です。
ローカルリポジトリがリモートリポジトリの場所を覚えていてくれるので、次から簡単にpushをすることができるようになります。

リモートリポジトリのURLoriginとして登録されていることを実際に確認してみましょう。

$ git remote
origin

remoteoriginが追加されていることがわかります
URLも確認することができます。

$ git remote get-url origin
https://github.com/ユーザー名/リポジトリ名

ちゃんと登録されていることが確認できたでしょうか。

場合によって使い分けることになるので、両方覚えておきましょう

  • git remote add origin URLで、remoteの情報にoriginという名前でURLを追加
  • git clone URLでリモートリポジトリをコピーしてくる

6. うまくいっていれば、これで先ほど作成したリモートリポジトリにローカルの内容が反映されているはずです。
 リモートリポジトリのURLにアクセスして確認してみましょう。
 https://github.com/ユーザー名/リポジトリ名
image.png

pushの詳細

GitHub上でリポジトリを共有するには、Git Bashコマンドプロンプト
git push リモートリポジトリ名 ブランチ名と入力します。

このリモートリポジトリ名というのは、リモートリポジトリ作成時に入力したRepository nameとは異なります
上の説明で使用されていたoriginというのがここでのリモートリポジトリ名です。(ローカルにおけるリモートのURLの名前と言った方がわかりやすいかもしれません。)
リモートリポジトリ名には自由な名前を付けることもできますが、通常の開発目的で作成した場合メインのリモートリポジトリにはoriginという名前を付けるのが慣習です。(cloneした場合は、リポジトリをダウンロードしてきた時点で自動でoriginが登録されています。)
次はブランチ名についてです。上の説明でのブランチ名はmasterとなっていましたが、これはpushしたいブランチのブランチ名によって変化します。
例えばadd-featureブランチをpushしたいとなったら、git push origin add-featureとなります。

ということで、git push origin masterというのは
originという名前が付けられたURLに存在するリモートリポジトリのmasterブランチに
 ローカルリポジトリのmasterブランチの変更内容をpushする。」

とも言い換えることができます。

ちなみに一つのローカルリポジトリに対して、リモートリポジトリを複数関連付けることは可能です。
その場合はメイン以外のリモートリポジトリの名前はoriginとはせず、役割に対応した名前を付けることになります。originというのはあくまでもメインのリモートリポジトリのみに付ける名前というのが慣習です。

.gitignoreとは

Gitリポジトリ内に.gitignoreファイルを作成し、その中で、無視してほしいファイル拡張子などを
指定することでリモートリポジトリにpushされないようにすることができます。


では実際に.gitignoreを活用してみましょう。
1. リポジトリ直下.gitignoreファイルを作成します。

image.png

2. では例としてpersonal_info.txtファイルを作ってみます
 (実際には個人情報を載せないでくださいね!執筆者は責任を負いませんからね!)
image.pngimage.png
この状態でgit statusを使用し、personal_info.txt.gitignore両方の追加が変更内容として表示されるのを確認してください。

$ git status
On branch master
Your branch is up to date with 'origin/master'.

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

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

personal_info.txtの変更が確認されてしまっています
このままadd --allしてpushしてしまうと、personal_info.txtインターネット上にアップロードされてしまいます

3. .gitignoreに、追跡しないでほしいファイル名personal_info.txtを記入しましょう
image.png
そうすると、
image.png
personal_info.txtの表示が暗くなっています。これでpersonal_info.txtignoreされたことになります。
(これはVSCodeでの表示です。お使いの環境によっては変化する可能性があります。)
 VSCodeについてはこちらに説明があります。

git statusでも確認してみましょう

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore  
                        ← さっきはあった「personal_info.txt」が消えている
nothing added to commit but untracked files present (use "git add" to track)

無事、変更が追跡されていないことが確認できます。

4. 練習も兼ねてpushしてみましょう

$ git add --all

$ git commit -m ".gitignoreを追加"
[master ec72b94] gitignoreを追加
 1 file changed, 1 insertion(+)
 create mode 100644 .gitignore
$ git push origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 308 bytes | 154.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/ko50/testrepo.git
   55c6bad..ec72b94  master -> master

5. GitHubを確認してもpersonal_info.txtはアップロードされていないはずです
 これで個人情報をpushの魔の手から守ることができます
image.png

※ちなみに、個人情報を含むファイルを既にリモートリポジトリにpushしてしまった場合、
 後から.gitignoreに追記しても commit履歴から見れてしまうので、その時はcommit自体を
 なかったことにする必要があります。(その場合の対処法は今回では扱いません。)

まとめ

  • GitHubは人権 使えないとGitを習得した意味がほとんどないまである
  • リモートリポジトリに個人情報は載せないようにする
  • ローカル(自分のパソコン)にリモートリポジトリの情報を登録するには二つの方法がある
    • git remote add origin URLで、remoteの情報にoriginという名前でURLを追加
    • git clone URLでリモートリポジトリをコピーしてくる
  • ローカルの変更内容はpushしないとリモートリポジトリには反映されない
    • git push リモートリポジトリ名 ブランチ名
    • メインのリモートリポジトリ名は特別な理由が無ければoriginにする
  • パスワードなどは.gitignoreを使用して追跡されないようにする
  • コードを外部に漏らしたくないときはリポジトリをprivateにして保護する

他パートへのリンク

次回

NITICNoobsによるGit/GitHub講座 第7回 ~fetch/pull~

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者

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

NITICNoobsによるGit/GitHub講座 第8回 〜Pull Request/Issue〜

自己紹介

どうも、isso0424です。又の名をいっそうです。
高専2年生でぷよぐやみんぐを趣味でやっています。
限界開発鯖で無限に通話をしてます。
何やってるかは以下のtwitterやGitHub見てもらえればわかると思います。
twitter
GitHub
今回は僕がGit&GitHub解説を進めていきます。

気づいたかも知れませんが俗に言うコピペと呼ばれる魔法を使いました。

お目次

  • Issue
  • Pull Request

今回はGitHubの実践編になります。

お説明

Issue

これはリポジトリに結び付けられる課題問題点などを指す言葉です。

使用する場面

Issueを使用する場面はそこそこあります

  • 新機能の実装
  • バグの報告
  • 改善点の提案

立て方

では実際に自分のリポジトリで見てみましょう。
Screenshot from 2020-06-03 02-35-42.png

ダークテーマを拡張機能で入れているので違和感があるかも知れませんが気にしないでください。
ここでCodeの隣のIssueボタンを押すとIssueの一覧が見れます。
IssueList.png

(おそらく)まだIssueを作成していないと思うので右上のNew Issueボタンを押して新しいIssueを作成しましょう。
CreateNewIssue.png

この画面で以下の情報が指定できます。

名前 意味
Title Issueのタイトル
Comment Issueに付けるコメント
Assignees Issueの担当者(self assignにより自分でIssueを解決するという意思表示ができる)
Labels Issueについたラベル(Bugなど)Issueの方向性を示す

その他は割愛します。
そして、Submit new issueを押すことでIssueを立てることができます。

閉じ方

IssueはCloseすることで解決したことを示します。
それぞれのIssueのページでClose Issueというボタンを押すと閉じれます。
また、後述のリンクされたPull Requestがマージされた際にも閉じられます。

Pull Request

これはブランチを、GitHub上で別なブランチにマージする為のものです。

作り方

まず、

git checkout -b hoge

hogeブランチに移動します。

次に、ファイルを編集します。
その後、コミットして

git push origin hoge

originに対してhogeの変更をpushします。

その後、GitHubへ行きPull Requestのボタンをクリックすると以下のような画面に飛びます。PRList.png

右上のNew Pull Requestを押すとIssueのような感じでPull Requestの作成画面に飛びます。

ChangeCompare.png

今回はmasterbasehogeをマージするので左上のcomparehogeに変更します。

すると下のような画面になります。CreateNewPR.png

ここでCreate New Pull Requestというボタンを押すとPull Requestを作成するページに飛びます。CreateNewPR2.png

ここはIssueと似ていますが一点だけ相違点があります。
それはReviewersの指定ができることです。
Reviewersというのは後述のReviewを行う人員を指します。
今回は個人リポジトリなので指定しなくて問題ありません。

そしてCreate pull requestを押すとPull Requestを作成できます。
すると下のスクショのような画面に移るはずです。
Screenshot from 2020-06-03 03-21-08.png

Pull Requestのマージ

これはとても簡単でMerge Pull Requestを押すだけでマージできます。
共同開発の場合は、ReviewerからのApprove(後述)の上でマージすることになります。
PRmerge.png

Pull Requestのレビュー

Pull Requestでのコードの変更に対してはレビューという形で指摘などをすることができます。
レビューをするにはまず、File changedというボタンをクリックします。
FilesChanged.png

そして、下のような画面に飛びます。
Screenshot from 2020-06-03 03-35-01.png
ここでレビューを行います。
指摘したい場所の行番号にカーソルを持っていって出てくる+をクリックします。
すると以下のようなフォームが出てきます。
StartAReview.png
ここでStart a reviewを押すとレビューが開始します。
あとは気になるところを指摘していきます。

最後にレビューの種類を決めます。
レビューの種類には以下のものがあります。

名前 意味
Approve マージしていいぞ
Request Changes こんなコードマージさせれるか書き直してこい
Comment 特に特殊な意味の無いコメント

Reviewers全員からApproveがもらえればそれはマージする許可が出たということなのでマージします。
逆にRequest Changesが来たらコメントを元に修正する必要があります。

ここで重大な事実なんですがなんと Pull Requestを立てた本人は自分のPull Requestに対してApproveやRequest Changesを出せません。

というわけで今回はCommentだけにしておきましょう。

すると、Pull Requestの画面に戻ると下のようにコメントが追加されます。Screenshot from 2020-06-03 03-48-10.png

これがレビューです。

Issueとのリンク

Pull Requestの大切な機能としてIssueとリンクさせる事ができることが挙げられます。
リンクと言われてもピンとこないかも知れませんがこのPull RequestはこのIssueを解決しましたというのを示すものになります。
そして、Pull Requestが後述のようにマージされると同時にIssueCloseされます。

おまとめ

  • プロジェクトの課題はIssueという形で示す。
  • 別ブランチの変更をリモートの別ブランチに適用するときはPull Requestを立てる
  • Pull Requestはレビューを募れる

おリンク

1回目〜〜インストール編〜〜
2回目〜〜設定編〜〜
3回目〜〜基本技能編〜〜
4回目〜〜平行世界編-1〜〜
5回目〜〜平行世界編-2〜〜
6回目〜〜GitHub編〜〜
7回目〜〜fetch/pull編〜〜
8回目〜〜Issue/PR編〜〜 ←イマココ

執筆者

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

大きな機能開発を細かくレビューしてもらうときに使いたいGitHubのSquash Marge

チーム開発において、大きな機能開発をいきなり大きなPRを作るとレビューが大変です。
また、レビューの段階で設計的に良くない点が見つかって大きな書き直しに迫られることもあるかと思います。
このようなことはある程度規模の大きくなってきたアプリケーションに、複数の機能を並行して開発している経験があるならイメージが付きやすいと思います。

そんな作業途中のコミットログやレビューでの指摘事項の修正が、すべてmasterブランチのコミットログに残ってしまうのは格好わるいような気がします。
そんなときに今の会社に入って運用されているマージのルールがとてもよかったのでメモしておきます。

Squash Mergeとは

GitHubには3つのマージ方法がある、ということを意識したことがある人はどれぐらいいるでしょうか?
スクリーンショット 2020-06-03 2.16.49.png
▼をクリックすると、このようなメニューが開いてマージの方法を選択することができます。
そのうちの1つがSquash Mergeというもので、マージする際に途中のコミットログが消えて1つのコミットに集約されなおされます。

詳しくはこちらのQiitaが参考になると思います。

GitHubの3種類のマージを理解する - Qiita

ブランチの運用ルール

  • master
    • masterブランチ。本番へデプロイされる
  • develop/XXXX
    • 機能ブランチ。 masterへは「Create merge commit」 する
  • work/XXXX/YYYY
    • 作業ブランチ。 develop/XXXXから派生ブランチとして切る。 develop/XXXXへ「Squash and Marge」 する

workブランチではPRを作るとき派生元の積極的にコミットを詰んでいってかまいません。レビューの指摘内容とかもここで詰んでいくのが主です。PRを作るとき、ベースブランチは develop/XXXX を選びます。
最終的に、developにマージするとき、「Squash and Merge」を選ぶと developブランチの1つのコミットになります。

developブランチはmasterへマージされる前の最終確認的な運用をします。
このブランチのPRで指摘があった場合は、別途workブランチを切り直して修正したほうがコミットログがきれいでしょう。
最後に「Create merge commit」すると、 workブランチのPR単位のコミットログが並びます。

コミットグラフっぽいものを書いていくとこんな感じでしょうか。

◯[master]
|\
| ◯[develop/X] (まだコミットが積まれてないので本当は枝分かれしてないけどイメージ
| |\
| | ◯[work/X/Y1] wip
| | ◯ feat: 機能1のwork1
| | ◯ fix: 機能1のレビュー指摘事項の修正

developブランチとworkブランチを切って、workブランチで作業します。
develop/Xブランチに向かってPRを切り、workブランチをsquashマージします。

◯[master]
|\
| ◯ [develop/X] work1 (#1)

squashマージすると、develop/XブランチにPR1個分のコミットが1つのコミットとして積まれます
次のworkブランチも切りましょう。

◯[master]
|\
| ◯[develop/X] work1 (#1)
| |\
| | ◯[work/X/Y2] feat: 機能1のwork2

work2のブランチもdevelop/XブランチにSquashマージします。

◯[master]
|\
| ◯[develop/X]
| |
| ◯ work1 (#1)
| |
| ◯ work2 (#2)

develop/Xブランチにwork2の作業内容が1コミットにまとめられて積まれます。

◯[master]
|\
| ◯[develop/X]
| |
| ◯ work1 (#1)
| |
| ◯ work2 (#2)
|/
◯[master] Merge pull request #3 from develop/X

最後にCreate commit and mergeすると、PR単位のコミットログだけが残ります!
コミットログが作業中のようなコメントではなく、PRに紐付いた1つのまとまりとしてコミットされるので、とても見通しがよいのではないでしょうか!

Squash Mergeなんて知らなかったよ、という私なので、とても感動したという話でした。

余談

マージ方法の選択は完全なる手動オペです。最後に選択してマージした方法が記録されるようです。
自動的に選択してもらう方法はないっぽい?なのでしばしば間違いが起こりますが、それについては特に気にしてない感じで運用してます。
うまいことやるとコミットログが綺麗になって気持ちいい、くらいですね。
間違えたからといって目くじらを立てているとつらくなってしまうかもしれません。

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

大きな機能開発を細かくレビューしてもらうときに使いたいGitHubのSquash Merge

チーム開発において、大きな機能開発をいきなり大きなPRを作るとレビューが大変です。
また、レビューの段階で設計的に良くない点が見つかって大きな書き直しに迫られることもあるかと思います。
このようなことはある程度規模の大きくなってきたアプリケーションに、複数の機能を並行して開発している経験があるならイメージが付きやすいと思います。

そんな作業途中のコミットログやレビューでの指摘事項の修正が、すべてmasterブランチのコミットログに残ってしまうのは格好わるいような気がします。
そんなときに今の会社に入って運用されているマージのルールがとてもよかったのでメモしておきます。

Squash Mergeとは

GitHubには3つのマージ方法がある、ということを意識したことがある人はどれぐらいいるでしょうか?
スクリーンショット 2020-06-03 2.16.49.png
▼をクリックすると、このようなメニューが開いてマージの方法を選択することができます。
そのうちの1つがSquash Mergeというもので、マージする際に途中のコミットログが消えて1つのコミットに集約されなおされます。

詳しくはこちらのQiitaが参考になると思います。

GitHubの3種類のマージを理解する - Qiita

ブランチの運用ルール

  • master
    • masterブランチ。本番へデプロイされる
  • develop/XXXX
    • 機能ブランチ。 masterへは「Create merge commit」 する
  • work/XXXX/YYYY
    • 作業ブランチ。 develop/XXXXから派生ブランチとして切る。 develop/XXXXへ「Squash and Merge する

workブランチではPRを作るとき派生元の積極的にコミットを詰んでいってかまいません。レビューの指摘内容とかもここで詰んでいくのが主です。PRを作るとき、ベースブランチは develop/XXXX を選びます。
最終的に、developにマージするとき、「Squash and Merge」を選ぶと developブランチの1つのコミットになります。

developブランチはmasterへマージされる前の最終確認的な運用をします。
このブランチのPRで指摘があった場合は、別途workブランチを切り直して修正したほうがコミットログがきれいでしょう。
最後に「Create merge commit」すると、 workブランチのPR単位のコミットログが並びます。

コミットグラフっぽいものを書いていくとこんな感じでしょうか。

◯[master]
|\
| ◯[develop/X] (まだコミットが積まれてないので本当は枝分かれしてないけどイメージ
| |\
| | ◯[work/X/Y1] wip
| | ◯ feat: 機能1のwork1
| | ◯ fix: 機能1のレビュー指摘事項の修正

developブランチとworkブランチを切って、workブランチで作業します。
develop/Xブランチに向かってPRを切り、workブランチをsquashマージします。

◯[master]
|\
| ◯ [develop/X] work1 (#1)

squashマージすると、develop/XブランチにPR1個分のコミットが1つのコミットとして積まれます
次のworkブランチも切りましょう。

◯[master]
|\
| ◯[develop/X] work1 (#1)
| |\
| | ◯[work/X/Y2] feat: 機能1のwork2

work2のブランチもdevelop/XブランチにSquashマージします。

◯[master]
|\
| ◯[develop/X]
| |
| ◯ work1 (#1)
| |
| ◯ work2 (#2)

develop/Xブランチにwork2の作業内容が1コミットにまとめられて積まれます。

◯[master]
|\
| ◯[develop/X]
| |
| ◯ work1 (#1)
| |
| ◯ work2 (#2)
|/
◯[master] Merge pull request #3 from develop/X

最後にCreate commit and mergeすると、PR単位のコミットログだけが残ります!
コミットログが作業中のようなコメントではなく、PRに紐付いた1つのまとまりとしてコミットされるので、とても見通しがよいのではないでしょうか!

Squash Mergeなんて知らなかったよ、という私なので、とても感動したという話でした。

余談

マージ方法の選択は完全なる手動オペです。最後に選択してマージした方法が記録されるようです。
自動的に選択してもらう方法はないっぽい?なのでしばしば間違いが起こりますが、それについては特に気にしてない感じで運用してます。
うまいことやるとコミットログが綺麗になって気持ちいい、くらいですね。
間違えたからといって目くじらを立てているとつらくなってしまうかもしれません。

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

Githubのeditばかり使う人へ送る"Squash merge workflow"

前書き

この記事は特にGithubEditを使い糞Commitを量産している方に見てもらいたいです。

GithubEditは本当に楽ちんなので巨大ファイルじゃない限りWebIDEとかも使う気になれませんよね。ですが、何回も何回もUpdate ***.xxxを繰り返しているのではないかと思いました。それでLocalCloneしてSoft ResetしてForce Pushしていた過去が私にはあります。

#

実践

まずGithubにて新しいRepositoryを作りましょう。そうしたらREADME.mdを作りますよね、、、????

そしたらこの段階でBranchを切ります。名前はどんなのが良いんでしょうか、王道のdevelopか、それとも?

名前は置いといて、README.mdでも編集してください、この記事を見たら1回Typoするので2回Commitされてるはずです。

次にPull Requestmasterに送り、このままMerge、しないでください。プルダウンリストの二番目にあるSquash and mergeを選択して、Mergeします!

後書き

これならDevelopでくそこみとなんかいもできて、Masterよごさなくていいね!
あと、もじに色つけるのめんどいね、、<font color="Lime">Repository</font>

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

NITICNoobsによるGit/GitHub講座 第4回 〜並行世界を創世する〜

フライさん(loxygen)です。限界開発鯖でのだのだ言っています。フライさんにおまかせなのだ!
説明はあまり得意ではありません。

※この記事は茨城高専生向けに書かれたものです。

お説明

ここからちょっと難しくなってきます。対戦よろしくおねがいします。
今回は「ブランチ」について解説していきます。このお話は、プログラマーを世界を操る神として例えるとしやすい(当社比)ので、になりきって読んでくださると読みやすいかと思います。

ブランチってどんなの?

ブランチというのは、履歴を分岐して記録していくための機能です。噛み砕くと並行世界のようなものでしょうか。
ブランチを新しく作成することを「ブランチを切る」といいます。
ブランチを切る」のは「並行世界を新しく創る」と同義ですね。

どういうタイミングで切っていくんや?

大体は、一つの機能ごと、または機能の小さな集まりごとにブランチを切っていきます。テキストエディタを例に取るなら、

  • テキストを編集する機能を実装するブランチ
  • ファイルを読み込み・保存する機能を実装するブランチ

もちろん他にもいろいろなやり方があります。

masterブランチ

リポジトリを作成すると、必ず一つ、masterという名前がついたブランチが生成されています。いわゆる現実世界です。
masterブランチがメインのブランチになります。プログラムの完成品を置いていく場所ですね。

マージ

並行世界でたくさん変更を加えたあとは、まとめて現実世界にその変更を反映させます。並行世界だけに変更を加えても現実世界は何の変化もないですからね。
この「まとめて現実世界にその変更を反映させる」ことをマージ(merge)と言います。

ブランチの存在意義

変更履歴が必然的に美しくなる

ブランチを切らないで、何も考えずに実装していったとしましょう。
以下の図はコミット履歴を表した図です。
一つの○が一つのコミットで、線がコミット同士のつながりです。同じ色のコミットは同じ機能を実装しています。

image.png

複数の機能の実装が入り組んでしまっていて、履歴がわかりにくくなっています。
今は問題ないかも知れませんが、後から見たり、また他の人が見たりしたときに「:thinking:」となる可能性は十分あります。

ここでブランチを使用してみましょう。

一つ、または機能のまとまりごとにブランチを切っていくと説明しましたね。機能(=同じ色)ごとにブランチを切ってみましょう。
具体的には、こんな感じになります:
image.png
masterブランチの編集履歴が単純化されていますね。複数の機能が混じることなく、機能実装ごとにコミットが分かれています。
上の図と比べたら大分キレイになっていますね。
あまり詳しく考えずに「嗚呼確かにそうかもな」ってだけ思って頂ければ幸いです。

品質を保証できる

ブランチがあることのもうひとつの利点は、masterブランチ上のプログラムの品質を保証できることです。
現実世界でバグが起こったら嫌ですよね。SCP1どころの騒ぎじゃなくなるかもしれません。
そこで、各々のブランチ(=並行世界)でバグを潰したあとにmasterブランチにマージします。

するとどうなるでしょうか。masterブランチ(=現実世界)のバグはかなり抑えられた状態になります。つまりこれは、masterブランチ上のプログラムの品質が保証されているということになりますね。
これがもう一つの利点です。

キーボードかたかたしよう

そろそろ用語の解説に飽きてきたので、ブランチ切ってコミットしてマージしてみましょう。
作業したいフォルダでGit Bashを開いておいてくださいね。

リポジトリを生成してInitial Commitする

リポジトリがないとマジで何も始まらないので作ります。

以下のコマンドを入力してEnterを押してください。
こるくも言っていましたが、$は入力しないでくださいね。

Bash
$ git init (任意のリポジトリ名)

(任意のリポジトリ名)」は、お好きな名前にしてください。

Enterを押すと

Initialized empty Git repository in /path/to/your/selection/(任意のリポジトリ名)/.git/

と表示されます。新しいリポジトリが生成されました。
リポジトリに移動しましょう。

Bash
$ cd (任意のリポジトリ名)

ブランチはコミットを単位に切っていきます。つまりコミットがないとブランチを切ることができません。というわけでInitial Commitをしちゃいましょう。

リポジトリにhello.txtという名前で以下のファイルを生成して保存してください。

hello.txt
I am the smartest person.

そうしたらInitial commitします。
Addを忘れないでくださいね。筆者は忘れてしまいました。

Bash
$ git add --all

git statusを確認する癖をつけましょう。つけて困ることはありません。

Bash
$ git status

すると以下の出力を得ることができます。

Bash
On branch add-new-func
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    new file:   hello.txt

「緑色でnew file: hello.txt」 …「次のコミットで hello.txtが新しいファイルとして登録されるで!」と出力されていますね。新しくhello.txtというファイルを作ったので正常です。

もしhello.txtが赤く表示されていればaddし忘れています。しましょう。
このままコミットして問題なさそうなのでコミットしちゃいましょう。

Bash
$ git commit -m "Initial Commit"

以下のように表示されます。

[master (root-commit) 1234567] Initial Commit
 1 file changed, 1 insertion(+)
 create mode 100644 hello.txt

これでこのリポジトリのコミット履歴はこうなりました:
image.png
Initial Commitだけがある状態です。HEAD(≒現在位置)もInitial Commitにいます。

ブランチを切る

これまで入力と出力を分けて書いていましたが、ここから一緒に書いてしまいます。
入力する際は、$から行末までを入力してください。

ここで並行世界を創世しましょう。新しいコマンドのお出ましです。
以下のコマンドを入力してEnterを押してください。

Bash
$ git branch add-new-func

このコマンドを叩くと、add-new-funcというブランチが切られます。新しく並行世界を創世するわけです。
並行世界を創世しただけじゃ何も始まらないので、創世した並行世界に移動しましょう。

Bash
$ git checkout add-new-func
Switched to branch 'add-new-func'

このコマンドを叩くとadd-new-funcブランチに移動します

ちなみに以下のコマンドを打つと上記の2つの操作を同時に行うことができます。

Bash
$ git checkout -b add-new-func
Switched to a new branch 'add-new-func'

通常はこちらを使います。一行で済んで楽ですからね。

試しにgit statusを叩いてみましょう。

Bash
$ git status
On branch add-new-func
nothing to commit, working tree clean

On branch add-new-func、つまり「add-new-funcブランチにいますよ」と表示されていますね。

さて、一連のコマンドを打った後、コミット履歴はこうなりました。
image.png

・・・?なんも変わってないやん。
なんかadd-new-funcブランチって文字列は認識できるけどそれ以外はなんも変わってないやん。 

この時点ではまだコミット履歴上の変化はありません。それではここにコミットをしてみましょう。

並行世界に歴史を刻む

先程作ったファイルを以下のように変更してください。

hello.txt
I am the kindest human.

そしてコミットします。コミットメッセージは何でも構いません。

Bash
$ git add --all

$ git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   hello.txt

$ git commit -m "Edit hello.txt"
[add-new-func c48284a] Edit hello.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

これでコミット履歴はこうなっています。
image.png

あっ!?なんか縦にズレとる!
そうです。並行世界で変更を加えたのでちょっとズレました

現実世界はどうなってるん?

並行世界(=masterから切ったブランチ)で変更を加えましたが、現実世界(=masterブランチ)はどうなってるんでしょうか。一旦masterに戻ってどんなもんか見てみましょう。

Bash
$ git checkout master
Switched to brach 'master'

このコマンドで現実世界に帰ることができます。-bはいらないので注意してください。
ちなみに、ブランチ間を移動することを「チェックアウト」と呼びます。

ここで、hello.txtの中身を見てみましょう。「cat」というコマンドを使用してみます。
catコマンドは、ファイルの中身を見るコマンドです。
全てGit Bashで完結させたかったので使っていますが、もちろんお好みのエディタで大丈夫です。以降についても同様です。

Bash
$ cat hello.txt
I am the smartest person.

catのあとにファイル名を入力してEnterすると、そのファイルの中身が表示されます。
お気づきかもしれませんが、並行世界で加えた変更がありません
でも消し飛ばされたわけではありません。並行世界に帰ってみましょうか。

Bash
$ git checkout add-new-func
Switched to branch 'add-new-func'

同じコマンドを打ってhello.txtを見てみます。

Bash
$ cat hello.txt
I am the kindest person.

変更が帰ってきました

そうです。並行世界で変更を加えても、現実世界には反映されないようになってるんです。
そりゃそうだろと言えばそりゃそうなんですが、なんだかすごいですよね。本当に世界を行き来してるみたいじゃありませんか?

お練習

一旦masterブランチに帰りましょう。

Bash
$ git checkout master
Switched to branch 'master'.

そうしたら、以下の操作をしてみてください。

・add-new-func-2ブランチを切る。
・hello.txtの中身を以下のように変更する:
  I am the greatest people.
・自由なコミットメッセージでコミットする。

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
以下に答えを書いておきます。行き詰まったり、正解を確認したいときに見てくださいね。

お答え

Answer

まずブランチを切りましょう。

Bash
$ git checkout -b add-new-func-2
Switched to a new branch 'add-new-func-2'.

そしたらファイルの中身を指示されたとおりに変更します。お好みの方法でどうぞ。

保存したらコミットします。

Bash
$ git add --all

$ git status
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   hello.txt

$ git commit -m "(何かしらメッセージをどうぞ)"
[add-new-func d2ad39f] (入力したメッセージ)
 1 file changed, 1 insertion(+), 1 deletion(-)

これで完成です!

このルーチンは生涯で$N$回 ($N \geqq 任意の数字$)回やるので、なんとしてでも身につけておきましょう。

マージする

並行世界に変更を加えただけでは現実世界(masterブランチ)に変更は反映されません。というわけでマージもしてみましょう。

マージの流れ

  1. マージしたいのブランチにチェックアウトします。
  2. git merge <マージするブランチ>をします。
  3. 上手く行けばマージ完了です!

この流れでマージします。上手く行かなかった場合については、次回説明します。

実際にマージしてみる。

今のところ、コミット履歴は以下のようになっているはずです:
image.png
masterブランチからadd-new-funcブランチとadd-new-func-2ブランチが生えている状態です。HEADは動かすのでどこでも大丈夫です。
それでは並行世界の歴史を現実世界に反映していきましょう。

まず、マージするのブランチにチェックアウトします。
今回はmasterブランチにMergeしたいので、masterブランチにチェックアウトしましょう。

Bash
$ git checkout master
Switched to branch 'master'

一応ここでhello.txtを見ておきます。

Bash
$ cat hello.txt
I am the smartest person.

並行世界上では変わっていますが、現実世界上では変わっていませんね。smartest personのままです。

そうしたら実際にマージしてみます。

Bash
$ git merge add-new-func
Updating 1234567..890abcd
Fast-forward
 hello.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

なんかいろいろ出てきましたね。エラーは見た感じ出てないみたいです。
hello.txtを見てみましょう。

Bash
$ cat hello.txt
I am the kindest person.

…おっ?中身が変わりましたね。smartest personkindest personになっています。中身がadd-new-funcブランチのものと同一になりました。

ここで、コミット履歴は以下のようになっています。
image.png
ァ!なんかくっついてる!2
はい。mergeをしたことによってadd-new-funcブランチの歴史がmasterブランチの歴史に併合しました
こうして並行世界の変更が現実世界にも適用されました。

コンフリクト

第5回で詳しく説明しますが、add-new-func-2 ブランチは「コンフリクト」というエラーが発生してマージすることができません
マージしないまま第5回に進んでくださいね。

マージする前の確認作業

上記のエラーを防ぐために、マージ作業を執り行う前にある確認作業をするとお作法がいいです。3これも一緒に第5回で説明しますので、ぜひ頭に置いておいてください。

おまとめ

  • ブランチは並行世界のようなもの
  • masterブランチは現実世界のようなもの
  • ブランチの利点は:
    • 変更履歴が必然的にキレイになる
    • masterブランチの品質を保証できる
  • ブランチの操作には以下のコマンドを使用する:
    • git checkout -b <ブランチ名> …ブランチを切る
      中身はgit branch <ブランチ名>git checkout <ブランチ名>
    • git checkout <ブランチ名> …ブランチ間を移動(チェックアウト)
    • git merge <ブランチ名> …ブランチをマージする

ここまでお疲れ様でした。が、ブランチの話にはあと少しだけ続きがあります。
第4回はかなり膨れてしまったのでここで切り上げますが、第5回で同じリポジトリを使用するので取っておいてくださいね。

おリンク

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 いまここ
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者


  1. いわゆる超常現象を引き起こす物たちです。いきなり精神犯し始めたりします。 

  2. 今回は噛み砕いて説明することを意識しているので分かりやすく書きましたが、今回のケースでは実際はFast-forwardという方法が自動的に選択されてマージされています。
    (Fast-forwardマージが選択された場合は、図のようなコミット履歴にはなりません(masterブランチでのHEADがadd-new-funcブランチのHEADに移動するだけです)。)
    興味のある方は調べてみてください。 

  3. ちなみに筆者は知りませんでした。お作法が悪いですね。 

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

NITICNoobsによるGit/GitHub講座 第1回 ~インストールしてみよう~

自己紹介

こるくといいます。
限界開発鯖 とかいうヤバい開発者コミュニティに所属している茨城の高専生です。
今回からn回に渡り、「Gitを触ったことがない」という方のために、私と他3人でGitとGitHubの使い方をゼロから伝授していきます。

※とりあえずGitをインストールしたい人はこちら

はじめに

1920px-Git-logo.svg.png
Git公式ロゴ

この記事は、茨城高専の2I向けに執筆された記事です。
実際に手を動かしなら読み進めてください。

Gitとは?

Gitとは、ソースコード(実際に書かれたプログラムのこと)を円滑に管理することができるソフトウェアです。
ソースコード以外にも、テキストファイルなら何でも管理できます。
小説やレポートをGit管理してもいいでしょう。
現在、IT業界のデファクト・スタンダードです。
エンジニア、エンジニアになりたい人みんなが使っています。
人権といっても過言ではありません。
さらに共同開発に向いています。

メリット

フォルダが汚くなりがち。
きちんとファイルを体系立てて管理したい。
そう思ったことはありませんか?

Gitは、それを叶えるソフトウェアです。

このフォルダを見てください。
image.png
どう感じたでしょうか。

Gitをつかえば、こんなファイル管理とはおさらばです。
面倒な管理を、あなたに代わってやってくれます。
あと使ってるとかっこいい

バージョン間で、

  • どこが変更されたのか (diff表示)
  • 誰が変更したのか
  • それは何のためなのか (コメント)

といったことの管理を自動でやってくれます。

▼ こんな感じです。
image.png
image.png

しかも、バージョンを指定するだけでそのバージョンに戻れたりもします。

後述しますが、他の人と並行して作業し、お互いの作業の成果物を結合させる、なんてことも出来ます。

と、このようなメリットがあるので共同開発においてGitやGitHubは必要不可欠な存在になります。

逆に、Gitを使わずに共同開発をしようとするとどうなるのでしょうか。

Gitを使わないと...?

  • ファイルの共有にslackやメール、dropboxなどを用いる必要がある。
  • 次の作業に移るごとにバックアップをいちいち作る必要がある。
  • いつ、だれが、どこを編集したのかわからない。
  • 複数人で並行作業した際に、その作業をまとめるのに時間がかかる。

地獄ですね、絶対にこんな開発はしたくありません。確実にハゲマス。

インストール!

では、Gitの素晴らしさがわかったところで、実際にWindowsにGitをインストールしてみましょう。

ダウンロード

まず、以下のリンクに飛びます。
Git - Downloading Package

▼ Gitのダウンロードページ
image.png

ほとんどの場合、64-bit Git-for Windows Setupを選択しておけば問題ありません。
自分の環境にあったものをダウンロードしてください。

インストーラーの起動

ダウンロードしたファイルをクリックしてインストーラーを実行しましょう。
image.png

ライセンス条項が出てきます。
内容を確認して、問題がなければNextをクリック。

インストール先の設定

image.png

ここではインストール先を設定することが出来ます。
お好みで設定していただいて構いませんが、特別な事情が無い限りそのままにしておきましょう

オプションの調整

image.png

基本的にデフォルトのままで構いません。
Use a TrueType font in all console windowsはデフォルトでは無効ですが、後述する「Git bash」の文字がなめらかになります。
デスクトップにGit bashのショートカットを作成したい場合は、On the Desktopを選択してください。

スタートメニューの設定

image.png

Gitをスタートメニューに追加するかどうか尋ねられます。
追加したくない場合、Don't create a Start Menu folderを選択してください。

▼ Windowsのスタートメニュー
image.png

デフォルトのテキストエディタの設定

image.png

Git bash内でテキストを書くとき、どのソフトウェアを使うかの設定です。
デフォルトではVimですが、初心者にはおすすめしません。
Visual Studio Code as Git's default editor選択することをおすすめします。
VS Codeを選択する場合、事前にインストールされている必要があります。
VS Codeはプログラムを書く際のソフトウェア(エディタ)として、かなり有名です。
入れておいて損はないでしょう。
(※ 余談ですが筆者はJetBrains IDE信者です)

▼ VS Code の導入記事
VisualStudioCodeのインストールと日本語化

環境変数の設定

image.png

Gitを使うにあたり、どのような環境にするか聞いてきます。
特に理由がなければ、Git from the command line and also from 3rd-party softwareを選択。

接続方式の設定

image.png

後述する「リモートリポジトリ」を利用する際に、どのような接続方式を用いるか設定することが出来ます。
特に理由がなければ、Use the OpenSSL libraryを選択しておくと後々幸せになれます。

改行方法の選択

image.png

WindowsとUNIX系のOS(macOSやLinuxなど)では、システム内で「改行」を表す方法が異なります。
そのため、後述する「コミット」時に、Windowsの方法のままにしておくか、UNIX系の方法に修正するかどうか聞かれます。
特に理由がなければ、Checkout Windows-style, commit Unix-style line endingsを選択。

Gitが利用するターミナルエミュレーターの設定

image.png

Gitでは、文字で命令を入力して使います(CLI) 。
(GUIでGitを扱う方法もありますが割愛します)

この画面では、デフォルトでWindowsに入っているCommand Promptを使うか、新たにMinTTYを導入するか聞いてきています。

基本的にUse MinTTY (the default terminal of MSYS2)を選択しておくことをおすすめします。

git pull コマンドの挙動の設定

image.png

git pullコマンドにどのような挙動をさせるか設定できます。

今はとりあえずDefault (fast-forward or merge)を設定しておいて問題ありません。

git pullについては第n回で解説しています。

その他の設定

image.png

細かいの設定を調節することが出来ます。
デフォルトのままで問題ありません。

実験的機能の設定

image.png

実験的な新機能を追加するかどうか聞いてきます。
気になる方は選択してみましょう。
ですが実験的な機能は不安定なことも多いので、無理に有効にする必要はありません。

もうひといき!

image.png

インストール時の設定はこれで完了です。
後は自動でインストールを進めてくれます。

完了!

image.png

この画面でインストールは完了です。
すぐに触ってみたい人はLaunch Git Bashを選択しておきましょう。

Nextをクリックしてインストールの作業は完了です。
お疲れさまでした!

ここだけ覚えて!今回のまとめ!

✅ Gitは、バージョン管理システムである。
✅ Gitは、現在のIT業界のデファクト・スタンダードになっている。
✅ Gitは、共同開発で多く使われる。

リンク

次回

NITICNoobsによるGit/GitHub講座 第2回 ~設定しよう~

第1回 インストール編
第2回 設定編
第3回 実際に使ってみよう-基本技能編
第4回 ブランチ(平行世界)編-1
第5回 ブランチ(平行世界)編-2
第6回 GitHub入門編
第7回 fetch/pull編
第8回 issue/Pull Request編

執筆者

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

NITICNoobsによるGit/GitHub講座 第7回 〜fetch/pull〜

自己紹介

どうも、isso0424です。又の名をいっそうです。
高専2年生でぷよぐやみんぐを趣味でやっています。
何やってるかは以下のtwitterやGitHub見てもらえればわかると思います。
twitter
GitHub
今回は僕がGit&GitHub解説を進めていきます。

お目次

  • fetch
  • pull

お説明

fetch

fetchが今回最初に説明するコマンドになります。
これはリモートリポジトリから変更を引っ張ってくるコマンドです。

使い方

git fetch [リモートリポジトリ]

これで終わりって言えば終わりなんですけど、具体的な例を見てみましょう。

もともと以下のようなファイルがあったとします。

demo.txt
I'm genius.

yes

そこに、origin/masterにAさんが変更をpushします。
変更内容は以下の通りです。

demo.txt
I'm genius.

no

そして、この状態であなたが

demo.txt
I`m noob.

yes

という変更を加えようとします。

しかしまだ待ってください。
この状態でファイルを変更しようとするとCONFLICTします。
なぜなら、リモートの変更とローカルの変更が矛盾して衝突してしまうからです。
は?CONFLICT?しらねえよって人は今すぐ
第五回を見てきてください。

このときに,前述のfetchを使います。
というわけで編集前に

git fetch origin

を実行します。
これによりリモートの変更がローカルに適用され、以下のようなログが出ます。

remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 223 bytes | 223.00 KiB/s, done.
From URL
  hoge..fuga master    -> origin/master

これはリモートの変更取ってきたぞ!というGit君からの喜びの叫びです。

さて、変更は取ってきただけでは意味がありません
これをローカルに適用するためマージしましょう。

git merge origin/master

origin/master: remoteリポジトリ"origin"のmasterブランチ

これで、リモートの更新にローカルが追いついたため、pushできるようになります。
この状態で前述の変更を行い、pushすることができます。

git push origin master

これで世界に平和が訪れました。

pull

前回と合わせてmerge,fetchについて学んできました。
毎回fetchしてからmergeしても良いのですが段々面倒になってきます。

そんなワガママな希望にも答えてくれるのがgit君です。
gitにはpullというコマンドがあります。

使い方

git pull [リモートリポジトリ名] [リモートリポジトリのブランチ名]

これにより現在作業しているブランチにリモートリポジトリのブランチをマージすることができます。

つまり、pullはfetchとマージを組み合わせたコマンドと考える事ができます。

先程の例を流用します。
先程の例でfetchをしたタイミングで

git pull origin master

を実行します

この時点で、origin/masterがmasterに対してマージされます。
そのため、この時点でファイルの編集に入ることができます。

あとは先程の例のマージ後と同じです。

おまとめ

  • リモートの変更内容を取ってくる時はfetch
  • リモートのあるブランチの最新状態と同期させたい時はpull

次回はGitHubのPullRequest/Issueについて説明します。

おリンク

1回目〜〜インストール編〜〜
2回目〜〜設定編〜〜
3回目〜〜基本技能編〜〜
4回目〜〜平行世界編-1〜〜
5回目〜〜平行世界編-2〜〜
6回目〜〜GitHub編〜〜
7回目〜〜fetch/pull編〜〜 ←イマココ
8回目〜〜Issue/PR編〜〜

執筆者

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