20200830のGitに関する記事は8件です。

Gitの用語をわかりやすくまとめる(レポジトリ?コミット?ブランチ?)

プログラミングの勉強日記

2020年8月30日
チーム開発には欠かせないGitの用語をまとめる。

レポジトリ

 Gitの基本的な機能で、時系列でファイルの記録を整理することができる。この記録を管理するデータベースをレポジトリという。データを一元的に管理することができ、最新のデータだけでなく昔のデータも見ることができる。
 すでに誰かが作ったものをコピーしてくることをレポジトリのクローンといい、自分で空のものを作成することをレポジトリのイニットという。

コミットとコミットメッセージ

 レポジトリに現在のファイルの内容を記録することや、その結果作られた記録のことをコミットという。
 Gitではファイルを変更するたびにコミットすることができる。複数のファイルをまとめてコミットすることも1つのファイルをコミットすることもできる。
 コミットしない限りファイルの変更はリポジトリに記録されない。

 コミットするときに、自動的にコミットしたユーザの名前が記録されて、コミットメッセージを残す必要がある。コミットメッセージは、そのコミットでの変更を具体的に記述する。
 チーム開発においては良いコミットメッセージを残すことも大切なスキルとなる。1日の作業において数回以上コミットする方がいい。

ワークツリー

 ワークツリーは普通のフォルダのようなもの。ただ、ワークツリーにあるファイルの変更がGitによって監視されている。
 Gitは、現在のコミットとワークツリーの内容を比較してそこに差があったときに行単位で変更箇所がわかる。ファイルの削除や追加も差分として扱われる。

ブランチとマージ

 ブランチは複数の機能を同時に開発するときに使われる、コミットの系図の枝分かれを指した概念のこと。作業履歴を枝分かれさせて記録する。この枝分かれしたブランチは他のブランチの影響を受けないので、同じリポジトリの中で複数の変更を同時に進めることができる。
 枝分かれしたブランチは他のブランチとマージ(合流)することで1つのブランチにまとめ直すことができる。

コンフリクト

 ブランチはファイルの衝突を先延ばしにすることができるが、完全に衝突を阻止することはできない。同じファイルが2つのブランチでそれぞれ変更されて、Gitで中身を合体できないという状況になるとコンフリクトが発生する。
 コンフリクトが起こるとブランチのマージは一旦保留になり、ユーザが手動でコンフリクトを解消しなければならない。

参考文献

本当の初心者向け!Git入門のための概念から基本用語まで
ブランチとは

 

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

Git clone から pushまで

Gitの使い方

リモートリポジトリからclone→ローカルでブランチ作成→ファイル修正→リモートにpushまでの方法のまとめ

ディレクトリ作成
mkdir test

ディレクトリ移動
cd test

リポジトリからファイルをクローン
git clone URL(githubのリポジトリのURLを貼り付け)

ブランチ作成参考URL
https://backlog.com/ja/git-tutorial/reference/branch/#section2

現在のブランチを確認(ここからの操作はvscodeのターミナルでも可能)
git branch

ブランチの作成
git branch hoge(hoge部分は自分の作りたいブランチ名を設定)

ブランチの変更
git checkout hoge

ここまで進んだらでファイルの編集を行う

編集が終わったらステージング
git add README.md(README.MDの部分はステージングしたいファイル名を記述)
※変更したファイルを全て選択する場合は「git add .」

ステージングした内容をコミット
git commit -m "add new file"

コミットした内容をpush
git push origin master(masterの部分はpushしたいブランチに変更する。今回であれば git push origin hoge)

以上でクローンからリモートへのプッシュまでが完了

この後について

プルリクエスト→マージの流れはターミナルではなく、github上でやればOK

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

個人的によく使うGitコマンド

仕事でもプライベートでもGitを使うことが多いので、
個人的に使うGitコマンドをまとめました。
Gitコマンド忘れた場合は是非、こちらのページを参考にしてください。

clone

  • リモートリポジトリをローカルに複製する
git clone <リポジトリのURL>

remote

  • fork元を追加する
git remote add <名前> <リポジトリのURL>

