-
1. はじめに
- 1.1 バージョン管理について
- 1.2 Gitの簡単な歴史
- 1.3 Gitとは何か?
- 1.4 コマンドライン
- 1.5 Gitのインストール
- 1.6 Gitの初回設定
- 1.7 ヘルプの取得
- 1.8 まとめ
-
2. Gitの基本
- 2.1 Gitリポジトリの取得
- 2.2 リポジトリへの変更の記録
- 2.3 コミット履歴の表示
- 2.4 元に戻す方法
- 2.5 リモートとの連携
- 2.6 タグ付け
- 2.7 Gitエイリアス
- 2.8 まとめ
-
3. Gitブランチ
- 3.1 ブランチの概要
- 3.2 基本的なブランチとマージ
- 3.3 ブランチ管理
- 3.4 ブランチワークフロー
- 3.5 リモートブランチ
- 3.6 リベース
- 3.7 まとめ
-
4. サーバー上のGit
- 4.1 プロトコル
- 4.2 サーバーへのGitのインストール
- 4.3 SSH公開鍵の生成
- 4.4 サーバーの設定
- 4.5 Gitデーモン
- 4.6 スマートHTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 サードパーティホストオプション
- 4.10 まとめ
-
5. 分散型Git
- 5.1 分散型ワークフロー
- 5.2 プロジェクトへの貢献
- 5.3 プロジェクトの維持
- 5.4 まとめ
-
6. GitHub
- 6.1 アカウント設定と構成
- 6.2 プロジェクトへの貢献
- 6.3 プロジェクトの維持
- 6.4 組織の管理
- 6.5 GitHubスクリプティング
- 6.6 まとめ
-
7. Gitツール
- 7.1 リビジョン選択
- 7.2 インタラクティブステージング
- 7.3 スタッシュとクリーン
- 7.4 作業への署名
- 7.5 検索
- 7.6 履歴の書き換え
- 7.7 リセットの解説
- 7.8 高度なマージ
- 7.9 Rerere
- 7.10 Gitを使ったデバッグ
- 7.11 サブモジュール
- 7.12 バンドル
- 7.13 置換
- 7.14 資格情報の保存
- 7.15 まとめ
-
8. Gitのカスタマイズ
- 8.1 Gitの設定
- 8.2 Git属性
- 8.3 Gitフック
- 8.4 Gitによるポリシー適用例
- 8.5 まとめ
-
9. Gitと他のシステム
- 9.1 Gitクライアントとして
- 9.2 Gitへの移行
- 9.3 まとめ
-
10. Git内部構造
- 10.1 内部コマンドと外部コマンド
- 10.2 Gitオブジェクト
- 10.3 Git参照
- 10.4 パックファイル
- 10.5 Refspec
- 10.6 転送プロトコル
- 10.7 メンテナンスとデータ復旧
- 10.8 環境変数
- 10.9 まとめ
-
付録A. その他の環境でのGit
- A1.1 グラフィカルインターフェース
- A1.2 Visual StudioでのGit
- A1.3 Visual Studio CodeでのGit
- A1.4 IntelliJ/PyCharm/WebStorm/PhpStorm/RubyMineでのGit
- A1.5 Sublime TextでのGit
- A1.6 BashでのGit
- A1.7 ZshでのGit
- A1.8 PowerShellでのGit
- A1.9 まとめ
-
付録B. アプリケーションへのGitの埋め込み
- A2.1 コマンドラインGit
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
付録C. Gitコマンド
- A3.1 設定と構成
- A3.2 プロジェクトの取得と作成
- A3.3 基本的なスナップショット
- A3.4 ブランチとマージ
- A3.5 プロジェクトの共有と更新
- A3.6 検査と比較
- A3.7 デバッグ
- A3.8 パッチ
- A3.9 メール
- A3.10 外部システム
- A3.11 管理
- A3.12 内部コマンド
7.3 Gitツール - スタッシュとクリーン
スタッシュとクリーン
プロジェクトの一部に取り組んでいると、作業ディレクトリが散らかっていて、別の作業を行うためにブランチを切り替えたい場合があります。問題は、後でこの時点に戻れるように、中途半端な作業をコミットしたくないことです。この問題に対する答えは、git stash
コマンドです。
スタッシュは、作業ディレクトリの変更されていない状態(つまり、変更された追跡ファイルとステージングされた変更)を取得し、いつでも再適用できる(別のブランチでも)未完了の変更のスタックに保存します。
注記
|
git stash push への移行2017年10月下旬以降、Gitメーリングリストで活発な議論が行われており、
|
作業のスタッシュ
スタッシュのデモンストレーションとして、プロジェクトに入り、いくつかのファイルで作業を開始し、変更をステージングします。git status
を実行すると、変更されていない状態を確認できます。
$ git status
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
ここで、ブランチを切り替えたいのですが、作業中の内容をコミットしたくないので、変更をスタッシュします。スタックに新しいスタッシュをプッシュするには、git stash
またはgit stash push
を実行します。
$ git stash
Saved working directory and index state \
"WIP on master: 049d078 Create index file"
HEAD is now at 049d078 Create index file
(To restore them type "git stash apply")
これで、作業ディレクトリがクリーンになったことがわかります。
$ git status
# On branch master
nothing to commit, working directory clean
この時点で、ブランチを切り替えて他の作業を行うことができます。変更はスタックに保存されています。保存したスタッシュを確認するには、git stash list
を使用します。
$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
この場合、以前は2つのスタッシュが保存されていたため、3つの異なるスタッシュされた作業にアクセスできます。元のスタッシュコマンドのヘルプ出力に示されているコマンドを使用して、ちょうどスタッシュしたものを再適用できます。git stash apply
です。古いスタッシュの1つを適用する場合は、次のように名前を指定して指定できます。git stash apply stash@{2}
。スタッシュを指定しない場合、Gitは最新のスタッシュを想定して適用しようとします。
$ git stash apply
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: index.html
modified: lib/simplegit.rb
no changes added to commit (use "git add" and/or "git commit -a")
stashを保存した際に、Gitがrevertしたファイルを再変更することがわかります。この場合、stash適用を試みた際に作業ディレクトリはクリーンであり、stashを保存したのと同じブランチで適用を試みました。しかし、stashを正常に適用するために、作業ディレクトリがクリーンであることや、同じブランチで適用することが必須ではありません。あるブランチでstashを保存し、後で別のブランチに切り替えて、変更を再適用することもできます。また、stashを適用する際に、作業ディレクトリに修正済みでコミットされていないファイルがあっても構いません。クリーンに適用できないものがあれば、Gitはマージコンフリクトを発生させます。
ファイルへの変更は再適用されましたが、事前にステージングされたファイルは再ステージングされませんでした。そのためには、git stash apply
コマンドに--index
オプションを付けて実行し、ステージングされた変更を再適用するようコマンドに指示する必要があります。これを代わりに実行していれば、元の状態に戻ることができました。
$ git stash apply --index
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
apply
オプションはstashされた作業を適用しようとするだけで、スタック上には残ったままです。削除するには、git stash drop
コマンドにstashの名前を指定して実行します。
$ git stash list
stash@{0}: WIP on master: 049d078 Create index file
stash@{1}: WIP on master: c264051 Revert "Add file_size"
stash@{2}: WIP on master: 21d80a5 Add number to log
$ git stash drop stash@{0}
Dropped stash@{0} (364e91f3f268f0900bc3ee613f9f733e82aaed43)
stashを適用してすぐにスタックから削除するには、git stash pop
コマンドを実行することもできます。
stashの高度な活用
役立つ可能性のあるstashのバリエーションがいくつかあります。非常に人気のある最初のオプションは、git stash
コマンドの--keep-index
オプションです。これは、Gitに対し、作成中のstashにステージングされたすべてのコンテンツを含めるだけでなく、インデックスにも同時に残しておくように指示します。
$ git status -s
M index.html
M lib/simplegit.rb
$ git stash --keep-index
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
M index.html
stashでやりたいことのもう一つのよくあることは、追跡されているファイルだけでなく、追跡されていないファイルもstashすることです。デフォルトでは、git stash
は修正済みでステージングされた追跡済みファイルのみをstashします。--include-untracked
または-u
を指定すると、Gitは作成中のstashに追跡されていないファイルを含めます。ただし、stashに追跡されていないファイルを含めても、明示的に無視されたファイルは含まれません。無視されたファイルも追加で含めるには、--all
(または-a
)を使用します。
$ git status -s
M index.html
M lib/simplegit.rb
?? new-file.txt
$ git stash -u
Saved working directory and index state WIP on master: 1b65b17 added the index file
HEAD is now at 1b65b17 added the index file
$ git status -s
$
最後に、--patch
フラグを指定すると、Gitは変更されたものをすべてstashするのではなく、stashする変更と作業ディレクトリに残しておく変更を対話的にプロンプト表示します。
$ git stash --patch
diff --git a/lib/simplegit.rb b/lib/simplegit.rb
index 66d332e..8bb5674 100644
--- a/lib/simplegit.rb
+++ b/lib/simplegit.rb
@@ -16,6 +16,10 @@ class SimpleGit
return `#{git_cmd} 2>&1`.chomp
end
end
+
+ def show(treeish = 'master')
+ command("git show #{treeish}")
+ end
end
test
Stash this hunk [y,n,q,a,d,/,e,?]? y
Saved working directory and index state WIP on master: 1b65b17 added the index file
stashからブランチを作成する
作業をstashし、しばらくそこに残しておいて、stashした作業と同じブランチで作業を続けた場合、作業を再適用する際に問題が発生する可能性があります。適用によって、その後修正したファイルを修正しようとすると、マージコンフリクトが発生し、解決する必要があります。stashされた変更を簡単に再テストしたい場合は、git stash branch <新しいブランチ名>
を実行できます。これは、選択したブランチ名で新しいブランチを作成し、作業をstashしたときのコミットをチェックアウトし、そこで作業を再適用し、正常に適用された場合はstashを削除します。
$ git stash branch testchanges
M index.html
M lib/simplegit.rb
Switched to a new branch 'testchanges'
On branch testchanges
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: lib/simplegit.rb
Dropped refs/stash@{0} (29d385a81d163dfd45a452a2ce816487a6b8b014)
これは、stashされた作業を簡単に復元し、新しいブランチで作業するための便利なショートカットです。
作業ディレクトリのクリーンアップ
最後に、作業ディレクトリの一部の作業やファイルをstashしたくない場合、単にそれらを削除したい場合があります。それがgit clean
コマンドの用途です。
作業ディレクトリをクリーンアップする一般的な理由としては、マージや外部ツールによって生成された不要なファイルを削除すること、またはクリーンビルドを実行するためにビルドアーティファクトを削除することがあります。
このコマンドは、追跡されていないファイルを作業ディレクトリから削除するように設計されているため、注意が必要です。考えを変えた場合、これらのファイルの内容を取り戻すことはほとんどできません。より安全な方法は、git stash --all
を実行して、すべてを保存してstashに保存することです。
不要なファイルを削除するか、作業ディレクトリをクリーンアップする必要があると仮定すると、git clean
を使用して実行できます。作業ディレクトリの追跡されていないすべてのファイルを削除するには、git clean -f -d
を実行します。これにより、ファイルと、結果として空になるサブディレクトリが削除されます。-f
は「強制」または「本当にこれを実行する」という意味で、Git設定変数clean.requireForce
が明示的にfalseに設定されていない場合に必要です。
何をするのかを確認したい場合は、--dry-run
(または-n
)オプションを付けてコマンドを実行できます。これは、「ドライランを実行し、削除する内容を伝える」という意味です。
$ git clean -d -n
Would remove test.o
Would remove tmp/
デフォルトでは、git clean
コマンドは無視されていない追跡されていないファイルのみを削除します。.gitignore
またはその他の無視ファイルのパターンと一致するファイルは削除されません。すべての.o
ファイル(ビルドによって生成されたファイル)を削除して完全にクリーンなビルドを実行するなど、これらのファイルも削除する場合は、clean
コマンドに-x
を追加します。
$ git status -s
M lib/simplegit.rb
?? build.TMP
?? tmp/
$ git clean -n -d
Would remove build.TMP
Would remove tmp/
$ git clean -n -d -x
Would remove build.TMP
Would remove test.o
Would remove tmp/
git clean
コマンドが何をするのかわからない場合は、常に最初に-n
を付けて実行して、-n
を-f
に変更して実際に実行する前に二重チェックしてください。プロセスに注意するもう一つの方法は、-i
または「対話型」フラグを付けて実行することです。
これにより、clean
コマンドが対話モードで実行されます。
$ git clean -x -i
Would remove the following items:
build.TMP test.o
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each 5: quit
6: help
What now>
この方法で、各ファイルを個別にステップ実行したり、削除のパターンを対話的に指定したりできます。
注記
|
作業ディレクトリのクリーンアップをGitに強制的に要求する必要があるかもしれない奇妙な状況があります。他のGitリポジトリ(おそらくサブモジュールとして)をコピーまたはクローンした作業ディレクトリにいる場合、 |