20200708のGitに関する記事は6件です。

Gitの基本

Gitとは

プログラムのソースコードなどの変更履歴を記録・追跡するための分散型バージョン管理システム
集中型バージョン管理システムのSubversionとよく比較されている。

重要用語

  • ワーキングツリー
  • インデックス
  • ローカルリポジトリ
  • リモートリポジトリ
  • ブランチ

ローカルリポジトリの作成からリモートリポジトリへの反映

$ mkdir /develop/Git-Tutorial
$ cd /develop/Git-Tutorial
$ git init #ローカルリポジトリを作成し、管理に必要な.gitディレクトリが作成される
Initialized empty Git repository in /develop/Git-Tutorial/.git/

$ echo "test1" > test1.txt
$ git add test1.txt #test1.txtをインデックスに追加する
$ git status #変更状況を確認する
$ echo "test2" > test2.txt
$ echo "test3" > test3.txt
$ git status
$ git add . #変更したも(test2.txtとtest3.txt)のを全てインデックスに追加する
$ git commit -m "first commit" #インデックスからローカルリポジトリへ反映する
$ git commit --amend -m"first commit message is changed" #直前のコミットメッセージを修正する
$ git log #コミットログを確認する
$ git remote add origin [追加したいリポジトリのurl] #リモートリポジトリを追加する
$ git push -u origin master #ローカルリポジトリの今いるブランチの内容をリモートリポジトリのmasterブランチに登録する
$ echo "test3 add" > test3.txt
$ git diff #ワーキングツリーとインデックスとの差分を確認する
$ git commit -m "test3 add message"
$ git diff --staged #インデックスと最新のコミットとの差分を確認する
$ git push -u origin master 

リモートリポジトリのデータを取得しマージする

git clone [リモートリポジトリのurl] #リモートリポジトリのデータをローカルにコピーし、管理に必要な.gitディレクトリが作成される
git fetch origin #リモートリポジトリのデータをダウンロードするが、ローカルリポジトリのファイルは更新されない
git log origin #リモートリポジトリから取得した履歴を表示する
git merge origin master #リモートリポジトリのマスターブランチのデータを今いるブランチにマージする
git pull origin master #「git fetch + git merge」でリモートリポジトリから最新のデータを取得し、ローカルリポジトリのマスターブランチを更新する
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitで覚えたコマンドを書いていく

注意書き

勉強しながらメモした物です。
間違っている点があるかもしれませんので、
使用する場合は参考程度にしてください。

なおコマンドのオプションについて省いている部分があります。

Gitじゃないが使うコマンド

cd

「change directory」の略で、ディレクトリを移動する。

cd (相対パス or フルパス)

ls

「list segments」の略で、ファイルやディレクトリ情報を表示する

ls

mkdir

make directory」の略で、ディレクトリを新規作成する

mkdir ディレクトリ名

rm

「remove」の略で、ファイルやディレクトリの削除をする

rm ファイル名

cat

「concatenate」の略で(猫じゃないの!?)、ファイル結合や閲覧で使用する

cat ファイル名

Git コマンド

詳細後日記載予定

git config

git config --global user.name "GitHubのユーザー名"

git config --global user.email GitHubに登録したメール@example.com

git config --global core.editor "エディタ名 --wait"

git status

git commit

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

Git for Windowsの改行コードの設定

Git for Windowsには改行コードを自動変換する機能があります。

しかし、この機能の設定を適切に行わないと、Windows上で作成したコードがLinux上で動作しないなどの不具合が生じます。

この記事では、改行コードを適切に設定する方法について解説します。

Gitの改行コードの自動変換機能

LinuxとWindowsの改行コードは次のようになっています。

  • Linux:LF
  • Windows:CRLF

Gitの改行コードの自動変換の設定項目は「core.autocrlf」です。この設定には以下の3つの値が設定できます。

設定 チェックアウトまたはクローン時 コミット時
true LF → CRLF CRLF → LF
input 変換なし CRLF → LF
false 変換なし 変換なし