# よく使うのは
git remote add upstream <リポジトリのURL> #fork元リポジトリを追加する

fetch

  • リモートリポジトリの情報を取得する
git fetch <リモート名>

# よく使うのは
git fetch origin 
git fetch upstream
  • フェッチする際にリモートリポジトリ上で削除されたブランチを削除する
git fetch -p <リモート名>

-pは毎回つけたいので.gitconfigのエイリアスに追加する

[alias]
        fetch = fetch -p

switch

  • ブランチを作成し、作成したブランチへ移動する
git switch -c <ブランチ名> <作成元ブランチ>

よく使うのは
git switch -c <ブランチ名> upstream/master #fork元のmasterから作成する
  • ブランチを移動する
git switch <ブランチ名>

branch

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

よく使うのは
git branch <ブランチ名> upstream/master #fork元のmasterから作成する
  • ブランチを削除する
git branch -D <ブランチ名> #カレントブランチを削除したい場合は一旦他のブランチに移動してから実行する

add

  • 対象のファイルをインデックスに追加する
git add <ファイル>
  • 全てのファイルをインデックスに追加する
git add .
#または
git add --all 

restore

  • 対象のファイルをワークツリーに移動する
git restore --staged <ファイル名>
  • 対象のファイルをワークツリーから破棄する
git restore --worktree <ファイル名>
  • 全てのファイルをワークツリーに移動する
git restore --staged .
  • 全てのファイルをワークツリーから破棄する
git restore --worktree .

commit

  • コミットする
git commit -m "コミットメッセージ"
  • コメントメッセージを修正する
git commit --amend

push

  • プッシュ先のブランチを追跡ブランチとして登録する
git push -u <リモート名> <ブランチ名>:<リモートリポジトリのブランチ名>
  • 強制的にプッシュする
git push --force-with-lease <リモート名> <ブランチ名>:<リモートリポジトリのブランチ名>

pull

  • fetch + mergeではなくfetch + rebaseで実行する
git pull --rebase

merge

  • no fast-forwardでマージする
git merge --no-ff <ブランチ名>

rebase

  • コミットを1つにまとめる
git rebase -i <コミットハッシュ値>

rebase -iについては以下を参考にしてください。
https://qiita.com/KTakata/items/d33185fc0457c08654a5#git-rebase--i---interactive

  • マージコミットを残したままリベースする
$ git rebase --rebase-merges <ブランチ名>

cherry-pick

  • あるコミットの差分をインデックスに追加する
git cherry-pick -n <コミットハッシュ値> 

stash

  • 一時保存(退避)する
git stash push "メッセージ"
  • 一時保存(退避)したものを戻す
git stash apply stash@{数字}

# 数字については
git stash list
# で確認
  • 一時保存(退避)したものを戻して、削除する
git stash pop stash@{数字}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Issue/PRに起こったイベントを取得できるGithub Timeline API

概要

GithubのIssue/PullRequestで発生したイベントを取得できる Timeline API について調べたのでまとめます。

Timeline APIとは

GithubのIssue/PullRequestでは、誰かがアサインされたり、コメントがついたり、レビューされたりといったイベントが発生します。このイベントの一覧を取得できるのが Timeline API GET /repos/{owner}/{repo}/issues/{issue_number}/timeline です。Issue/PRの状況を取得してなんらかの通知をするようなシステムを独自で作るときに便利だと思います。完全に正確ではありませんが、GithubのUIで見られる以下の一連の表示がそのままAPIで取得できると思っておけばOKです。

スクリーンショット 2020-08-30 13.47.58.png

ちなみに、ほぼ同じような機能を持っている Events API というAPIもあって使い分けが謎ですが、調べた限り以下の差分がありました。

  • Events API/Timeline API それぞれどちらかでしか取得できないイベントの種類/情報がある
  • Events APIはIssue/PRに関するイベントに加えてRepositoryに関するイベントを別途取得できるが、Timeline APIはIssue/PRについてしか取得できない

この記事ではEvents APIのことは気にせずTimeline APIについてのみ書きます。

