-
1. Gitを始めるにあたって
- 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 Resetの解明
- 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 PlumbingとPorcelain
- 10.2 Gitオブジェクト
- 10.3 Gitリファレンス
- 10.4 Packfile
- 10.5 Refspec
- 10.6 転送プロトコル
- 10.7 メンテナンスとデータ復旧
- 10.8 環境変数
- 10.9 まとめ
-
A1. 付録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 まとめ
-
A2. 付録B: アプリケーションへのGitの組み込み
- A2.1 コマンドラインGit
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. 付録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 Plumbingコマンド
7.3 Git ツール - スタッシュとクリーニング
スタッシュとクリーニング
プロジェクトの一部を作業していると、作業中の状態が散らかった状態になり、一時的に別のブランチに切り替えて別の作業をしたいと思うことがよくあります。問題は、後でこの時点に戻れるように、中途半端な作業をコミットしたくないことです。この問題の解決策がgit stash
コマンドです。
スタッシュは、作業ディレクトリのダーティな状態(つまり、変更された追跡ファイルとステージされた変更)を、いつでも(別のブランチでも)再適用できる未完了の変更のスタックに保存します。
注
|
git stash push への移行2017年10月下旬以降、Gitメーリングリストで
|
作業のスタッシュ
スタッシュを実演するために、プロジェクトに入り、いくつかのファイルでの作業を開始し、おそらくその変更の1つをステージします。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
を使用して、直前にスタッシュしたものを再適用できます。古いスタッシュのいずれかを適用したい場合は、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")
スタッシュを保存したときに元に戻したファイルがGitによって再変更されることがわかります。この場合、スタッシュを適用しようとしたときにクリーンな作業ディレクトリがあり、保存元と同じブランチで適用しようとしました。クリーンな作業ディレクトリを持つことと、同じブランチで適用することは、スタッシュを正常に適用するために必要なことではありません。あるブランチでスタッシュを保存し、後で別のブランチに切り替えて、変更を再適用することもできます。スタッシュを適用するときに作業ディレクトリに修正されコミットされていないファイルがあってもかまいません。クリーンに適用できないものがあれば、Gitはマージの競合を発生させます。
ファイルの変更は再適用されましたが、以前にステージしたファイルは再度ステージされませんでした。これを行うには、--index
オプションを付けてgit stash apply
コマンドを実行し、ステージされた変更を再適用するようにコマンドに指示する必要があります。代わりにこれを行っていれば、元の位置に戻っていたでしょう。
$ 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
オプションはスタッシュされた作業を適用しようとするだけで、スタックには残ったままです。これを削除するには、削除するスタッシュの名前を指定してgit stash drop
を実行します。
$ 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)
git stash pop
を実行してスタッシュを適用し、すぐにスタックから削除することもできます。
クリエイティブなスタッシュ
他にも役立つスタッシュのバリアントがいくつかあります。特に人気のある最初のオプションは、git stash
コマンドの--keep-index
オプションです。これは、作成されるスタッシュにステージされたすべてのコンテンツを含めるだけでなく、同時にインデックスに残すようにGitに指示します。
$ 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
スタッシュでやりたいもう1つの一般的なことは、追跡ファイルだけでなく、未追跡ファイルもスタッシュすることです。デフォルトでは、git stash
は修正およびステージされた_追跡_ファイルのみをスタッシュします。--include-untracked
または-u
を指定すると、Gitは作成されるスタッシュに未追跡ファイルを含めます。ただし、スタッシュに未追跡ファイルを含めても、明示的に_無視された_ファイルは含まれません。無視されたファイルも追加で含めるには、--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は修正されたすべてをスタッシュするのではなく、どの変更をスタッシュし、どの変更を作業ディレクトリに残したいかをインタラクティブに尋ねます。
$ 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
スタッシュからのブランチの作成
ある作業をスタッシュし、しばらくそのままにして、その作業をスタッシュしたブランチで作業を続けると、その作業を再適用する際に問題が発生する可能性があります。もし適用が、その後修正したファイルを修正しようとすると、マージの競合が発生し、解決しなければなりません。スタッシュされた変更をもう一度テストする簡単な方法が必要な場合は、git stash branch
を実行できます。これは、選択したブランチ名で新しいブランチを作成し、作業をスタッシュしたときのコミットをチェックアウトし、そこに作業を再適用し、正常に適用された場合はスタッシュを破棄します。
$ 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)
これは、スタッシュされた作業を簡単に回復し、新しいブランチで作業するための素晴らしいショートカットです。
作業ディレクトリのクリーンアップ
最後に、作業ディレクトリ内の作業やファイルをスタッシュしたくないが、単にそれらを削除したい場合があります。そのためのコマンドがgit clean
です。
作業ディレクトリをクリーンアップする一般的な理由としては、マージや外部ツールによって生成されたごみファイルを削除したり、クリーンなビルドを実行するためにビルド成果物を削除したりすることが挙げられます。
このコマンドは、追跡されていないファイルを作業ディレクトリから削除するように設計されているため、かなり注意して使用する必要があります。もし気が変わっても、それらのファイルの内容を復元することは多くの場合できません。より安全なオプションは、git stash --all
を実行してすべてを削除し、スタッシュに保存することです。
ごみファイルを削除したり、作業ディレクトリをクリーンアップしたりしたい場合は、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リポジトリをコピーまたはクローンした作業ディレクトリにいる場合、 |