どの値を設定するかは、どのOS上でコードを実行するかによって異なります。

  • Linux上で利用する場合 input
    チェックアウトやクローン時には変換せず、コミット時に「CRLF」を「LF」に変換します。Windows上で作成したファイルは「CRLF」となりますが、コミット時に「LF」へ変換されるため、Linux上で正常に動作させることができます。
    また、チェックアウト時は「LF」のままにしておきたいので、変換をしない「input」が適切です。

  • Windows上で利用する場合 false
    Windows上で作成したファイルは「CRLF」となり、チェックアウト時もコミット時も変換する必要はないので「false」を設定します。

Gitの設定ファイル

Gitには以下の3つの設定ファイルがあります。

  • システムの設定ファイル C:/Program Files/Git/etc/gitconfig
  • ユーザーの設定ファイル C:/Users/ユーザー名/.gitconfig
  • ローカルの設定ファイル .git/config *リポジトリ内のみ有効

読み込む順番は「システム → グローバル → ローカル」であり、後から読み込まれた設定によって上書きされます。つまり、ローカルの設定が最優先されます。

core.autocrlf の設定

core.autocrlf の設定は、作成するコードをどのOS上で利用するかによって異なります。

作成するコードがLinuxおよびWindowsの場合

私の場合、TerraformはWindows上で利用するので「CRLF」が必要ですが、AnsibleはLinux上で動作させるので「LF」が必要です。多くの人はLinuxおよびWindows両方のコードを必要とするこのケースに該当するかと思います。以下、LinuxまたはWindowsのどちらをデフォルトにするかによって設定が分かれます。

  • Linuxの改行コードをデフォルトとする場合 

ユーザーの設定ファイル input ローカルの設定ファイル false

デフォルトの設定として「input」(Linux用)を使用し、Windows用のコードを作成する時は「false」を適用する

  • Windowsの改行コードをデフォルトとする場合

ユーザーの設定ファイル false ローカルの設定ファイル input

デフォルトの設定として「false」(Windows用)を使用し、Linux用のコードを作成する時は「input」を適用する

こうすることで、LinuxとWindowsの両方に対応した適切な改行コードを設定することができます。

Linuxの改行コードをデフォルトとする場合

ユーザーの設定ファイル(--globalオプション)に input を設定します。

git config --global core.autocrlf input

設定を確認するには以下のコマンドを実行します。

git config --list --global

システムの設定ファイルに「core.autocrlf」が設定されていても、ユーザーの設定ファイルの方が優先度が高いため、ユーザーの設定ファイルが適用されます。念のため、システム設定ファイル(C:/Program Files/Git/etc/gitconfig)を開いて、「core.autocrlf」の値を「input」にするまたは削除しても良いと思います(システムの設定ファイルの値は、Gitインストール時の設定によって異なります)。

ローカルの設定を行わない限り、ユーザーの設定ファイルが適用されます。従って、ユーザーの設定ファイルに「input」を設定しておけば、そのユーザーが作成するすべてのコードはコミット時のみ「LF」に変換されます。

Windows用のコードを作成する時は、ローカルの設定ファイル(--localオプション)に false を設定します。

Windows用のプロジェクトのディレクトリ内で以下のコマンドを実行します。

git config --local core.autocrlf false

設定の確認を行うには以下のコードを実行します。

git config --list --local

ローカルに設定した場合はユーザーの設定よりも優先されるため、「input」を上書きして「false」となり、改行コードは変換されず「CRLF」のままとなります。

*Windowsの改行コードをデフォルトとする場合は、ユーザーとローカルの設定を逆にすれば可能です。

作成するコードがLinux用のみの場合

ユーザーの設定ファイル(--globalオプション)に input を設定します。

git config --global core.autocrlf input

作成するすべてのコードのコミット時に改行コードが「LF」に変換されます。

作成するコードがWindows用のみの場合

ユーザーの設定ファイル(--globalオプション)に false を設定します。

git config --global core.autocrlf input

すべてのコードに対して変換を行いません。つまり、作成時の改行コード(CRLF)のままとなります。

Gitで管理しないコードの改行コード VS Codeの設定