APIの叩き方

Timeline APIを単純に叩くと以下のレスポンスが返ってきます。

{
    "message": "If you would like to help us test the Timeline API during its preview period, you must specify a custom media type in the 'Accept' header. Please see the docs for full details.",
    "documentation_url": "https://docs.github.com/rest/reference/issues#list-timeline-events-for-an-issue"
}

このAPIはまだpreview stateなので、専用のヘッダをつける必要があるとのこと。 ドキュメント にしたがって以下のヘッダをつけて送ることでレスポンスを得ることができます。

Accept: application/vnd.github.mockingbird-preview+json

また、プライベートレポジトリのIssueのTimelineを取得するにはAccess Tokenが必要です。 GithubのSettings からrepoの権限のついたTokenを発行して、以下のヘッダを付与することで、自分が権限を持ったプライベートレポジトリのTimelineもAPIから取得できるようになります。

Authorization: token <発行したToken>

レスポンス

Timeline APIを叩くとだいたいどういうレスポンスが返ってくるのか把握するために、 記事を書いている時点で一番最後にcloseされたrails/railsのPullRequest のTimelineを取得してみます。PR番号が40114なので、

GET https://api.github.com/repos/rails/rails/issues/40114/timeline

を叩くと、以下のようなレスポンスが返ってきます。あくまでだいたいどういうレスポンスが返ってくるのかを見るためにここに示しているだけなので、大したことがなさそうなフィールドは全部省略しています。実際のフルのレスポンスをみたい場合は実際にAPIを叩いてみてください(rails/railsはパブリックレポジトリなのでTokenは不要です)。

[
    {
        "sha": "e0637a5a503fd624b5346c5c51adb447a23d8035",
        "node_id": "MDY6Q29tbWl0ODUxNDplMDYzN2E1YTUwM2ZkNjI0YjUzNDZjNWM1MWFkYjQ0N2EyM2Q4MDM1",
        "url": "https://api.github.com/repos/rails/rails/git/commits/e0637a5a503fd624b5346c5c51adb447a23d8035",
        "html_url": "https://github.com/rails/rails/commit/e0637a5a503fd624b5346c5c51adb447a23d8035",
        "author": {
            "name": "Adrianna Chang",
            "email": "adrianna.chang@shopify.com",
            "date": "2020-08-26T17:30:29Z"
        },
        "message": "Add attr_writer for credentials to Rails::Application",
        "event": "committed",
        ...
    },
    {
        "id": 475768545,
        "node_id": "MDE3OlB1bGxSZXF1ZXN0UmV2aWV3NDc1NzY4NTQ1",
        "user": {
            "login": "rafaelfranca",
            "id": 47848,
            ...
        },
        "body": "",
        "state": "commented",
        "html_url": "https://github.com/rails/rails/pull/40114#pullrequestreview-475768545",
        "event": "reviewed"
        ...
    },
    {
        "sha": "55a668db2937a5fe7b1c8b2f5e1913e54a16e427",
        "node_id": "MDY6Q29tbWl0ODUxNDo1NWE2NjhkYjI5MzdhNWZlN2IxYzhiMmY1ZTE5MTNlNTRhMTZlNDI3",
        "url": "https://api.github.com/repos/rails/rails/git/commits/55a668db2937a5fe7b1c8b2f5e1913e54a16e427",
        "html_url": "https://github.com/rails/rails/commit/55a668db2937a5fe7b1c8b2f5e1913e54a16e427",
        "author": {
            "name": "Adrianna Chang",
            "email": "adrianna.chang@shopify.com",
            "date": "2020-08-26T17:30:40Z"
        },
        "message": "Remove references to secrets.yml from documentation",
        "event": "committed",
        ...
    },
    {
        "id": 3696199379,
        "node_id": "MDIzOkhlYWRSZWZGb3JjZVB1c2hlZEV2ZW50MzY5NjE5OTM3OQ==",
        "url": "https://api.github.com/repos/rails/rails/issues/events/3696199379",
        "actor": {
            "login": "adrianna-chang-shopify",
            "id": 22918438,
            ...
        },
        "event": "head_ref_force_pushed",
        "created_at": "2020-08-26T18:59:38Z",
        ...
    },
    {
        "id": 3696281850,
        "node_id": "MDE1OlJlZmVyZW5jZWRFdmVudDM2OTYyODE4NTA=",
        "url": "https://api.github.com/repos/rails/rails/issues/events/3696281850",
        "actor": {
            "login": "rafaelfranca",
            "id": 47848,
            ...
        },
        "event": "referenced",
        "created_at": "2020-08-26T19:22:34Z",
        ...
    },
    {
        "id": 3696281853,
        "node_id": "MDExOk1lcmdlZEV2ZW50MzY5NjI4MTg1Mw==",
        "url": "https://api.github.com/repos/rails/rails/issues/events/3696281853",
        "actor": {
            "login": "rafaelfranca",
            "id": 47848,
            ...
        },
        "event": "merged",
        "created_at": "2020-08-26T19:22:34Z",
        ...
    },
    {
        "id": 3696281858,
        "node_id": "MDExOkNsb3NlZEV2ZW50MzY5NjI4MTg1OA==",
        "url": "https://api.github.com/repos/rails/rails/issues/events/3696281858",
        "actor": {
            "login": "rafaelfranca",
            "id": 47848,
            ...
        },
        "event": "closed",
        "created_at": "2020-08-26T19:22:34Z",
        ...
    },
    {
        "id": 3696425655,
        "node_id": "MDE5OkhlYWRSZWZEZWxldGVkRXZlbnQzNjk2NDI1NjU1",
        "url": "https://api.github.com/repos/rails/rails/issues/events/3696425655",
        "actor": {
            "login": "adrianna-chang-shopify",
            "id": 22918438,
            "node_id": "MDQ6VXNlcjIyOTE4NDM4",
            ...
        },
        "event": "head_ref_deleted",
        "created_at": "2020-08-26T20:07:17Z",
        ...
    }
]

