| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

Git

提供: MyMemoWiki
ナビゲーションに移動 検索に移動

| Subversion |

目次

Git

  • 以下の本からメモなど

設定

種類 範囲 場所 レベル
system システム全体 /etc/gitconfig 1
global 該当ユーザー全リポジトリ ~/.gitconfig 2
local 該当リポジトリ [repository]/.git/config 3


確認 (config)

基本

$git config --global --list
user.email=pppiroto@gmail.com
user.name=piroto

ユーザーインターフェースの色

$git config --global color.ui "auto"

設定 (config)

  • 確認
$git config --list
  • 変更
$git config --global user.name "Hiroto Yagi"
$git config --global user.email "pppiroto@gmail.com"
  • 編集
$git config --global --edit

ヘルプ (help)

$git help
$git help コマンド

GUI

gitk


  • Cygwinでgitkが使えないときの対策メモ
  • gitk はグラフィカルな履歴ビューア。 git log や git grep をパワフルなGUIシェルから使えるようにしたようなもの。 過去に何が起こったかを検索したり、プロジェクトの歴史を視覚化しようとしているときに使う。
  • --all : HEADだけではなく 任意の 参照から到達可能なコミットを表示させる
    • 各ドットはコミットを、線は親子関係を表す
$ gitk [git logのオプション]

0552 gitk.jpg

git-gui


  • git-gui は主にコミットを作成するためのツール
  • 左側はインデックスです。ステージされていない変更が上に、ステージされた変更が下に表示
  • 右上に表示されているのは diff
    • この領域を右クリックすることで、個々のhunk(または個々の行)をステージング
  • 右下はメッセージとアクションの領域です。テキストボックスにメッセージを入力し、 “Commit” をクリックすれば、 git commit と同じようなことができます
  • “Amend” ラジオボタンを選択すると、 “Staged Changes” 領域に最後のコミットの内容が表示されるので、そのコミットを修正することもできます。 変更をステージしたり、ステージを取り消したり、コミットメッセージを変更したりしたら、 “Commit” を再度クリックすれば古いコミットが新しい内容で更新
$ git gui

0551 git gui.jpg

GitKraken


Github Desktop


Sourcetree


プロジェクトの作成

プロジェクトコードが保存される3つの場所

作業ツリー -- add --> インデックス -- commit --> ローカルリポジトリ -- push --> リモートリポジトリ

作業ツリー

  1. 直接ファイルを編集

インデックス(ステージングエリア)

  1. 作業ツリーとリポジトリとの間のバッファ
  2. コミット前に一時的に登録しておき、コミットによりリポジトリに格納される
  3. ステージを設けることにより、関連性の強い変更のみをコミットできるようになる

リポジトリ

リポジトリの作成 (init)

  • Gitのリポジトリは、作業ツリーと同じ場所の.gitディレクトリの中
$mkdir mysite
$cd mysite
$git init

リモートリポジトリの作成

  • 作業ファイル、ワーキングディレクトリがなく、管理ファイルのみのリポジトリ
$git init --bare hoge

変更を加える

ステージングエリアへ追加し、コミット対象とする (add)

$git add hoge.txt
  • サブディレクトリを含めたすべてを登録
$git add .
  • gitがコミットのための追加・変更をステージする
  • 対話形式に対象を選ぶ
$git add -i
    :
*** Commands ***
  1: status       2: update       3: revert       4: add untracked
  5: patch        6: diff         7: quit         8: help
  • 4.まだ追跡していないファイルをステージする
  • 5.コミットする変更箇所を指定する

コミット (commit)

$git commit -m "Comment for this commit"
  • gitが変更を把握しているすべて(追加以外、ステージングとワークディレクトリの差分)をコミット
$git commit -a
  • -mは、一行コミットコメント。省略すると詳細コメント
    • 1行目:コミット内容の要約
    • 2行目:空行(区切りとみなす)
    • 3行目:詳細の説明