Gitでコードを管理する場合は、コミット時に自動変換を行うことでLinux上で動作させることができます。

しかし、Gitで管理しないコードはどうでしょうか?

例えば、Windows上でプロビジョニング用のコードを作成し、Linux上にアップロードして使用する場合、そのままでは正常に動作させることはできません。

そのような場合、テキストエディタの機能を使うことで解決できます。

各エディタには似たような機能があると思いますが、以下ではVS Codeについて説明します。

VS Codeには「Files eol」という既定の改行コードを設定する項目があり、以下の3つの値が設定できます。

  • auto(OSの改行コードを使用)
  • \n(LF)
  • \r\n(CRLF)

また、既定の改行コードの他にも、フォルダごとに改行コードを設定することができます。

そのため、通常はLinux用の改行コードを適用し、Windows用のフォルダにのみ「CRLF」を適用することが可能です。

以下では、既定の改行コードを「LF」、フォルダごとの改行コードを「CRLF」と設定する方法を説明します。

  • 既定の改行コードの設定

「設定」を開き、検索窓に「eol」と入力します。

「Files eol」の値を「\n(LF)」に変更します。

  • フォルダごとの改行コードの設定

該当フォルダのルートに「.vscode」フォルダを作成します。その中に「settings.json」ファイルを作成します。

settings.jsonに「CRLF」を設定する以下のコードを記述します。

{
  "files.eol": "\r\n"
}

このフォルダ内の改行コードはすべて「CRLF」となります。

解説は以上です。改行問題に悩まされることが少なくなれば幸いです。

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

Git コミット 管理コマンド

こちらは個人の勉強メモです

ステージング

タイトルからはズレるが、コミットする時にはステージングされたものを全てコミットするしかないので
ステージングの時点で意味のあるコミットを心がけて整理しておくことが必要となる

git status, 今コミットしたらどうなるか

インデックスのステータスの確認

git status

ワーキングディレクトリ (commit に反映されていない作業差分) の状態を表示する
一番大事。とにかく commitする前に現在のワーキングディレクトリの状態を常にこれで確認するべき。
全て commit してあったら何もないのでクリーンですと出る

git add -p, 変更を分割しながらステージング

参考
git add -p 使ってますか?

インデックスにステージングするワーキングディレクトリの新しい作業を分割することができる。
これを使うと、内容を確認しながら ステージング してくれる

git add -p 

で stage this? と7 lines くらいずつ聞いてくれる。

返答で約半分にできる。かなり便利。

なお、すでにこれをするをの忘れて、
ワーキングディレクトリの新規作業を全てステージングしてしまった場合は

git reset HEAD, ステージングの取り消し

git reset HEAD

でステージングしたのを取り消せる。

git reset HEAD
Unstaged changes after reset:
M       lib/posts.js
M       pages/index.js
M       posts/pre-rendering.md

コミットは後から取り消すことを考えると 1 ファイルずつ、 1 関数ずつしたほうがいいので、
作業した後にコミットし忘れたのを気づいたら、上記の git add -p で少しづつステージングして
それからコミットすればコミットを細かく意味がコミットメッセージの明確なものができる

git reset --soft HEAD^
git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        new file:   components/date.js

間違えて

git add .

でワーキングディレクトリの内容を追加してコミットもしてしまったら

git reset --soft HEAD^

した方が確実にコミットを取り消せる。ワーキングディレクトリは巻き戻さずに。

git log

コミットログの表示

git log -p

詳細コミで表示

  • commit の16進数の id
  • した人
  • 日付時間
  • コミットメッセージ
  • ファイル名
  • 差分のテキスト

古い順で表示されていく

commit aaaaaaaaaaa161616161616hexhexhex
Author: yourusername <yourmail@exmaple.com>
Date:   Wed Jul 8 20:21:18 2020 +0900

    add worked hours

diff --git a/2020/07/08.md b/2020/07/08.md
index ccf9e0d..44cce18 100644
--- a/2020/07/08.md
+++ b/2020/07/08.md
@@ -37,11 +37,15 @@
 + 15:00 ~ 17:00
 + 19:00 ~ 20:10