イベントのリストが返ってきていますね。リスト要素のeventフィールドが、そのオブジェクトが表すイベントの種別です。今回の例だと、イベント種別は、上からcommittedreviewedcommittedhead_ref_force_pushedreferencedmergedclosedhead_ref_deletedですね。PRの一生がAPIでわかってありがてえ。それぞれのイベント種別についてはこの記事の次項でまとめますが、 公式のドキュメント によくまとまってます。

event以外のフィールドを見ると、該当のイベントの詳細がわかります。例えば、committedイベントだと、shaからコミットハッシュが、messageからコミットメッセージがわかりますね。

イベント一覧

どのようなイベント種別が存在するか、それぞれのイベント種別にどのようなフィールドが存在するかを簡単にまとめておきます。自分から見て重要そうなイベントの重要そうなフィールドについてのみ書くので、この記事ではだいたいこんな情報が取れるんだなということを把握するのにとどめて、すべてのイベント種別についてちゃんと知りたい場合は 公式ドキュメント を参照してください。ただし、自分が見つけた範囲でもforce pushを表すhead_ref_force_pushedというイベント種別がドキュメントになかったり、イベント種別によって実際のAPIレスポンスとフィールドのキーが異なったりしたのでもしかしたら公式ドキュメントが実際の仕様に追従できていない部分があるかもしれません。

共通

ほとんどのイベント種別に共通のフィールド。

  • event: イベント種別
  • node_id: global node ididというフィールドも存在するが、イベント種別によってはidがないこともあるのでイベントのユニークなIDがほしいときはnode_idを使うのが良さそう(たぶん)
  • created_at: イベントの発生日時

assigned

Issue/PRがアサインされたこと。

  • actor: アサインした人
    • login: Githubのユーザネーム
    • id: GithubのユーザID
    • avatar_url: アイコンのURL
  • assignee: アサインされた人
    • login
    • id
    • node_id
    • avatar_url

committed

コミットのこと。

commented

Issue/PRにつくコメントのこと。

  • url
  • html_url
  • actor: コメントした人
    • login
    • id
    • avatar_url
  • body: コメントの本文