直前のコミットを修正 (amend)
  • add してコミットすると、直前のコミットに追加される
  • --no-edit でコミットメッセージの変更をせずに実行
  • 以下のコマンドのみ実行するとコミットコメントのみを修正できる
$ git commit --amend

変更・移動 (mv)

  • ファイル名の変更やファイルの移動
git mv 元ファイル名 後ファイル名

<blockquote>mvは、新しいファイルに対する、add と古いファイルに対する rm を自動で行う</blockquote>

ファイルを無視する (.gitignore)

  • .gitignoreファイルに設定を書き足す
  • 通常のファイルで構成管理対象のため共有されてしまう
  • 複数にマッチする場合、最後にマッチしたパターン
  • Github
  • テンプレート
基本ルール
  • # 始まりはコメント
  •  ! 始まりは該当しないものを表す
  • / で終わる場合、ディレクトリのみ
  • / で始まる場合、リポジトリルート
簡易正規表現(globパターン)が使用可能
  • * は複数文字にマッチ
  • [a,b,c] は括弧内の任意の文字、左記なら、a,b,c
  • [0-9] は文字の範囲
  • ** ネストされたディレクトリにマッチ
    • a/**/z なら、a/z, a/b/z, a/b/c/z などにマッチ
.git/info/exclude
  • .git/info/excludeに記述する方法もある。
  • 他のユーザとは共有されない。

https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff

特定の拡張子を無視する
*.exe
特定のフォルダの中身全てを無視する
bin/
特定のパターンを無視しない
!bin/hoge.exe
フォルダ内の特定拡張子を無視
package/**/*.class
隠しフォルダを無視するが、.gitignoreファイルは無視しない
.*
!/.gitignore

変更の確認

現在の状況を確認 (status)

$git status

差分の確認 (diff)


作業ツリーの変更を表示

  • パラメータなし
$git diff
ステージングとリポジトリとの差分表示

$git diff --cached
ステージング含め作業ツリーのすべてをリポジトリと比較

$git diff HEAD

<blockquote>HEADは現在作業しているブランチの直前のコミットを表すキーワード</blockquote>

コミット同士


 $ git diff 変更前SHA..変更後SHA

コミットログの確認 (log)

コミットの履歴を見る (log)
$git log
オプション 内容
-n <limit> 件数を指定
--oneline それぞれの履歴を一行に圧縮
--stat 追加、削除行数の表示
-p 完全な差分を表示
<file> 指定したフィイルを含むコミットのみ表示
--pretty=format:"%h - %an %ar: %s" 独自のフォーマットを指定
--graph 左側にグラフィカル表示
--decorate コミットログにブランチ名
これまでHEADが辿ってきた履歴を見る (reflog)
$git reflog

誰がいつ書いたコードか調べる(blame)

$ git blame <file_name>

作業を開始する

  • 作業ツリーがgitにどう見えているか
$git status

変更を削除

ファイル指定 (checkout)
git checkout <filename>
すべて (checkout)
$git checkout .
指定 (checkout)
 $git checkout <branch_name>
 $git checkout <commit_id>
 $git checkout <commit_id> <file_name>

コミットを打ち消すコミット(revert)

  • そのコミット内容を打ち消すコミットを新たに加えることで、過去のコミット履歴から指定したスナップショットを無かったことにする
  • 手動でコミット内容を元に戻して、再度コミットするのを自動化
$ git revert <commit_id>

ステージを取り消す (rm)

  • ワーキングディレクトリ、及びステージングエリアからファイルを削除
$ git rm <file_name>
  • cachedをつけると、ステージングエリアからは削除するが、ワーキングディレクトリはそのまま
$ git rm --cached <file_name>

ファイル名の変更・移動(mv)

  • ワーキングディレクトリのファイル名変更と移動
$ git mv <old_file> <new_file>

リセット(reset)でコミットを書き換える

git reset は実行すると取り消しが効かない危険なコマンドであることを留意

直前のコミット取り消し (reset)

  • コミット履歴を過去に遡って以降のコミットをなかったことにする
  • git revert は打ち消し処理も履歴として残るが、resetは履歴が残らない
