tarコマンドで.gitignore内のファイル、フォルダを除外してアーカイブする

たとえば、以下のようなプロジェクトがあったとします。

$ ls -1Fa
.git/
.gitignore
README.md
assets/
dist/
hogehoge.log
index.html
node_modules/
package-lock.json
package.json
public/
src/

tarコマンドで、

$ tar -czf /tmp/backup.tar.gz .

としてしまうと、不要なnode_modulesディレクトリやログ、生成物(dist)も含めてアーカイブされてしまいます。

$ tar -tf /tmp/backup.tar.gz
./
./node_modules/
./node_modules/xxxxxx/
./node_modules/xxxxxx/yyyyy
:
:
:
:
./package-lock.json
./src/
:
:
./.gitignore
./package.json
./README.md
./.git/
:
:
./dist/
:
:
./assets/
:
:
./hogehoge.log
./public/
:
:
./index.html

tarコマンドには除外オプションがあり、不要なファイルは.gitignoreに定義されているので、組み合わせることができないかと調べてみたところ、tarオプションにすでに組み込まれていました。(2014年リリースのバージョン1.28で追加)

GNU tar 1.34 より

‘–exclude-vcs-ignores’

Before archiving a directory, see if it contains any of the following files: ‘cvsignore’, ‘.gitignore’, ‘.bzrignore’, or ‘.hgignore’. If so, read ignore patterns from these files.

The patterns are treated much as the corresponding VCS would treat them, i.e.: 

オプションをつけて実行してみると、.gitignoreに登録しているファイルフォルダを除外してアーカイブされます。

.gitignoreの中身

$ cat .gitignore
node_modules
*.log
dist
$ tar -czf /tmp/backup.tar.gz --exclude-vcs-ignores .
$ tar -tf /tmp/backup.tar.gz
./
./package-lock.json
./src/
:
:
./.gitignore
./package.json
./README.md
./.git/
:
:
./assets/
:
:
./public/
:
:
./index.html

.gitignoreのフォーマットに従って除外されるので、.gitkeepなどの一部Git管理下に置いているものも除外されるようです。

ディレクトリ構造

test/
test/.gitkeep
test/sampledir/
test/sample.txt

testディレクトリのうち.gitkeepはgit addで登録済み

.gitignoreの中身

test/*

tarコマンドでアーカイブ

# オプションなし
$ tar -czf /tmp/backup.tar.gz .
$ tar -tf /tmp/backup.tar.gz |grep test
./test/
./test/.gitkeep
./test/test1/
./test/sample2.txt

# オプションあり
$ tar -czf /tmp/backup.tar.gz --exclude-vcs-ignores .
$ tar -tf /tmp/backup.tar.gz |grep test
./test/

参考

.gitconfigはGitで管理しておいて、git config user.name/user.emailは管理したくない

Gitを使う上で、git config user.name/user.emailの設定は必要。そして.gitconfigなどのdotfilesをgithubで管理したいけど、git config user.name/user.emailはそこに記載したくない。
ということで、gitconfigのincludeを使って別ファイルにしました。

Gitで管理する.gitconfigには

[include]
  path = ~/.gitconfig.local

としておいて、dotfileの展開スクリプト内で

GIT_CONFIG_LOCAL=~/.gitconfig.local
if [ ! -e $GIT_CONFIG_LOCAL ]; then
  echo -n "git config user.email?> "
  read GIT_AUTHOR_EMAIL

  echo -n "git config user.name?> "
  read GIT_AUTHOR_NAME

  cat < $GIT_CONFIG_LOCAL
[user]
  name = $GIT_AUTHOR_NAME
  email = $GIT_AUTHOR_EMAIL
EOF
fi

とすることで、展開スクリプト実行中にプロンプトを出して、user.name/user.emailを入力させました。

実際のdotfileの展開スクリプト

参考

gitのhookをスキップ

コミットする際に、コードのチェックや整形を行うスクリプトをpre-commitフックに入れていました。
あるとき複数の変更が入ったコードを内容ごとに分けてコミットするために、 git add -pでコードの一部分をステージ上げ、コミットしようとしたところ、フックスクリプトによって、
一部分ではなく、変更のあった部分がすべてコミットされてしまうことがありました。

フックスクリプトをgit add -pに対応する修正調べてみましたが、やり方がわからなかったので、
コードのチェック済みという前提で、フックをスキップできる方法を調べたところ、

より、–no-verify (-n) オプションで、pre-commitとcommit-msgフックをスキップできるとのこと。

git commit --no-verify

または

git commit -n

gitのtagをリモートに反映する

[git] gitのtagをリモートに反映する | blog mg ☃ frozen
git でリモートのタグやブランチを削除する方法 – Qiita

1.タグの追加をリモートに反映

ローカルでタグ付け

git tag TAGNAME

リモートに反映。リモート名はoriginの場合、

git push origin TAGNAME

2.タグの削除をリモートに反映

ローカルでタグを削除

git tag -d TAGNAME

リモートに反映。リモート名はoriginの場合、

git push origin :TAGNAME

1.7以降であれば

git push --delete origin TAGNAME

3.リモートタグの一覧

git ls-remote --tags origin