カテゴリー
コンピューター

git stash を使って作業開始時に毎回行う同じ作業(設定修正など)を楽にする

Git で管理しているプロジェクトで、新しく開発作業を始めるたびに一部ファイルの設定部分をローカル開発用に修正する必要がございました。

一旦該当ファイルのバックアップを作り、設定部分を書き換えればよいですの。

ただ、辛いですの><。

リモートリポジトリに push する前に設定ファイルを元に戻す必要があり、面倒ですの><。

そして次の作業に入るときに設定ファイルをローカル開発用に再度変更する必要があり、面倒ですの><。

Git を使って少しでも楽ができないかしら?

以前触ってみて使い途がわからなくなっていた git stash が使えましたので、ご紹介いたします♪

環境

  • OS X 10.11.4 (15E65)
  • git version 2.7.4 (Apple Git-66)

開発作業を始める時の状態

次のような架空でシンプルなプロジェクトを例にとりあげますわ♪

まず最初に git clonegit fetchgit pull などを実行した時の状態となります。

本番環境用のコードのため、そのままでは動きません><。

ローカルの開発環境でも動くように一修正を加えつつ、git push するときだけ本番環境用にコードを戻すという変則的で面倒な運用となります。。。

test_git_stash/
├── kani
└── setting_and_program
zuwai
// setting
group --name=honban
user --name=honban --password=himitsu

// program
init
main1
end
$ git log --all --decorate --graph --oneline
* 11d6da9 (HEAD -> master) clone や fetch や pull した状態
$

ローカル開発用に設定を修正

setting_and_program.bk というファイルでバックアップしました。

そして次のように修正しました。

// setting
group --name=kaihatsu
user --name=kaihatsu --password=naisyo

// program
init
main1
end

git stash でこの変更を退避、開発準備をする

退避

ローカル開発用に修正した設定部分は、今後 git fetchgit pull した時に毎回同じローカル開発用への修正を行います。

うんざりしますので、git stash で退避し、fetch や pull した時に再利用できるように準備しておきます。

$ # ローカル開発用に設定修正直後。作業ディレクトリに差異が生じた。
$ git status
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:   setting_and_program

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	setting_and_program.bk

no changes added to commit (use "git add" and/or "git commit -a")
$ # 退避
$ git stash save --include-untracked "ローカル開発用設定"
Saved working directory and index state On master: ローカル開発用設定
HEAD is now at 0225586 clone や fetch や pull した状態
$ # 退避したことにより、作業ディレクトリが前回コミット直後時点のクリーンな状態となった。
$ git status
On branch master
nothing to commit, working directory clean
$ # 退避のリスト確認
$ git stash list
stash@{0}: On master: ローカル開発用設定
$ # ログにも変化あり
$ git log --all --decorate --graph --oneline
*-.   96ff560 (refs/stash) On master: ローカル開発用設定
|\ \  
| | * 0e7673b untracked files on master: 0225586 clone や fetch や pull した状態
| * d6b0c26 index on master: 0225586 clone や fetch や pull した状態
|/  
* 0225586 (HEAD -> master) clone や fetch や pull した状態$

退避を一旦ローカルリポジトリに適用して準備完了

この時点ですと、コミット直後の状態です。

つまり、ローカル開発用に行った設定修正がなくなってしまいました。

これでは、いけませんね。

ですので、退避した内容をワーキングディレクトリへ適用します。

注意したいのは、git stash pop ではなく、git stash apply を使用します。git stash pop ですと、適用完了後に stash が削除されてしまいますの><。

$ 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:   setting_and_program

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	setting_and_program.bk

no changes added to commit (use "git add" and/or "git commit -a")
$

これで開発準備が整いました。

開発を行う

ブランチを作成、チェックアウトし、開発を行いましょう。

今回の開発内容は、タラバを加える事です。

kani を修正し、ローカル開発環境で実際に動かし、テストも合格しました。

リモートリポジトリへ push する必要がありますので、setting_and_program ファイルはバックアップから元に戻しますの。

それから commit いたしましょう。

$ git checkout -b add-taraba
M	setting_and_program
Switched to a new branch 'add-taraba'
$ vim kani
$ push するために etting_and_program はバックアップから元に戻す。
$ mv setting_and_program.bk setting_and_program
$ git add kani
$ git commit -m "タラバを追加する"
[add-taraba 1fcbe24] タラバを追加する
 1 file changed, 1 insertion(+)
$ git log --all --decorate --graph --oneline
* 1fcbe24 (HEAD -> add-taraba) タラバを追加する
| *-.   96ff560 (refs/stash) On master: ローカル開発用設定
| |\ \  
|/ / /  
| | * 0e7673b untracked files on master: 0225586 clone や fetch や pull した状態
| * d6b0c26 index on master: 0225586 clone や fetch や pull した状態
|/  
* 0225586 (master) clone や fetch や pull した状態

push と後始末

作業が完了いたしましたので、master へとマージしましょう♪

$ git checkout master
Switched to branch 'master'
$ git merge add-taraba
Updating 0225586..1fcbe24
Fast-forward
 kani | 1 +
 1 file changed, 1 insertion(+)
$ git log --all --decorate --graph --oneline
* 1fcbe24 (HEAD -> master, add-taraba) タラバを追加する
| *-.   96ff560 (refs/stash) On master: ローカル開発用設定
| |\ \  
|/ / /  
| | * 0e7673b untracked files on master: 0225586 clone や fetch や pull した状態
| * d6b0c26 index on master: 0225586 clone や fetch や pull した状態
|/  
* 0225586 clone や fetch や pull した状態
$

この master ブランチを、git push いたしまして、開発完了です♪

後始末として、add-taraba ブランチを削除しておきますわ。

$ git branch -d add-taraba
Deleted branch add-taraba (was 1fcbe24).
$

次の開発を始め、退避していたローカル設定を適用する

ようやく本題ですの!

本番環境用の設定だった部分を再びローカル開発用設定へ戻す必要がございます。

つまり、setting_and_program の設定部部の修正と、本番環境用設定が書かれているもともとのファルのバックアップを元通りにいたします。

そのためには、ただ git apply とすればよいですの♪

$ # 新しいブランチにチェックアウトして次の作業を始める。
$ git checkout -b next-feature
Switched to a new branch 'next-feature'
$ # 退避を適用する。
$ git stash apply
On branch next-feature
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:   setting_and_program

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	setting_and_program.bk

no changes added to commit (use "git add" and/or "git commit -a")
$

トラブルシューティング

さらに別のブランチへチェックアウトし作業をして、再度元のブランチにチェックアウトして戻ってきたとします。

その時に再度 git stash apply しようとしたら次のようなエラーとなりました><。

$ git stash apply
setting_and_program.bk already exists, no checkout
Could not restore untracked files from stash
$

これはエラーメッセージにもある通り、untracked files である setting_and_program.bk がすでに存在しているため git stash apply できない、というエラーですわ。

ですので解決方法は単純で、一旦該当する untracked files を削除すればよいのです。

$ # 削除対象を確認
$ git clean -n
Would remove setting_and_program.bk
$ # 削除を実行
$ git clean -f
Removing setting_and_program.bk
$ 

これで stash の退避を適用することができました♪

$ git stash apply
On branch next-feature
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:   setting_and_program

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	setting_and_program.bk

no changes added to commit (use "git add" and/or "git commit -a")

おわりに

そもそも設定ファイルは別ファイルに切り分けて .gitignore ファイルに登録し、トラッキングしないようにするべきですけれどもね♪

以上です。

コメントを残す