ステージングエリアから削除
  • git add の取り消し
  • ファイルを指定しなければ、全てのaddを取り消す(直前のコミット状態に戻る)
  • フィアるの変更は破棄されない
$ git reset <file>
コミットのみ
$ git reset --soft HEAD^
すべて
$ git reset --hard HEAD^

コミット後の変更を全部取り消し

$ git reset --hard HEAD

addの取り消し

$ git reset --mixed HEAD

過去の状態に戻す

  • 直前のコミットと完全に一致した状態
  • ワーキングディレクトリの変更内容は全て破棄
$ git reset --hard
  • 特定の時点
$ git reset --hard 昔のコミットのハッシュ値
  • リモートにpush済みの場合、再度pushするとエラーになる
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.
  • 無理矢理pushするには、-f とする
$ git push -f origin master


resetの後最新の状態に戻す
$ git reset --hard ORIG_HEAD

直前のリセットを取り消す

$ git reset --hard ORIG_HEAD

ワーキングディレクトリの追跡対象外ファイルを元に戻す(clean)

  • gitに管理させることなく、ワーキングディレクトリに作成したファイルを一括して削除
  • 対象を確認
$ git clean -n
  • 強制削除
$ git clean -f

チーム開発

  1. メインブランチからトピックブランチを作成
    1. メインブランチは開発の中心となっていてチームの大多数が参照しているブランチ
    2. トピックブランチは一つのトピックに絞った開発を行うブランチ
  2. 機能実装を行いローカルリポジトリのトピックブランチにコミット
  3. 定期的にトピックブランチをリモートリポジトリにプッシュ
    1. メンバーに公開(ローカルブランチの作業は非公開なので)
  4. 定期的にメインブランチの内容をフェッチしてローカルリポジトリにマージ
    1. 自分の作業内容と競合していないか定期的にフェッチして、マージもしくはプルして更新しておく
  5. トピックブランチをメインブランチにマージ
    1. トピックブランチの開発が区切られたら、メインブランチを最新(フェッチ+マージ もしくは プル)したのちトピックブランチをマージ
  6. リモートリポジトリのメインブランチにプッシュ
    1. マージが無事に完了したら、リモートリポジトリにプッシュ、全員がメインブランチを参照できるようになる

ブランチ

Git の真髄は、あらゆるものがブランチのように扱われることにある

ブランチ一覧(branch)

$ git branch
* master
  • リモートのブランチ一覧
$ git branch -r
  origin/HEAD -> origin/master
  origin/fix_chart
  origin/master

ブランチを作る (branch)


  • masterブランチを元にRB_1.0ブランチを作成する
  • masterブランチは、Subversionにおけるtrunkにあたる
 $git branch RB_1.0 master
  • new ブランチをつくる
 $git branch new
  • "*"が打たれているのがcheckout(現在作業ツリーに反映されている)されているブランチ
  • この時点ではブランチが作成されただけで、checkoutはされていない
 $git branch
 * master
   new
  • 新しいブランチをcheckout
$git checkout new
Switched to branch 'new'
  • 確認
$git branch
  master
* new

過去のコミットからブランチを作る

  • git checkout -b <new_branch> <commit_hash>
$ git checkout -b retry 3462e9a

ブランチ名の変更と削除

  • チェックアウトしているブランチに、git brancn -m 変更後名称で、名称変更
  • git branch -d ブランチ名 で、ブランチの削除、-D で強制削除

ブランチを切り替える(checkout)

 $git checkout RB_1.0

Gitでは、ブランチにかかるコストが安い。Gitのブランチはそのブランチで成された最新のコミットだけを記録している

作業途中のブランチを切り替える(stash)