mentioned

メンションのこと。

  • actor: メンションされた人
    • login
    • id
    • avatar_url

メンションされた人の情報しかなく、メンションした人やメンションがあったコメントに関してはこのイベントでは取得できないみたいです。

review_requested

レビューリクエストのこと。

  • review_requester: レビューをリクエストした人
    • login
    • id
    • avatar_url
  • requested_reviewer: レビューをリクエストされた人
    • login
    • id
    • avatar_url

reviewed

レビューのこと。

  • user: レビュアー
    • login
    • id
    • avatar_url
  • body: レビュー時につけたコメント
  • state: レビューのstate。commented changes_requested approved のいずれか
  • html_url
  • author_association: レビュアーレポジトリ権限。 OWNER COLLABORATOR など

merged

PRのマージのこと。

  • actor: マージした人
    • login
    • id
    • avatar_url
  • commit_id: マージコミットのコミットハッシュ

closed

Issue/PRのクローズのこと。

  • actor: クローズした人
    • login
    • id
    • avatar_url

結論

Timeline APIはIssue/PRの流れがわかってうれしい。Issue/PRを定期的に監視してなにかあったらいい感じで通知するみたいなツールを自分で作りたいときに使えそうです。

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

[学習記録]Gitを習得する

目的

Gitを理解して使いこなせるようになること

達成度の目安

  • 何に使うかわかる
  • (個人的に)使える
  • 分かる
  • 教えられる
  • 展開できる
  • 問題解決できる

習得方法

1つ目 『サルGit』で学ぶ

有名なGit解説のページ: サル先生のGit入門

もちろん入門編から

2020.8.30

インストールしてるGitのバーション: 2.17.1
主に使用しているPCのOS: Ubuntu 18.04.5 LTS

<<何に使うか分かる>>

  • ファイルのバージョン管理を簡単に効率よく行うために使う。
  • 複数人で編集しているときも間違いが起きにくい
  • 古いファイルを保存するのではなく、履歴を残す
  • ファイルの管理をする場所がリポジトリ
  • ローカルPC上には作業用のローカルレポジトリ、サーバー上には共有用のリモートレポジトリ
  • コミット(commit)すると変更点が保存される
  • 作業フォルダがワークツリー、コミット準備用フォルダがインデックス。
  • プッシュ(push)するとリモートレポジトリで共有できる
  • クローン(clone)するとリモートリポジトリをコピーしたローカルレポジトリを作れる
  • プル(pull)するとリモートレポジトリの最新の更新履歴をダウンロードできる
  • 他の変更履歴がある場合はマージ(merge)しないとプッシュできない
  • マージすると、Gitが自動的に変更箇所を統合する
  • 自動的に統合できなかった箇所はコンフリクト(conflict)になる -同じ部分を変更してるときとか

<<(個人的に)使える>>

  • インストールする
  • 設定ファイルの操作 (細かい設定は後で)
  • 新しいリポジトリの作成 ローカルレポジトリはフォルダを作って、コンソールでgit init
  • git statusでディレクトリの状態確認
  • git add <ファイル名>でファイルをインデックスに登録
  • git commit -m <コメント>でコミットする
  • サルGitではBacklogでリモートレポジトリを作成しているけど、GitHubで作った。
  • git remote add <リモートレポジトリの名前> <リモートレポジトリのURL>でリモートレポジトリを登録
  • プッシュやプルの実行時にリモートレポジトリの名前を省略するとoriginが指定されるので、特別事情がなければリモートレポジトリの名前はoriginにする
  • git push <指定するリモートレポジトリ> <ブランチ>でpush。ブランチについては後で。
  • git clone <リモートレポジトリのURL> <複製に使うディレクトリ名>でリモートレポジトリをローカルにクローン
  • 競合の解決: プルして、競合部分を編集して、プッシュする

次は発展編

<<何に使うか分かる>>

  • ブランチ(branch)で変更を分岐させる <作業毎、目的毎、人毎> -無駄な競合を避けられる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git/GitHubを軽く触ってみた