+3+0.5+2+1
+
+6.5時間
+

 ## 次回稼働予定
 明日2020/07/09 木
 09:30 ~ 18:30
-8h
+8時間

commit aaaaaaaaaaa161616161616hexhexhexhex
Author: yourusername <your@mail.com>
Date:   Wed Jul 8 20:11:49 2020 +0900

    Filled whole 2020/08.md report

このように詳細コミでブランチのコミットログが出てくる。

git log --oneline

1行で表示

0cf4e81 (HEAD -> 20200708-daily-report, origin/20200708-daily-report) add worked hours
b5375be Filled whole 2020/08.md report
9ecbd48 applied report template
39ce8fc made 07/08.md
133627b (origin/master, origin/HEAD, master) Merge pull request #2 from kodansha/20200702-daily-report
9d49266 replace hatena to Hatena
d06148b  、。に統一
488fc83 add lines to before and after headers and fence blocks
cb6dbba changed docker to Docker
683f641 integrated things name to `GitHub`, `Qiita`, `Qiita Teams`, `Docker`,
0e2f469 mod view
54d0ad1 Update issue templates
44e086c Update issue templates
043aab3 (origin/hoge, hoge, 20200701-report) wrote 0702
a4a14f4 (origin/20200702-daily-reoprt) add 2020/ 07/ dir, and ad http://01.md
e31b897 first commit
91eb15c Initial commit

1行ずつ コミット id の16進数, コミットメッセージが見れる。

この中からgit rebase -iの引数を選べる

git log --graph --oneline --decorate --all

グラフ で1行でデコって表示

git log --graph --oneine --decorate --all

ブランチが全て枝分かれして色がついて出る。

push される コミットの確認

git でpush前にcommitを確認する方法

git log origin/master..master

これで今何が push されるのか確認できる

git log origin/master..master
commit yourhexyourhexyourhex (HEAD -> master)
Author: yourusername <yourmail@exmaple.com>
Date:   Thu Sep 17 17:51:59 2020 +0900

    add 404 js

このように現在のローカルリポジトリの最新と、リモートリポジトリの最新の差分が取れる。


reflog, 過去のすべての行動の履歴

コミット の管理コマンドという趣旨からは外れるが、関連コマンドとしてあげておく

参考
http://www-creators.com/archives/1116#6

デフォルトではHEADの移動をすべて表示します。
HEAD@{xx}というのは、過去何番目のHEADの状態かということですね。
元に戻したいポイントがわかれば、あとは、git reset --hard で強制的に巻き戻します。

指定のコミットに、ブランチ状態を強制上書き。全部取り消し。 git reset --hard HEAD@{14} のように。

危険なので推奨されていないチームもある。
現在所属しているチームでは reset hard も rebase も, feature ブランチで行うならば非推奨ではない。
コミット を綺麗に保つ方が優先されている。

実際に実行すると

git reflog                                                                             
153a2e9 (HEAD -> 20200820-daily-report, origin/20200820-daily-report) HEAD@{0}: commit: 2020年08月20日の日報                           
2f3704d (origin/master, origin/HEAD, master) HEAD@{1}: checkout: moving from master to 20200820-daily-report
2f3704d (origin/master, origin/HEAD, master) HEAD@{2}: pull origin master: Fast-forward
15e4f2b HEAD@{3}: checkout: moving from 20200818-daily-report to master
e3c21fb (origin/20200818-daily-report, 20200818-daily-report) HEAD@{4}: commit: rm inside secret data
688d299 HEAD@{5}: checkout: moving from 20200819-daily-report to 20200818-daily-report
703b65c (origin/20200819-daily-report, 20200819-daily-report) HEAD@{6}: commit: 2020年08月19日の日報
15e4f2b HEAD@{7}: checkout: moving from master to 20200819-daily-report
15e4f2b HEAD@{8}: checkout: moving from 20200818-daily-report to master
688d299 HEAD@{9}: commit: 2020年08月18日の日報
15e4f2b HEAD@{10}: checkout: moving from master to 20200818-daily-report
15e4f2b HEAD@{11}: checkout: moving from 202008180daily-report to master