【git stash】コミットはせずに変更を退避したいとき 「とあるブランチで作業中だけど、いますぐやりたいことができた。作業がすごく中途半端だからコミットはしたくない。」 というときに、stashが使えます。 stashを使用すると、コミットしていない変更を退避することができます。 stashで現在の変更を退避して、今すぐやりたい作業をして、退避させていた変更を戻して作業を再開することができます。

  • 未コミットの状態だと、checkoutでブランチを切り替えられない
  • git stash を利用することで、作業状態を保存し、ブランチを切り替えられる
  • 保存した情報を取り出すには、git stach pop

ブランチ間での変更マージ (merge)

  • ブランチ間で変更をマージする方法はいくつかある
    • 直接マージ: 履歴をマージして一緒にしようとする
    • 圧縮コミット: 変更を圧縮(squash)して別なブランチの先頭にコミット
    • チェリーピック: コミットを1つとってきて、現在のブランチに適用

直接マージ

  • マージ先としたいブランチに切り替え
 $git checkout master
 $git merge {マージしたいブランチ}
$ git branch
* directlink
  master
calcutta:favophrase-web hirotoyagi$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.
$ git merge directlink

コンフリクトを解消


  • 以下のようなコンフリクトが発生した場合
Auto-merging lib/photo_list_screen.dart
CONFLICT (content): Merge conflict in lib/photo_list_screen.dart
Automatic merge failed; fix conflicts and then commit the result.
  • 「自動マージに失敗しました。コンフリクトを修正してから結果をコミットしてください。」
  • git status で対象を確認
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

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:   lib/photo_list_screen.dart
        both modified:   pubspec.lock
  • ==== より上の部分が、HEADが参照しているブランチの内容
  • ==== より下の部分が、変更内容
  • どちらかを採用するなどした後、git add , git commit
<<<<<<< HEAD
            .collection('users/${user.uid}/photos')
            .doc()
            .set(data);
=======
          .collection('users/${user.uid}/photos')
          .doc()
          .set(data);

        HttpsCallable callable = FirebaseFunctions.instance.httpsCallable('ocr',
          options: HttpsCallableOptions(timeout: const Duration(seconds:30)));

        var res = await callable.call(
          {'gsUrl':'gs://tenarai-online.appspot.com/users/${user.uid}/photos/$path'});
          //gs://tenarai-online.appspot.com/users/m8dAoyu7s3UJUNQwI1F8E3NcMO72/photos/1628325188064403_IMG_20210807_173119.jpg
        
        await showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Text('Response'),
              content: Text(res.data.toString()),
            );
          },
        );
>>>>>>> 090b91525ddb715a39803757bd7617eeb0e8029a

リリースのハンドリング

タグを打つ (tag)

  • タグの名前(1.0)、タグを打ちたいポイント(RB_1.0)
$git tag 1.0 RB_1.0

タグ一覧の参照

$git tag

タグをリモートにpush (push)

$git push origin {tag_name}
  • 一括でpush
$git push origin --tags
$ git push origin master

未 push コミットの確認

  • git log (リポジトリ名)/(リモートのブランチ名)..(ローカルのブランチ名)
  • 存在しなければ何も出力されない
$ git log origin/master..master

rebase:ブランチから変更を取り出し別ブランチの先頭で再生 (rebase)

  • masterブランチからブランチしたRB_1.0 の変更をmasterブランチに反映させる
  • まず、masterブランチへ戻る
  • rebase で反映させる
$git checkout master
$git rebase RB_1.0

ブランチの削除 (branch)

  • タグを打ってあるため、ブランチを削除しても問題ない
$git branch -d RB_1.0
  • リリースに対してパッチする場合、タグからブランチすればよい
$git branch RB_1.0.1 1.0
$git checkout RB_1.0.1

アーカイブする (archive)

  • --formatでアーカイブ形式、--prefixでディレクトリを指定
 $git archive --format=zip --prefix=phraseit-0.9/ master >master0.9.zip
  • 現在のワーキングディレクトリのHEADをアーカイブ
$ git archive --format=zip HEAD -o export.zip

フォマット一覧

$ git archive -l
tar
tgz
tar.gz
zip

