Git
| Subversion |
目次
- 1 Git
- 2 設定
- 3 GUI
- 4 プロジェクトの作成
- 4.1 プロジェクトコードが保存される3つの場所
- 4.2 リポジトリの作成 (init)
- 4.3 変更を加える
- 4.4 変更の確認
- 4.5 コミットログの確認 (log)
- 4.6 作業を開始する
- 4.7 変更を削除
- 4.8 コミットを打ち消すコミット(revert)
- 4.9 ステージを取り消す (rm)
- 4.10 ファイル名の変更・移動(mv)
- 4.11 リセット(reset)でコミットを書き換える
- 4.12 ワーキングディレクトリの追跡対象外ファイルを元に戻す(clean)
- 5 チーム開発
- 6 ブランチ
- 7 リリースのハンドリング
- 8 リモートリポジトリ
- 9 Tips
- 10 Workflow
Git
- 以下の本からメモなど
設定
- https://note.nkmk.me/git-config-setting/
- レベルが大きい順に適用
種類 | 範囲 | 場所 | レベル |
---|---|---|---|
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のオプション]
git-gui
- git-gui は主にコミットを作成するためのツール
- 左側はインデックスです。ステージされていない変更が上に、ステージされた変更が下に表示
- 右上に表示されているのは diff
- この領域を右クリックすることで、個々のhunk(または個々の行)をステージング
- 右下はメッセージとアクションの領域です。テキストボックスにメッセージを入力し、 “Commit” をクリックすれば、 git commit と同じようなことができます
- “Amend” ラジオボタンを選択すると、 “Staged Changes” 領域に最後のコミットの内容が表示されるので、そのコミットを修正することもできます。 変更をステージしたり、ステージを取り消したり、コミットメッセージを変更したりしたら、 “Commit” を再度クリックすれば古いコミットが新しい内容で更新
$ git gui
GitKraken
Github Desktop
Sourcetree
プロジェクトの作成
プロジェクトコードが保存される3つの場所
作業ツリー -- add --> インデックス -- commit --> ローカルリポジトリ -- push --> リモートリポジトリ
作業ツリー
- 直接ファイルを編集
インデックス(ステージングエリア)
- 作業ツリーとリポジトリとの間のバッファ
- コミット前に一時的に登録しておき、コミットによりリポジトリに格納される
- ステージを設けることにより、関連性の強い変更のみをコミットできるようになる
リポジトリ
リポジトリの作成 (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)
基本ルール
- # 始まりはコメント
- ! 始まりは該当しないものを表す
- / で終わる場合、ディレクトリのみ
- / で始まる場合、リポジトリルート
簡易正規表現(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
チーム開発
- メインブランチからトピックブランチを作成
- メインブランチは開発の中心となっていてチームの大多数が参照しているブランチ
- トピックブランチは一つのトピックに絞った開発を行うブランチ
- 機能実装を行いローカルリポジトリのトピックブランチにコミット
- 定期的にトピックブランチをリモートリポジトリにプッシュ
- メンバーに公開(ローカルブランチの作業は非公開なので)
- 定期的にメインブランチの内容をフェッチしてローカルリポジトリにマージ
- 自分の作業内容と競合していないか定期的にフェッチして、マージもしくはプルして更新しておく
- トピックブランチをメインブランチにマージ
- トピックブランチの開発が区切られたら、メインブランチを最新(フェッチ+マージ もしくは プル)したのちトピックブランチをマージ
- リモートリポジトリのメインブランチにプッシュ
- マージが無事に完了したら、リモートリポジトリにプッシュ、全員がメインブランチを参照できるようになる
ブランチ
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)
[1] 「とあるブランチで作業中だけど、いますぐやりたいことができた。作業がすごく中途半端だからコミットはしたくない。」 というときに、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
© 2006 矢木浩人