このように

  • id
  • 動作の HEAD(現在地)からの位置
  • 動作の内容。commit や checkout など

が 1行ずつ出る
コミット だけの履歴が出る git log と違って checkout などの「行動」も出る。

merge と rebase

mergeとrebaseは共に履歴を統合するコマンドだが、特徴が異なる

merge

変更内容の履歴はそのまま残るが、履歴が複雑になる。

rebase

履歴は単純になるが、元のコミットから変更内容が変更される。そのため、元のコミットを動かない状態にしてしまうことがある。

上司によると

 
merge と rebase は、チームの運用方針に応じて使い分けます。
例えば、履歴を一本化するように運用をするのであれば
トピックブランチに統合ブランチの最新のコードを取り込む場合は rebase を使う

統合ブランチにトピックブランチを取り込む場合は、まず rebase してから merge
というように使い分けます。

とのことで
トピック(リモートの最新の)ブランチをとってくる場合、コンフリクトが起きたら
rebase でこちら側の歴史を改変して
統合ブランチに push する。

git reset

コミットを「ひとます戻る」コマンド

reset は、ブランチの最新コミットから順番に記録を消していくもの
コミットから消したものをワーキングツリーに復活させるのがデフォルトだが、
--hard つけるとワーキングツリーにも残らなくなる

git status                                                                                                  
On branch master                                                                                                                       

No commits yet                                                                                                                         

Changes to be committed:                                                                                                               
  (use "git rm --cached <file>..." to unstage)                                                                                         
        new file:   .browserslistrc                                                                                                    
        new file:   .gitignore                                                                                                         
        new file:   .ruby-version                                                                                                      
        new file:   Gemfile                                                                                                            
        new file:   Gemfile.lock 

git status で見るとコミットはされていないが、ステージングに
Gemfile など大量のファイルが上がっている。
これを

git reset
git status                                                                                                  
On branch master                                                                                                                       

No commits yet                                                                                                                         

Untracked files:                                                                                                                       
  (use "git add <file>..." to include in what will be committed)                                                                       
        .browserslistrc                                                                                                                
        .gitignore                                                                                                                     
        .ruby-version                                                                                                                  
        Gemfile                                                                                                                        
        Gemfile.lock 

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

git reset して git status で確認してみると
git 管理下にステージングされていたファイルが Untracked files にリセットされている。

git reset @^

HEADのalias

git reset --soft HEAD^

git reset --soft HEAD^

をすればコミットが一つ無かったことになる。
つまりやるたびに1つ git log の表示が消えていく

なお、branch を切る前の master から生成する前までも戻れてしまうため、それよりも戻すともう一度 push してある

git reset --hard HEAD^

一つ前のコミットをワーキングディレクトリの作業ごと消し去る。
結構危険なコマンド
対策としてわかりやすい削除すると書いた名前の リモートブランチにバックアップをあげておいてからこれをするという手がある

参考
[Git]コミットの取り消し、打ち消し、上書き

--hardオプション:コミット取り消した上でワークディレクトリの内容も書き換えたい場合に使用。
--softオプション:ワークディレクトリの内容はそのままでコミットだけを取り消したい場合に使用。

git rebase -i, ピンポイント history 修正

コミットログが汚くなってしまった時には必要な歴史修正コマンド
interactive の i、 双方向。会話型。

参考
コミット履歴の改善に役立つ git rebase -i 5つの使い方

git rebase -i <hash>

これで git log で出てきたコミットの id を指定すると

git rebase -i 043a...

pick 89bc90e Update issue templates
pick 3b933ef 2020/07/03 日報を追加します
pick d335193 rebased del 07/02, 07/03
pick 7b956fd add 2020/07/03 daily report
pick 523ce31 Revert "wrote 0702"
pick 2b6286f Revert "Update issue templates"

Rebase 043aab3..2b6286f onto 7b956fd (6 commands)

指定したhashの一つ前までのコミットが vim で開かれる。

ここで pick を 変更する。詳細は

# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message

となっている。