リモートリポジトリ

  • gitはリモートのリポジトリも扱える
  • 自分の作業を共有、コピーの取得など可能

リモートリポジトリのクローン

  • リモートリポジトリで作業を始めるためにはクローンの作成が必要
  • 作業を始めるリモートリポジトリの完全なコピーを作成する
$git clone ssh://root@rev.typea.info/var/www/git/phraseit

git remote

作業 コマンド
追加 git remote add
削除 git remote rm
確認 git remote -v
URL変更 git remote set-url
名前変更 git remote rename

ローカルリポジトリをリモートを作成してpushする例


  • サーバー側でリポジトリを作成
# git init --bare wol_swift.git
  • ローカル側からリモート設定
    • リモートリポジトリ登録
    • ブランチ名の確認
    • push
$ git remote add origin ssh://root@repo.typea.info/var/www/html/git/_samples/wol_swift.git
$ git branch
* main
$ git push origin main

リモートリポジトリの確認

$ git remote -v
origin	ssh://root@repo.typea.info/var/www/html/git/_samples/wol_swift.git (fetch)
origin	ssh://root@repo.typea.info/var/www/html/git/_samples/wol_swift.git (push)

リポジトリ公開時のApache設定

https://git-scm.com/book/ja/v2/Git%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC-Smart-HTTP

  • /etc/httpd/conf.d/git.conf を作成
<VirtualHost *:80>
    ServerName git.taisetsu.typea.info
    DocumentRoot /var/www/git
    SetEnv GIT_PROJECT_ROOT /var/www/git
    SetEnv GIT_HTTP_EXPORT_ALL
    ScriptAlias /git/ /usr/libexec/git-core/git-http-backend
    RewriteEngine On
    RewriteCond %{QUERY_STRING} servive=git-receive-pack [OR]
    RewriteCond %{REQUEST_URI} /git-receive-pack$
    RewriteRule ^/git/ -[E=AUTHREQUIRED]
    <Files "git-http-backend">
        AuthType Basic
        AuthName "Git Access"
        AuthUserFile /var/www/git/.htpasswd
        Require valid-user
        Order deny,allow
        Deny from env=AUTHREQUIRED
        Satisfy any
    </Files>
</VirtualHost>
  • 必要に応じて、ServerNameをhostsに記述
  • リポジトリのオーナーを変更
# chown -R apache /var/www/git
  • パスワードファイルの生成
# htpasswd -c /var/www/git/.htpasswd {ユーザー名} 
New password: 
Re-type new password: 
Adding password for user root
  • push 時に httpsでないと、403エラー config の設定を ssh: とし、ユーザー名もホスト名の先頭に付与するまた、パスは実際のパス
> git remote set-url origin ssh://root@git.taisetsu.typea.info/var/www/git/hoge.git

Webからリポジトリ内容を閲覧(GitWeb)

同期

リモートブランチの確認(branch -r)

$ git branch -r
  Github/master
  origin/master 

git fetch

  • ローカルリポジトリにないリモートリポジトリのコミットオブジェクトをローカルリポジトリに追加
  • リモートブランチの履歴取り込。このとき更新されるのは、あくまで指定したリモートブランチに対応する「リモート追跡ブランチ」です。(git fetch はローカルブランチ、インデックスや作業ツリーに一切の変更を加えません。)

git merge

  • 両ブランチで変更されたファイルのスナップショットを再作成して,新しいコミットオブジェクトを自動生成
  • 更新されたリモート追跡ブランチを、現在のブランチにマージする
$ git merge FETCH_HEAD

git pull

  • git fetch と git merge を合わせた動作
  • git pull <remote> <branch>
$ git pull origin master

Tips

日本語ファイル名を表示させる(文字化け対応)

  • 日本語ファイル名は "\nnn" にエスケープされてしまって読めない。以下の設定を追加することで日本語ファイル名が表示されるようになる。
$ git config --global core.quotepath false

Gitでやらかしたときに使えるコマンド

Workflow

  • 拾いもの

Git workflow.jpeg