エンジニアになるためにGitとGitHubは必須スキルのため、手を動かして試してみた!

リポジトリ系

リポジトリとはファイルの保管庫。

リモートリポジトリ

専用のサーバに配置して複数人で共有するためのリポジトリです。

ローカルリポジトリ

ユーザ一人ひとりが利用するために、自分の手元のマシン上に配置するリポジトリです。

※プッシュされたほうがリモートレポジトリ。するほうがローカルレポジトリ。
ローカルレポジトリ→リモートレポジトリ
という流れ(どちらも平等だが立場の話)でプッシュされる。

コミット系

intro3_1.png

さるかわより引用 https://backlog.com/ja/git-tutorial/intro/03/

コミットとリビジョンの微妙なニュアンスの違い

コミットとリビジョンは混合しやすい言葉だが、コミットは1つだけのコミットを指すのに対し、リビジョンは指定したコミットまでの全ての反映された成果物を指す。

※コミットの会話例→「例のコミットを送って」→「プッシュされてくる(リポジトリをローカルからリモートに反映されてくる)」
※リビジョンの会話例→「例のリビジョン送って」→「指定したコミットIDまで全てが反映された成果物が送られてくる」

コミットメッセージ

コミットするときにコミットした内容をメッセージとして残す。
「例」
1行目 : コミットでの変更内容の要約
2行目 : 空行
3行目以降 : 変更した理由
だいたいは1行で終わるが、ものによっては3行以降で。

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

intro4_1.png

さるわかより引用 https://backlog.com/ja/git-tutorial/intro/04/

ワークツリー:自分のデスクトップ上のフォルダ等
インデックス:コミットの対象となる差分が入る領域。Git内で作成される。
リポジトリ:コミットの保管庫

よく使うLinuxコマンド

コマンド名 何の略語か 説明
lsコマンド List Segments カレントディレクトリに存在するファイルやディレクトリなどを表示する
cdコマンド Change Directory カレントディレクトリを変更する
vdirコマンド「ぶいでぃあ」 不明 lsコマンドの「カレントディレクトリに存在するファイルやディレクトリなどを表示する」をよりわかりやすく表示する

よく使うGitコマンド

コマンド名 説明
git status ワーキングツリーとインデックスの状態を表示するコマンド
git clone {クローンするgitのURI} 指定したリモートレポジトリ(コピー元)からカレントディレクトリにレポジトリをクローンする。
git commit ステージングされた変更をコミット(確定)する。ステージング≒インデックス
git log 今までのコミット履歴を確認するコマンド。
git add {path/to/file} ワーキングツリーの変更内容をインデックスに追加するコマンド。.を指定した場合は、カレントディレクトリ配下すべてのファイルを対象とする。
git push -u origin master ローカルレポジトリの指定したブランチ(今回の例はmaster)を指定したリモートレポジトリ(今回の例はorigin)へプッシュする。今回は初めてのpushなので-uオプションをつけてmasterブランチを作成している。

感想

Gitを使っているときは出来てる気がするが、一人でいざ使おうとすると速攻で忘れる気がする。
考えてやるものじゃなくて作業の流れとして考えずにやれるように練習しないと。
ついでにQiitaの使い方も学べた。

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

git push をしたら reject されるときの解決法

やったこと

  1. GitHubのアカウントを作る
  2. ローカルとリモートをリンクさせる
  3. ローカルで適当なファイルを作る
  4. コミットしたあとにgit push origin masterを叩く

エラー内容

To https://github.com/○○○○/○○○○.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'https://github.com/○○○○/○○○○.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

解決方法

先に以下のコマンドを実行することでリモートの内容をローカルに反映させる

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

なぜ起きたか

GitHubで新しいリポジトリを作る時にREADME.mdを同時に作るとリモートとローカルに差分がでる

先にリモートの内容をローカルにマージしてからpushしてね、となる

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

macOSで初めてGitを使おうとした時に出るエラーの対処法

Mac のバージョン

Catalina 10.15.6

エラー内容

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

やったこと

以下のコマンドを叩くとポップアップが表示されるため許可をするとGitが使えるようになる

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