非常に難しく、しくじると非常にスパゲティーなコミットログになってしまう、
git で一番難しいコマンドである (私の知る限りでは)

なお、この操作の後は push -f origin <branchName>が必要

参考
git commit を取り消して元に戻す方法、徹底まとめ 

過去のコミットをhistoryから削除する
git rebase は、ブランチの歴史を修正するためのコマンドで、ブランチ履歴の整理のために、よく使うのgit コマンドの1つです。「i」は「interactive(インタラクティブ)」の略です。

例えば、下記のように取り消したいコミットの直前を指定します。あくまで「リベース」を実行していますので、「どのコミットを取り消したいか?」ではなく、「どのコミットに対して、リベースをかけるか」を引数で指定する点を意識して下さい。

現在のブランチを、 までリベース。
git rebase -i <commit>

一般的に、git rebase -i は、「s(コミットを直前のコミットに統合)」「f(sと一緒。ログも破棄)」などを利用して、ログをキレイに整える目的で利用することが多いでしょう。

git rebase --abort

で今のrebaseをなかったことにできる

git rebase -i e31b897
CONFLICT (add/add): Merge conflict in 2020/07/03.md
Auto-merging 2020/07/03.md
error: could not apply a18f98b... add 2020/07/03 daily report
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply a18f98b... add 2020/07/03 daily report

参考
git rebase --skip を知らなくて沼から出れなくなった

git rebase -i の最中では

git rebase --skip

をしないと抜け出せない場合があるので注意。

git revert

コミットの作業の取り消しコミットを作成する

git revert コミットのハッシュ値

作業ツリーを指定したコミット時点の状態にまで戻し、コミットを行う(コミットをなかったことにはせず、逆向きのコミットをすることで履歴を残す)

例えば hoge.md を削除したコミットを revert に指定すると、
逆方向のコミットとして、hoge.md を作成したコミットが作成された。

本番環境で巻き戻しをする時にはこのコマンドを使うらしい。
それをスムースに行うために 提出する feature ブランチではわかりやすいコミット履歴にしておくことが重要。

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

新規プロジェクトの作成時にGitでやっておくべきこと

プロジェクトを新規作成する際に最初にやるべきことは、Gitコマンドによる開発環境の構築になります。
本記事では、新規プロジェクト作成からgit-flowモデルでの開発環境の構築手順をまとめました。
なお、Composerは既にインストール済みのものとしています。

環境

MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)
PHP 7.4.1
Laravel Framework 7.18.0

Laravelプロジェクト作成

composer create-project --prefer-dist laravel/laravel SampleProject

localhost起動確認

  cd SampleProject
  php artisan serve
  Laravel development server started: <http://127.0.0.1:8000>

ステージング領域作成からプッシュまで

git init
Initialized empty Git repository in 作業ディレクトリのパス
git add .
git commit -m "コミットメッセージ"
git remote add origin リモートリポジトリURL
git push -u origin HEAD

作業ブランチを新規作成

git checkout -b develop
git checkout -b feature/作業ブランチ名
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelで新規プロジェクトを作成する時にGitでやっておくべきこと

プロジェクトを新規作成する際に最初にやるべきことは、Gitコマンドによる開発環境の構築になります。
本記事では、新規プロジェクト作成からgit-flowモデルでの開発環境の構築手順をまとめました。
なお、Composerは既にインストール済みのものとしています。

環境

MacBook Pro (13-inch, 2020, Two Thunderbolt 3 ports)
PHP 7.4.1
Laravel Framework 7.18.0

Laravelプロジェクト作成

composer create-project --prefer-dist laravel/laravel SampleProject

localhost起動確認

  cd SampleProject
  php artisan serve
  Laravel development server started: <http://127.0.0.1:8000>

ステージング領域作成からプッシュまで

git init
Initialized empty Git repository in 作業ディレクトリのパス
git add .
git commit -m "コミットメッセージ"
git remote add origin リモートリポジトリURL
git push -u origin HEAD

作業ブランチを新規作成

git checkout -b develop
git checkout -b feature/作業ブランチ名
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む