20191129のGitに関する記事は17件です。

【Git】エイリアス晒す&書き方まとめ

Git Advent Calendar 2019 1日目です。
2日目は@100さんの【VRChat】継続的なクロスプラットフォーム対応です。

TL;DR

.gitconfig
[alias]
    #以下の3種は全て同じコマンドが実行される

    # 単純な置き換え
    st = status -uno

    # 先頭に!を付けると、その後のコマンドを外部コマンドとして("git "を付けずに)シェルスクリプトで実行
    stex = !git status -uno

    # 関数を使うと引数を任意の場所に展開できる
    stfunc = !"f(){ git stauts -uno \"${@}\"; };f"

はじめに

Gitも気付いたら2.24.0になっていて(2019/12/01現在)、git switchとか新しいコマンドが生えててどんどん使いやすくなっている訳ですが、それでも我々は記憶量とタイピング量を減らしたい。人類の脳みそはそんなに強くない。
という訳でGitというよりシェルスクリプトの初級編、エイリアスについて。CUIをちょっと楽にしような。

エイリアスとは

Gitのコマンドの「別名」を付ける機能のこと。
タイピング量を減らしたり、覚えやすいコマンド名に置き換えるために利用される。git エイリアス名と打つと設定したコマンドが実行される。つまりシェルに任意のコマンドを一行で展開する機能として使えるので、複数のコマンドを繋げたり、それ単体で簡単なシェルスクリプトを組む芸当も可能。

設定ファイルの場所

エイリアスの設定を行うにはgit config --global alias.エイリアス名 エイリアス先のコマンドを打つ、などとエイリアスの公式ドキュメントには書かれている。が、後述する特殊文字のエスケープに加えて「git configコマンドを解釈するときのエスケープ」が必要になるため非常に面倒くさい。それよりはconfigファイルを弄ってしまった方が楽だと思う。

configファイルの場所は参考URLを参照のこと。
参考:gitconfig の基本を理解する

以下ではユーザー単位の~/.gitconfigに記述するものとする。
.gitconfigなどの設定ファイルに[alias]と書くことで、それ以降~次の[---]までがエイリアスの設定として認識される。
基本的には1行 = 1コマンドである。複数行に記述したいときは行末に\を置く。

書き方まとめ

単純な置き換え

.gitconfig
[alias]
st = status -uno

最も単純な方法。エイリアスに登録した文字列が置き換わる。
この場合、git stと打つとgit status -unoが実行される。従って、Gitのコマンド以外は指定できない。
オプションを付与したい場合は後ろに追記する。この場合、例えばgit st -sと打てばgit status -uno -sが実行される。

外部コマンド

.gitconfig
[alias]
stex = !git status -uno

エイリアスの冒頭に!を付与することで、git ~が丸ごと置き換えられる。この置き換え先はシェルコマンドとして解釈される。従ってGit以外のコマンドを利用することが可能。
ちなみにこの方法で「エイリアスのエイリアス」を無限に作成できる。

.gitconfig
[alias]
#特に意味はない
super_status = !git st
extra_status = !git super_status 
ultra_status = !git extra_status

また、適切な制御記号を入れることで複数のコマンドを繋げることが可能。

.gitconfig
[alias]
#git fetchが完了したらログを直近20個分出して、最後にstatusを確認
now = !git fetch; git graph -20 --date-order; git st

以下はエイリアスというよりシェルスクリプトの勉強内容だが、コマンド間の制御記号と効果についてはこんな感じ。

記号 効果
; 順番に実行
&& 前のコマンドが成功したら実行
|| 前のコマンドが失敗したら実行
| 前のコマンドの標準出力を次のコマンドの標準入力にする
& 前のコマンドをバックグラウンドで実行(つまり待たない)

一番最後の&はコマンドの途中に入れるとエイリアス(の実行シェル)が終了しても終了しないので、基本的には外部のプログラム(エディタなど)を起動したい時などに利用する。

関数にする

.gitconfig
[alias]
stfunc = !"f(){ git stauts -uno \"${@}\"; };f"

シェルスクリプトはf(){ コマンド }で関数を定義し、fでその関数を実行できる。従って"f(){ コマンド };f"で関数を定義し、即座に実行できる。両端の""が無いとsyntax errorとなる。
このとき、変数${1}~${n}に個別の引数が、${@}に全ての引数が、${#}に引数の数が、それ以外にもいろいろ入る。
参考:初心者向けシェルスクリプトの基本コマンドの紹介 #特別な変数

見やすさのために改行したい場合は以下の様に、行末に\を書く。これはシェルに渡される時点で一行に戻されて実行される。

.gitconfig
[alias]
stfunc = !"f(){ \
    git stauts -uno \"${@}\";\
 };f"

なお引数を使うための方法として!sh -c \"git status\"のような記述方法もあるが、「プロセスが多重起動すること」「Gitのエスケープとshのエスケープが両方必要になって記述が面倒くさくなること」から投げ捨てた方が良い、とのこと。

参考:関数の使用方法 UNIX & Linux コマンドおよびシェルスクリプトリファレンス
参考:位置パラメーターの一括展開 $* $@ "$*" "$@" の違いを知れ!!

登録時の注意点

大文字/小文字について

git statusなどの本来のGitのコマンドは大文字/小文字を区別しなければならない。しかし、エイリアスでst = statusと設定した場合は大文字/小文字を無視する。つまりgit STでもgit Stでもgit sTでも全てgit stと同じ動作をする。逆に言うと大文字/小文字で別のエイリアスを登録することはできない。
ついでにGitのコマンドと同名かつ大文字/小文字違い、つまりSTATUS = statusなどとしても、fatal: cannot handle STATUS.exe as a builtinとして怒られる。名前探索の最初の段階でgit-~と一致するか否かを見ている模様。

外部コマンドが動作するディレクトリ

単純な置き換えのときはカレントディレクトリから移動することは無い。しかし、!によって外部コマンド呼び出しにするとそのときのgitが動いている(.gitフォルダがある)ディレクトリに移動してから動作する。

.gitconfig
[alias]
pwd = !pwd

試しにこういうエイリアスを作ってpwdgit pwdを見比べてみる(Gitのリポジトリ位置は/c/source/alias_test/RemoteRepoとする)。

Terminal
usern@me MINGW64 /c/source/alias_test/RemoteRepo (master)
$ cd Child/

usern@me MINGW64 /c/source/alias_test/RemoteRepo/Child (master)
$ pwd
/c/source/alias_test/RemoteRepo/Child

usern@me MINGW64 /c/source/alias_test/RemoteRepo/Child (master)
$ git pwd
/c/source/alias_test/RemoteRepo

カレントディレクトリを/Childに移動してからpwdを記述すると当然(Gitのレポジトリ)/Childが表示されるが、git pwdと打つと(Gitのリポジトリ)に移動していることが分かる。これは公式ドキュメントに書かれている。

Note that shell commands will be executed from the top-level directory of a repository, which may not necessarily be the current directory. GIT_PREFIX is set as returned by running git rev-parse --show-prefix from the original current directory.
注:それらの(!を付与された)シェルコマンドはリポジトリのトップレベルディレクトリで実行されます。これはカレントディレクトリと一致するとは限りません。このとき、カレントディレクトリでgit rev-parse --show-prefixを実行した結果がGIT_PREFIXにセットされます。

このため、エイリアスでGit内のファイルを参照したい場合などはリポジトリのディレクトリからの相対位置だけ考えれば良い。
一方でgit ls-filesのようなカレントディレクトリの位置によって結果が変わるコマンドを使いたい場合、この挙動は困るかもしれない。公式ドキュメントによれば変数GIT_PREFIXに相対パスの値が入るよ、とのことなので、下記のようにcd ${GIT_PREFIX}を先に書いてあげれば良いようだ。

.gitconfig
[alias]
# git ls-filesを行うだけのエイリアス。これ自体に意味は無い
ls-files-alias = !cd ${GIT_PREFIX} && git ls-files;

参考:git aliasの外部コマンド呼び出しはgit管理下のルートディレクトリから呼ばれる

エスケープの仕様(未完成)

特に関数を使う場合、いくつかの特殊文字のエスケープが必要となる。関数を"f(){ コマンド };f"で記載する都合上、""に囲まれた範囲のどの文字をシェルに展開すればよいのかを明示しなければならない。
確認できる範囲では、"\は少なくとも\でエスケープする必要がある。例外として、if直後の[...]ブロック中は(これ自体が単体のコマンドなので)エスケープしなくても動く……たぶん。
どの文字がどの状況でエスケープ対象になるのか、ご存知の方がいらっしゃれば編集リクエスト頂きたく。

晒す

手元に設定しているエイリアス一覧はこんな感じ。
下の方にあるやたら長いエイリアスは以下の記事参照。
特定時点の特定ファイルをエディタで開くgit-alias
【git】checkoutせずに特定ブランチをpullするエイリアス

.gitconfig
[alias]
    # git alias : 現在登録してあるエイリアス一覧を表示する. 
    # 長いエイリアスが多いので前方42文字で切っている
    alias = !git config --get-regexp '^alias\\.' | sed 's/alias\\.\\([^ ]*\\) \\(.*\\)/\\1\\\t => \\2/' | cut -c 1-42 | sort

    # git st : トラッキングしているファイルのステータスのみ表示. 
    st = status -uno

    # git graph : logを良い感じにグラフで表示.
    # 全てのブランチを表示したいので --remotes と --branches を追加している
    graph = log --graph --date=format:'%m/%d %H:%M' --format=format:'%C(yellow)%h %C(cyan)%ad %C(green)%an%Creset%x09%s %C(red)%d%Creset' --remotes --branches

    # git now : 現在欲しい情報(直近20個のログとステージング)を更新してから表示. 
    # 便利だが、同名のフリーコマンドがあるらしいので別名にした方が良さそう.
    now = !git fetch; git graph -20 --date-order; git st

    # git F5 : git now が他のコマンドと被っているので別名を模索していた最中の産物
    # なんとなく「F5キーって更新っぽいよな」というだけ。
    F5 = !git now

    # git cm : commitの省略形。そんだけ。
    cm = commit
    cmm = commit -m
    cmam = commit -a -m

    # mergetool系
    # 大本の設定とかはこちらを参考にした → https://qiita.com/kobake@github/items/fb317b4fdacad718a4b2
    # difftoolをそのまま起動するとシェルが待機状態になってしまうので、関数形式にして末尾に`&`を付与し並列実行させている.
    windiff = "!f(){ git difftool -y -d -t WinMerge /"${@}/" & };f"
    winmerge = mergetool -y -t WinMerge
    # git winshow <コミットハッシュ等> : 一つ前のコミットと比較してWinMergeで表示する.
    winshow = "!f(){ git difftool -y -d -t WinMerge ${1}~..${1} & };f"

    # git-flow系
    # ぶっちゃけコマンドを毎回忘れるから設定しておくだけ
    fi = flow init -d
    ff = flow feature
    fr = flow release
    fh = flow hotfix

    #情報取得系
    # git where <コミットハッシュ>  そのコミットが属しているブランチを表示.
    where = branch --contains
    # git here : 現在のリポジトリのパスを取得. pwdコマンドに近いが表記がWindowsオリジナルに近くなる.
    here = rev-parse --show-toplevel
    #git showコマンドだと--onelineオプションが効かない気がするので、等価な働きをするlog -1を使う
    show2 = log -1

    # git show-file <コミットハッシュorブランチ名> <ファイルパス>
    # 詳細はこちら(https://qiita.com/YamEiR/items/7002ec1869717b7da9ce)
    # 特定の時点(コミット/ブランチ等)の特定ファイルをエディタで開く.
    # 作業ディレクトリは(Windowsの場合)AppData/Local/Temp/git-show/ であり、1週間以上経過すると削除される.
    # git config core.editorに適当なエディタを設定していないと動作しないため注意.
    show-file = "!f(){ \
        if [ $# -eq 2 ];then \
            local repo=$(git rev-parse --short ${1});\
            if [ "${?}" -ne 0 ]; then \
                return 1;\
            fi;\
            git ls-files ${2} > /dev/null || return 1 ; \
            local f_path=${2};\
            local f_name=${f_path##*/};\
            local f_row_name=${f_name%.*};\
            local f_ext=${f_name##*.};\
            mkdir -p /tmp/git-show;\
            git show ${repo}:${f_path} > /tmp/git-show/${f_row_name}-${repo}.${f_ext};\
            if [ $? -eq 0 ];then \
                $(git config core.editor) /tmp/git-show/${f_row_name}-${repo}.${f_ext} &\
            fi;\
        else \
            echo \"syntax error : git show-file <repo-name> <file-path>\";\
        fi;\
        find /tmp/git-show/* -mtime +7 -exec rm {} + ;\
    };f"

    # git pull-o ブランチ名
    # 詳細はこちら(https://qiita.com/YamEiR/items/630fcdd3c4c1984fdc2a)
    # 任意のブランチがfast-forward可能な場合にpullする
    pull-o = "!f(){ \
        local branch_name=${1};\
        local current_branch=$(git symbolic-ref --short HEAD);\
        local branch_remote=$(git config branch.${branch_name}.remote);\
        local branch_path=$(git config branch.${branch_name}.merge);\
        if [ ${branch_name} = ${current_branch} ];then \
            git pull ${branch_remote} ${branch_name} --ff-only;\
            return ${?};\
        else \
            git fetch ${branch_remote} && \
            git fetch . refs/remotes/${branch_remote}/${branch_name}:${branch_path};\
            return ${?};\
        fi;\
    };f"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

最近ぼくがVimに設定したこと

ハロー、ハッピーVimmer :tada:

今日はVim pluginと、それに対する僕の設定を紹介します。

マクロの実行をdot repeat可能にした

まずはシンプルかつ最強なやつです。

dot-repeatは通常1つの動作のみを繰り返しますが、これを使えば、以下のような繰り返しが可能です。

  1. qa マクロ記録開始
  2. dt( 動作1
  3. dib 動作2
  4. 3lD 動作3
  5. +q マクロ記録完了
  6. @a マクロを発動
  7. . 下に移動してから、上述のdt(から3lDまでを実行
  8. . 下に移動してから(略
  9. . 下に移動してからry
  10. 繰り返し

sample

Webページを非同期で表示するようにした

これは自作プラグインで、まだドキュメントの整備が終わっていない(する予定がない)のですが、せっかくなので紹介させてください。

これを以下のように設定すると

次のようにweblio辞書をVimのpopupで表示します。

sample

ドキュメントを追加して、あとは内部のバッファをいじれるようにすれば、もっと便利になると思いますが、使う人は僕以外いないし、いらんか。という。
だれかドキュメント書いて!

英和翻訳を非同期で表示するようにした

weblio辞書で和英ができるようになったので、あとは英和が必要です。

<leader>kで、選択した英文を翻訳してくれるようにしました。

sample

日本語関連の操作をしやすくした - vim-fmap

これはfキー及びFtTキーの4つへ、キーバインディングを提供してくれるプラグインです。

例えば以下を実行すると

nmap <leader>f <Plug>(fmap-forward-f)
FNoreMap p (  " 大文字括弧開き

<leader>fpbキーで、Vimデフォルトのf(を実行してくれます。

sample

僕はこれを以下のように設定して、IMEオンオフなしで日本語文字にジャンプできるようにしています!
これでnormal・visual・operatorへのいずれでも、ジャンプが可能になります :point_down:

let g:fmap_escape_keys = ['', '', '']

augroup vimrc
  autocmd VimEnter * FNoreMap / ・
  autocmd VimEnter * FNoreMap T ・
  autocmd VimEnter * FNoreMap tt …
  autocmd VimEnter * FNoreMap ''  
  autocmd VimEnter * FNoreMap p (
  autocmd VimEnter * FNoreMap k 「
  autocmd VimEnter * FNoreMap K 〈
  autocmd VimEnter * FNoreMap -k 『
augroup END

詳しくは :point_down:

括弧の操作を最強にした - vim-operator-surround

いわずと知れたプラグインですが、これも僕は日本語文字に活用しています。
(もちろん日本語文字以外にも。)

例えばカーソル下にwordという単語があれば、normalからのgajKキーでその周りに「」を追加することができ、つまりは「word」することができます。

これ :point_down: の執筆で大活躍でした。(宣伝)

gina.vimのコミット画面をcommittia.vimみたいにした

gina.vimは今季マジ推しのプラグインのうち、ひとつです。

そのまま使うでも便利なのですが、自前でキーマッピングを追加してみました。
見てみてください! :point_down:

sample

ちなみに、このキーマッピングの本家は :point_down:
(これを直接利用しようと考えたのですが、どうやらターミナルからgit-commitする用だったので、諦めました。もしVim上からもできるようだったら、すみません。)


以上です。
Happy Viming!

ZZ

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Fork(Gitクライアントツール)

概要

Gitクライアントツールとして、有名なツール SourceTree は利用する際にAtlassianのアカウント認証が必要。

Bitbucket を使うならいいが、今の業務では GitLab を使ってソース管理をしているため、
ツール使うためだけにアカウント作るのは面倒だった。

SourceTreeと似たようなことができるツールないかな(無料で)と探していた時にたどり着いたツールの紹介。

Fork

https://git-fork.com/

使える機能の説明などは上記のページに詳しく書かれています。
各ブランチごとのコミット履歴の確認やファイル差分の表示など、
自分がGitクライアントツールを使って確認したい内容は満たされていたので、使おうと思いました。

インストール方法

以下のリンク先からインストーラーをダウンロードできるので、実行してインストールするだけ。
Windows・Macともに対応しています。
 https://git-fork.com/

感想

使っていて不便に感じることがほとんどないため、かなり気に入っています。
SourceTreeを使おうと思ったけど、アカウント作るのが面倒と思ったときはぜひ使ってみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git パスワードを毎回聞かれる問題をHTTPSでも解決

GitHubにgit pushするときに毎回ユーザ名とパスワードが聞かれますね.

ググるとSSHを使うページが多いですが,GitHubの推奨はHTTPSです.
HTTPSでも聞かれなくする方法を紹介します.

結論

HTTPSでCloneしたリポジトリで,

git config credential.helper store

を実行して,ユーザ名,パスワードをキャッシュさせる.

これで,最初に一度ユーザ名,パスワードを入力すればそれ以降は聞かれなくなります.

ただ,これだと平文でパスワードが保存されるので,嫌な場合は後の項目を参照ください.

解説

基本的には,公式のページに全部書いてあります.

HTTPSのほうが「ファイアウォールやプロキシ下でも使いやすい」のもあって推奨していてます.
その下のTipsの欄に,「パスワードを覚えさせるにはcredential helperを使うといいよ」って書いてあります.

GitHubとしては,メモリにキャッシュとして記憶するオプション (git config credential.helper cache) を紹介しています.
デフォルトは15分でキャッシュが切れます.

git config credential.helper storeとすると,ファイル (~/.git-credentials) にhttps://myusername:mypassword@github.comのような形で,平文で保存されます.

平文テキストは怖いんだが...

GitHubの解説ページによると,Macではosxkeychain helper,Windowsではwincredが使えます.また,設定すればLinux (Ubuntu) ではgnome-keyringなどが使えます.

以下,MacとWindowsは動作未検証です.

Macの場合

(1) osxkeychain helperがインストールされているか確認

$ git credential-osxkeychain
> Usage: git credential-osxkeychain <get|store|erase>

↑インストールされていなければ,requesting installと言ってインストールのプロンプトが出ます.

(2) osxkeychain helperをGitで使うように設定

$ git config --global credential.helper osxkeychain

Windowsの場合

下記だけでwincredというhelperを使うように設定できます.

git config --global credential.helper wincred

Linuxの場合

このページ を参考に設定します.

(1) gnome-keyringのmakeに必要なライブラリを入れる.

sudo apt install libgnome-keyring-dev

(2) makeする

cd /usr/share/doc/git/contrib/credential/gnome-keyring
sudo make

(3) gitにcredential-helperを設定

git config --global credential.helper /usr/share/doc/git/contrib/credential/gnome-keyring/git-credential-gnome-keyring

まとめ

credential.helperを設定しておけば,快適にGitが使えますね.
(ただ,当然ですがcredentialの情報が変わったときに再設定が必要なのでご注意.)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git Hookにより自動でBlenderのレンダリング・FBXエクスポートを行う

はじめに

本記事は三重大学 計算研 Advent Calendar 2019 二日目です。

サークルでゲーム開発をする際に、Blenderで制作した3DモデルデータもGitでバージョン管理しました。
ゲーム開発でBlenderのファイルを使うためにはFBXにエクスポートしたものを使うほうが都合が良いです。

そこで今回Git Hookという機能を用いることで、Git Pushを実行した際に自動でサムネイル用画像レンダリングFBXエクスポートが行われるようにしました。

これにより、作業が自動化できただけでなく、FBXエクスポートの設定ミスが無くなるBlendファイルを編集した際のFBXファイルの更新忘れが無くなるというメリットもありました。

今回はGit Hookについての紹介と実際にBlenderにて自動エクスポートを行うための作業について紹介します。

Git Hookとは

Gitの標準の機能であり、特定のGitの作業を行った際にスクリプトを実行できるものです。

種類としては

  • クライアント
    • pre-commit : コミットメッセージ入力直前にスクリプト実行
    • prepare-commit-msg : コミットメッセージ入力用エディタ起動直前にスクリプト実行。デフォルトメッセージを編集したりできる
    • commit-msg : コミットメッセージ編集後にスクリプト実行
    • pre-push : Push実行直前にスクリプト実行 ← 今回はこれを用いる
    • pre-rebase : rebase実行直前にスクリプト実行。ゼロ以外を返せば処理を中断できる。

などがあります。

これらを使えば、

  • コミットする前に自動でテスト等を行ったり(pre-commit)
  • デフォルトのコミットメッセージを変更したり(prepare-commit-msg)
  • 入力されたコミットメッセージが規定にそっているかを調べたり(commit-msg)

が出来ます。

他にもサーバーサイドのもありますが、今回はクライアントサイドのpre-pushを用いて、Git Pushを行った際に自動でレンダリング、エクスポートを行えるようにします。

今回実現すること

developブランチにて、Blendファイルを配置しGit Pushすると自動で

  • 画像レンダリング
  • FBX生成
  • masterブランチに生成したFBXファイルを配置しコミット

が行われるようになります。

想定されるディレクトリ構成は以下のようなものです。

<Push前のDevelopブランチ>

├─Scripts : 自動レンダリング、FBXエクスポート用のスクリプトを置く。具体的な内容は後述する。
└─ProjectName
    │
    ├─blend : blendファイルを置くディレクトリ
    │  │ aaa.blend
    │  │ bbb.blend
    │  │ ccc.blend
    │
    └─Textures : テクスチャを置くディレクトリ

<Push後のDevelopブランチ>

├─Scripts
└─ProjectName
    │  aaa.fbx : [自動生成]blend/aaa.blendをFBXエクスポートしたもの
    │  bbb.fbx : [自動生成]blend/bbb.blendをFBXエクスポートしたもの
    │  ccc.fbx : [自動生成]blend/ccc.blendをFBXエクスポートしたもの
    │
    ├─blend 
    │  │ aaa.blend
    │  │ bbb.blend
    │  │ ccc.blend
    │
    ├─image : [自動生成]レンダリング画像が置かれるディレクトリ
    └─Textures : テクスチャを置くディレクトリ

<Push後のmasterブランチ>

└─ProjectName
    │  aaa.fbx 
    │  bbb.fbx 
    │  ccc.fbx 
    │
    └─Textures

developブランチにてBlendファイルとテクスチャファイルを配置し、Pushすると、
自動でレンダリング、FBX生成がされ、
FBXファイルとテクスチャファイルをmasterにCheckoutします。

開発環境

今回はWindows 10にて、

  • Blender 2.8
  • Git version 2.23.0.windows.1

で行いました。

作業手順

1. BlenderにPathを通す

まずは、Blender.exeにPathを通します。
環境変数のPathにBlenderのインストールディレクトリを追加します。
Blender公式サイトからインストーラーをダウンロードしてきてインストールした場合は、
"C:\Program Files\Blender Foundation\Blender"
がインストールディレクトリになると思います。

環境変数の編集方法は
https://qiita.com/sta/items/6d29da0dc7069ffaae60
が参考になると思います。

2. レンダリングを行うためのスクリプト

次に、レンダリングを行うためのスクリプトとして、Scripts/render.pyに以下の内容で保存します。

import bpy

bpy.context.scene.render.resolution_x = 1920
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.resolution_percentage = 25

path = bpy.context.blend_data.filepath.rstrip(bpy.path.basename(bpy.context.blend_data.filepath)) + "../image/" +  bpy.path.basename(bpy.context.blend_data.filepath).split(".")[0] +".png"
bpy.data.scenes["Scene"].render.filepath = path

bpy.ops.render.render( write_still=True )

これにより、blend/aaa.blendであれば、image/aaa.pngにレンダリング結果が保存されます。

今回はサムネイル画像用のレンダリングなので解像度を1920x1080の25%に指定しています。

3. FBXエクスポートを行うためのスクリプト

次に、FBXエクスポートを行うためのスクリプトとして、Scripts/ExportFBX.pyに以下の内容で保存します。

import bpy,sys

def fbx_export_geometry(arg_filepath='./export.fbx'):
  bpy.ops.export_scene.fbx(
    filepath=arg_filepath,
    object_types={'ARMATURE', 'MESH'},
    bake_anim=False,
  )
  # 出力対象の種別
  #  'EMPTY':エンプティ
  #  'CAMERA':カメラ
  #  'LAMP':ランプ
  #  'ARMATURE':アーマチュア
  #  'MESH':メッシュ
  #  'OTHER':その他
  return

# 関数の実行
path = bpy.context.blend_data.filepath.rstrip(bpy.path.basename(bpy.context.blend_data.filepath)) + "../" +  bpy.path.basename(bpy.context.blend_data.filepath).split(".")[0] +".fbx"
fbx_export_geometry(path)

これにより、blend/aaa.blendであれば、aaa.fbxにFBXエクスポートされます。

また、ここでカメラやランプを除いて、アーマチュアとメッシュのみをFBXエクスポートしています。

4. 2つのPythonスクリプトを呼び出すためのスクリプト

それでは、この2つのPythonスクリプトを呼び出すためのスクリプトを用意します。

Scripts/convert.shに以下の内容で保存します。

#!/bin/bash

log=$(pwd)/gitPush.sh.log

echo "[$(date)] start" >> $log

echo "[Messeage by convert.sh]cd git top level dir(" `git rev-parse --show-toplevel` ")"
cd  `git rev-parse --show-toplevel`

for raw in $(git log origin/develop..develop --stat | grep ".blend") ; do
    if [ ${raw##*.} = "blend" ]; then
        echo "[Messeage by convert.sh] blend file is ${raw}"
        echo "[Messeage by convert.sh] Start Render.py"
        blender --background ${raw} --python Scripts/Render.py
        echo "[Messeage by convert.sh] Start ExportFBX.py"
        blender --background ${raw} --python Scripts/ExportFBX.py
    fi  
done
echo '[Messeage by convert.sh] git commit -m "Auto Generate FBX/render image"'
git add *.fbx
git add *.png
git commit -am "Auto convert FBX and render image"

ログ用のechoの行が挟まっていますが、内容としては、

  1. Gitのトップレベルディレクトリに移動
  2. gitのlogから、変更が加わったblendファイルの名前を取得
  3. 変更が加わったblendファイルに対して、画像レンダリング(Render.py)、FBXエクスポート(ExportFBX.py)を実行する
  4. FBXファイルとレンダリングpng画像をgit addする
  5. git commitする

となっています。

Git Hook pre-pushの設定

最後に、これまで作成してきたスクリプトをGit Hook pre-pushにて実行されるようにします。

Gitリポジトリには.gitディレクトリが存在しますが、.git/hooks/に"pre-push"というファイル名でシェルスクリプトを保存します。
すると、Git Push実行直前にこのスクリプトが実行されるようになります。

直接ここにファイルを置いてもいいですが、.git/hooks/はGit監視下では無いので、シンボリックリンクを置いて作業しました。

ちなみに、WindowsのPowerShellでのシンボリックリンクの貼り方は、下のコマンドになります。

New-Item -Type SymbolicLink .git/hooks/pre-push -Value Scripts/hooks/pre-push

pre-pushファイルには以下の内容で保存します。

#!/bin/sh

remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000

while read local_ref local_sha remote_ref remote_sha
do
    if [[ "${remote_ref##refs/heads/}" = "develop" ]]; then
        `git rev-parse --show-toplevel`/Scripts/convert.sh
        git checkout master
        git checkout develop `git rev-parse --show-toplevel`'/ProjectName/*.fbx'
        git checkout develop `git rev-parse --show-toplevel`'/ProjectName/Textures/*'
        git commit -m "[Auto commit] Add FBX from develop"

        git checkout develop
        git push origin master
    fi
done

  1. 作業しているブランチがdevelopかを調べる
  2. <Gitのトップレベルディレクトリ>/Scripts/convert.sh を実行。(ここで自動レンダリング、FBXエクスポートを行う)
  3. テクスチャファイルと、自動生成したFBXファイルをMasterブランチにcheckout
  4. masterをgit commit
  5. masterをgit push
  6. といった内容です。

以上により、developブランチにBlendファイルとテクスチャをpushするだけで、自動で

  • レンダリング
  • FBXエクスポート
  • developブランチにレンダリング画像とFBXをcommit
  • masterブランチにFBXとテクスチャをCheckout
  • masterブランチのgit commit & push

が行われるようになります。

さいごに

今回、blendファイルが更新されたら自動でFBXも更新するシステムを作ろうとして、Git Hookを使ってみました。

最初はCI/CDが必要なのかな...と思ってGitHub Actionsを試していたのですが、Blenderでレンダリングを行う際にサーバーサイドにGPUが必要なので悩んでいたところ、サークルの先輩にGit Hookを紹介してもらいました。

結果としてやりたかったことが実現でき、さらにクライアント側で完結するコンパクトなシステムになったと思います。

また、Git Hookで呼び出すためにBlender Pythonスクリプトも初めて使ってみましたが、これによりレンダリング・FBXエクスポートの設定ミスが無くなり、特にFBXエクスポートで誤ってランプやカメラを含んでしまいUnityで読み込んだ際におかしくなる問題が無くなりました。

これまでは自動化のモチベーションはあまりなかったのですが、自動化によるメリットをいくつも得れた良い機会でした。

Git Hookには他にもいろいろな発火タイミングがあるので、便利に使っていきたいと思います。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git Hookをつかって、Pushしたら自動でBlenderのレンダリング、エクスポートを行う

はじめに

本記事は三重大学 計算研 Advent Calendar 2019 二日目です。

サークルでゲーム開発をする際に、Blenderで制作した3DモデルデータもGitでバージョン管理しました。
ゲーム開発でBlenderのファイルを使うためにはFBXにエクスポートしたものを使うほうが都合が良いです。

そこで今回、Git Hookという機能を用いることで、Git Pushを実行した際に自動でレンダリングFBXエクスポートが行われるようにしました。

これにより、作業が自動化できただけでなく、FBXエクスポートの設定ミスが無くなるBlendファイルを編集した際のFBXファイルの更新忘れが無くなるというメリットもありました。

今回はGit Hookについての紹介と実際にBlenderにて自動エクスポートを行うための作業について紹介します。

Git Hookとは

Gitの標準の機能であり、特定のGitの作業を行った際に、スクリプトを実行できるものです。

種類としては、

  • クライアント
    • pre-commit : コミットメッセージ入力直前にスクリプト実行
    • prepare-commit-msg : コミットメッセージ入力用エディタ起動直前にスクリプト実行。デフォルトメッセージを編集したりできる
    • commit-msg : コミットメッセージ編集後にスクリプト実行
    • pre-push : Push実行直前にスクリプト実行 ← 今回はこれを用いる
    • pre-rebase : rebase実行直前にスクリプト実行。ゼロ以外を返せば処理を中断できる。

といったものがあります。

これらを使えば、コミットする前に自動でテスト等を行ったり(pre-commit)、デフォルトのコミットメッセージを変更したり(prepare-commit-msg)、入力されたコミットメッセージが規定にそっているかを調べたり(commit-msg)といったことができるようになります。

他にもサーバーサイドのもの(pre-receive,update,post-receive)などがありますが、今回はクライアントサイドのpre-pushを用いて、Git Pushを行った際に自動でレンダリング、エクスポートを行えるようにします。

今回実現すること

developブランチにて、Blendファイルを配置しGit Pushすると、自動で

  • 画像レンダリング
  • FBX生成
  • masterブランチに生成したFBXファイルを配置しコミット

が行われるようになります。

想定されるディレクトリ構成は以下のようになります。

<Developブランチ - Push前>

├─Scripts : 自動レンダリング、FBXエクスポート用のスクリプトを置く。具体的な内容は後述する。
└─ProjectName
    │
    ├─blend : blendファイルを置くディレクトリ
    │  │ aaa.blend
    │  │ bbb.blend
    │  │ ccc.blend
    │
    └─Textures : テクスチャを置くディレクトリ

<developブランチ、Push後>

├─Scripts
└─ProjectName
    │  aaa.fbx : [自動生成]blend/aaa.blendをFBXエクスポートしたもの
    │  bbb.fbx : [自動生成]blend/bbb.blendをFBXエクスポートしたもの
    │  ccc.fbx : [自動生成]blend/ccc.blendをFBXエクスポートしたもの
    │
    ├─blend 
    │  │ aaa.blend
    │  │ bbb.blend
    │  │ ccc.blend
    │
    ├─image : [自動生成]レンダリング画像が置かれるディレクトリ
    └─Textures : テクスチャを置くディレクトリ

<Push後のmasterブランチ>

└─ProjectName
    │  aaa.fbx 
    │  bbb.fbx 
    │  ccc.fbx 
    │
    └─Textures

developブランチにてBlendファイルとテクスチャファイルを配置し、Pushすると、自動でレンダリング、FBX生成がされ、FBXファイルとテクスチャファイルのみmasterにCheckoutします。

開発環境

今回はWindows 10にて、

  • Blender 2.8
  • Git version 2.23.0.windows.1

で行いました。

Blender自動レンダリング、FBXエクスポート用スクリプト

BlenderにてレンダリングとFBXエクスポートをPythonスクリプトで行えるようにします。

1. BlenderにPathを通す

まずは、Blender.exeにPathを通します。
やり方はhttps://qiita.com/sta/items/6d29da0dc7069ffaae60
が参考になると思います。

2. レンダリングを行うためのスクリプト

次に、レンダリングを行うためのスクリプトとして、Scripts/render.pyに以下の内容で保存します。

import bpy

bpy.context.scene.render.resolution_x = 1920
bpy.context.scene.render.resolution_y = 1080
bpy.context.scene.render.resolution_percentage = 25

path = bpy.context.blend_data.filepath.rstrip(bpy.path.basename(bpy.context.blend_data.filepath)) + "../image/" +  bpy.path.basename(bpy.context.blend_data.filepath).split(".")[0] +".png"
bpy.data.scenes["Scene"].render.filepath = path

bpy.ops.render.render( write_still=True )

これにより、blend/aaa.blendであれば、image/aaa.pngという形式でレンダリングされます。

今回はゲームで使うモデルのサムネイル画像の生成のためのレンダリングなので解像度を1920x1080の25%に指定しています。

3. FBXエクスポートを行うためのスクリプト

次に、FBXエクスポートを行うためのスクリプトとして、Scripts/ExportFBX.pyに以下の内容で保存します。

import bpy,sys

def fbx_export_geometry(arg_filepath='./export.fbx'):
  bpy.ops.export_scene.fbx(
    filepath=arg_filepath,
    object_types={'ARMATURE', 'MESH'},
    bake_anim=False,
  )
  # 出力対象の種別
  #  'EMPTY':エンプティ
  #  'CAMERA':カメラ
  #  'LAMP':ランプ
  #  'ARMATURE':アーマチュア
  #  'MESH':メッシュ
  #  'OTHER':その他
  return

# 関数の実行
path = bpy.context.blend_data.filepath.rstrip(bpy.path.basename(bpy.context.blend_data.filepath)) + "../" +  bpy.path.basename(bpy.context.blend_data.filepath).split(".")[0] +".fbx"
fbx_export_geometry(path)

これにより、blend/aaa.blendであれば、aaa.fbxにFBXエクスポートされます。

また、ここでカメラやランプを除いて、アーマチュアとメッシュのみをFBXエクスポートしています。

4. 2つのPythonスクリプトを呼び出すためのスクリプト

それでは、この2つのPythonスクリプトを呼び出すためのスクリプトを用意します。

Scripts/convert.shに以下の内容で保存します。

#!/bin/bash

log=$(pwd)/gitPush.sh.log

echo "[$(date)] start" >> $log

echo "[Messeage by convert.sh]cd git top level dir(" `git rev-parse --show-toplevel` ")"
cd  `git rev-parse --show-toplevel`

for raw in $(git log origin/develop..develop --stat | grep ".blend") ; do
    if [ ${raw##*.} = "blend" ]; then
        echo "[Messeage by convert.sh] blend file is ${raw}"
        echo "[Messeage by convert.sh] Start Render.py"
        blender --background ${raw} --python Scripts/Render.py
        echo "[Messeage by convert.sh] Start ExportFBX.py"
        blender --background ${raw} --python Scripts/ExportFBX.py
    fi  
done
echo '[Messeage by convert.sh] git commit -m "Auto Generate FBX/render image"'
git add *.fbx
git add *.png
git commit -am "Auto convert FBX and render image"

ログ用のechoの行が挟まっていますが、内容としては、

  1. Gitのトップレベルディレクトリに移動
  2. gitのlogから、変更が加わったblendファイルの名前を取得
  3. 変更が加わったblendファイルに対して、画像レンダリング(Render.py)、FBXエクスポート(ExportFBX.py)を実行する
  4. FBXファイルとレンダリングpng画像をgit addする
  5. コミットする

となっています。

Git Hook pre-pushの設定

最後に、これまで作成してきたスクリプトをGit Hook pre-pushにて実行されるようにします。

Gitリポジトリには.gitディレクトリが存在しますが、.git/hooks/に"pre-push"というファイル名でシェルスクリプトを保存します。
すると、Git Push実行直前にこのスクリプトが実行されるようになります。

直接ここにファイルを置いてもいいですが、.git/hooks/はGit監視下では無いので、シンボリックリンクを置いて作業しました。

ちなみに、WindowsのPowerShellでのシンボリックリンクの貼り方は、下のコマンドになります。

New-Item -Type SymbolicLink .git/hooks/pre-push -Value Scripts/hooks/pre-push

pre-pushファイルには以下の内容で保存します。

#!/bin/sh

remote="$1"
url="$2"
z40=0000000000000000000000000000000000000000

while read local_ref local_sha remote_ref remote_sha
do
    if [[ "${remote_ref##refs/heads/}" = "develop" ]]; then
        `git rev-parse --show-toplevel`/Scripts/convert.sh
        git checkout master
        git checkout develop `git rev-parse --show-toplevel`'/ProjectName/*.fbx'
        git checkout develop `git rev-parse --show-toplevel`'/ProjectName/Textures/*'
        git commit -m "[Auto commit] Add FBX from develop"

        git checkout develop
        git push origin master
    fi
done

  1. 作業しているブランチがdevelopかを調べる
  2. <Gitのトップレベルディレクトリ>/Scripts/convert.sh を実行。(ここで自動レンダリング、FBXエクスポートを行う)
  3. テクスチャファイルと、自動生成したFBXファイルをMasterブランチにcheckout
  4. コミット
  5. masterをPush

これにより、Git Pushがされた際に自動で行われるようになります。

さいごに

今回、blendファイルが更新されたら自動でFBXも更新するシステムを作ろうとして、Git Hookを使ってみました。

最初はCI/CDが必要なのかな...と思ってGitHub Actionsを試していたのですが、Blenderでレンダリングを行う際にサーバーサイドにGPUが必要なので悩んでいたところ、サークルの先輩にGit Hookを紹介してもらいました。

結果としてやりたかったことが実現でき、さらにクライアント側で完結する無駄の少ないシステムになったと思います。

また、Git Hookで呼び出すためにBlender Pythonスクリプトも初めて使ってみましたが、これによりレンダリング・FBXエクスポートの設定ミスが無くなり、特にFBXエクスポートで誤ってランプやカメラを含んでしまいUnityで読み込んだ際におかしくなる問題が無くなりました。

これまでは自動化のモチベーションはあまりなかったのですが、今回のは自動化によるメリットをいくつも得れた良い機会でした。

Git Hookには他にもいろいろな発火タイミングがあるので、便利に使っていきたいと思います。

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

チーム内で不要とされたremote branchを消すコマンド

はじめに

gitを利用している場合
油断するとチリツモの如く溜まっていくremotebranch。

見通しが悪くなったりするので
PRが通ったタイミングで消すのがベストかもしれませんがうっかりなんてことありますよね:disappointed_relieved:

ちょうど試してみたのでその方法の共有になります。

コマンド

git branch -r --merged | egrep -v "\\*|release|master|develop|feature/xxx" | awk '{ print substr($0, 10)}' | xargs -I branch git push origin :branch && git fetch --prune

git branch -r --merged
merge済のbranchリストを取得

egrep -v "\\*|release|master|develop|feature/xxx"
merge済であっても消して欲しくないbranchを指定

消して欲しくないremotebranchについてはしっかりチームメンバーに聞きましょうね!
アクシデントの元になる恐れがあります:scream:

awk '{ print substr($0, 10)}'
egrepの出力結果ではorigin/が文字列に含まれており後に控えるremotebranchを消すコマンドで都合が悪いため文字をoridin/develop -> developとなるように整形

xargs -I branch git push origin :branch
整形された文字列を引数としてremotebranchを消す

git fetch --prune
remoteで削除されたbranchをlocalに反映

実行前にどのremotebranchが削除対象なのか確認

git branch -r --merged | egrep -v "\\*|release|master|develop|feature/xxx" | awk '{ print substr($0, 10)}' | xargs -I branch echo branch

最後に

remotebranchを消す方法については何個もやり方はあると思いますが、
一例としてみてもらえると幸いです:relaxed:

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitを触ってみたらやることが多すぎた

未来電子テクノロジーでインターンをしているtokky08です。
Git/GitHubについて勉強したのでアウトプットとして書いていきます。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

Gitって何をするの?

ファイルのバージョンを管理するためにある!

・最新のファイルがどれか分からなくなったり。
・気づかずに上書きしてしまったりする。

こういうことを防止するためにgitがある!

GitHubってGitと何が違うの?

GitHubとは、gitリポジトリのホスティングサービス。
gitでのファイルの変更・変更履歴をオンライン上で扱ってくれるサービス!

ローカルで大事な3要素!

ワークツリー
手元でファイルを変更する作業場

ステージ
コミットする変更を準備する場
= 記録したい変更だけステージに追加してコミットしていく。一部の変更だけ記録したいときのためにステージが存在している。

リポジトリ
スナップショットを記録する場

作業の流れ

ローカルでスナップショットを記録 → GitHub(リモートリポジトリ)へアップ

コマンド集

コマンド 意味
git init .gitディレクトリが作成されリポジトリが生成される。このディレクトリの中にgitで必要なほとんどのファイルが含まれる
git clone リポジトリ名 GitHubから.gitディレクトリとファイルをローカルにコピーする。githubにアクセスしてURLをコピペ。
git status ワークツリーとステージの間で変更されたファイルとリポジトリとステージの間で変更されたファイルを表示する
git diff ワークツリーとステージの間で変更されたファイルの変更差分を表示する
git diff --staged リポジトリとステージの間で変更されたファイルの変更差分を表示する
git log 変更履歴を確認する
git rm ファイル名 ファイルの削除を記録する。ワークツリーとリポジトリどちらのファイルも削除する
git rm -r ディレクトリ名 ディレクトリの削除を記録する。ワークツリーとリポジトリどちらのディレクトリも削除する
git rm --cached ファイル名 ワークツリーのファイルは残して、リポジトリにあるファイルだけを削除する
git mv 旧ファイル 新ファイル ファイルの移動を記録する。ファイル名の変更。ワークツリーとステージにあるファイル名をまとめて変更
git remote add origin URL(リモートリポジトリ) リモートリポジトリ(GitHub)を新規追加する。originは任意の名前でOK。
git push origin master リモートリポジトリへ送信する
git checkout -- ファイル名 ファイルの変更を取り消す
git checkout -- ディレクトリ名 ディレクトリの変更を取り消す
git checkout -- . 現在いるディレクトリ以下の変更を全て取り消す
git reset HEAD ファイル名 ステージしたファイルの変更を取り消す。ステージをなかったことにする。
git reset HEAD ディレクトリ名 ステージしたディレクトリの変更を取り消す。ステージをなかったことにする。
git reset HEAD . 先ほどステージしたもの全部をステージしなかったことにする 。
git commit --amend さっきやったコミットをやり直します。ただし、pushしたコミットはやり直したらだめ!
git remote -v 登録しているリモートリポジトリ名とURLを表示する
git fetch リモート名 リモートリポジトリの内容をローカルリポジトリに落とす
git merge リモート名/ブランチ名 ローカルリポジトリの内容をブランチのワークツリーに統合する
git pull リモート名 ブランチ名 リモートリポジトリの内容をローカルリポジトリに落として、ローカルリポジトリの内容をワークツリーに統合する。* 現在いるブランチに統合されるので気を付ける!
git remote show リモート名 リモートの詳細情報を表示する
git remote rename 旧リモート名 新リモート名 リモート名の変更
git remote rm リモート名 リモートを削除する
git branch ブランチ名 ブランチを作成する。ブランチの切り替えまでは行わない。
git branch ブランチの一覧表示
git branch -a リモートリポジトリも表示
git checkout 既存ブランチ名 ブランチを切り替える
git checkout -b 新ブランチ名 ブランチの作成と切り替えを一度にしてくれる
git merge リモート名/ブランチ名 他の人の変更内容を取り込む
git branch -m 新ブランチ名 現在いるブランチの名前を変更する
git branch -d ブランチ名 ブランチを削除する。masterにmergeされていない変更が残っているブランチは削除しない。
git branch -D ブランチ名 ブランチを強制削除する
git tag tagの一覧を表示する
git tag -a タグ名 -m “メッセージ” 注釈付きタグをつける。リリース時につける
git tag -a タグ名 コミット名 -m “メッセージ” 後からタグをつける
git show タグ名 タグの詳細を表示する
git push リモート名 タグ名 タグをリモートリポジトリに送信する
git push origin --tags ローカルにあってリモートリポジトリに存在しないタグを一斉に送信する
git stash 作業を一次避難する。stashに避難させることで、ワークツリーとステージの変更をなかったことにする。
git stash list 避難した作業の一覧を表示する
git stash apply 最新の作業を復元する
git stash apply --index ステージの状況も復元する
git stash apply スタッシュ名 特定の作業を復元する
git stash drop 最新の作業を削除する
git stash drop スタッシュ名 特定の作業を削除する
git stash clear 全作業を削除する

3種類のマージ

・Fast Foward:ブランチが枝分かれしてなかったときはブランチのポインタを前に進めるだけ
・Auto Merge:枝分かれして開発していた場合、マージコミットという新しいコミットを作る
・コンフリクト:同じファイルの同じ行に対して複数人が異なる編集を行ったときに生じる

コンフリクト防ぐには

・複数人で同じファイルを変更しない
・pullやmergeする前に変更中の状態を無くしておく(commitやstashをしておく)
・pullするときは、pullするブランチに移動してからpullする
・コンフリクトしても慌てない

マージかリベースどっちを使うべきか?

作業の履歴を残したいならマージ
履歴をきれいにしたいならリベース

プッシュしていないローカルの変更にはリベースを使い、プッシュした後はマージを使う。コンフリクトしそうならマージを使う。

複数のコミットをやり直す

rebase -i コマンドの一連の流れ
git rebase -i HEAD~数字 コマンドで対話的リベースモードに入る
・修正したいコミットをeditにしてコミットエディタを終了する
editのコミットのところでコミットの適用が止まる
git commit --amendコマンドで修正
git rebase --continueで次のコミットへ行く
pickだとそのままのコミット内容を適用して次へ行く

まとめ

Git/Githubを勉強するにあたって色々覚えることが多いなという印象です。実際に使っていくことで覚えていきたいですね。特に、プルリクエストなどは共同開発しなければ使わないと思うのでいざ使う時が訪れても慌てずに対処できるように流れを確認しておくべきだなと思いました。定期的に復習しようと思います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Git Study

ローカルでは細かくPushしてPRはまとめる

Pull Requestまでの流れ

ローカルの作業ブランチには自由にコミットする
作業ブランチのコミットを最後にキレイにする(まとめる)
Pull Requestを送る

git merge –squash

git rebase -iは作業ブランチのコミットを直接編集できて分かりやすいですが、コミットが多いほどまとめる作業が面倒なので、最終1つのコミットでいい場合は不向き
→git merge –squashを使う

# 作業ブランチをチェックアウト
$ git fetch
$ git checkout -b work/xxx-867 origin/develop 

# git add や commit などして作業完了

# Pull Request用ブランチをチェックアウト
$ git fetch
$ git checkout -b work/xxx origin/develop

# 作業ブランチをマージ
$ git merge --squash work/xxx-867

# Pull Requestに出すコミットを作成
$ git commit

最後にgit commitでPRに出すメッセージをedit

慣れてきたらコミットをまとめてPull Requestしよう(git merge --squash)

Close PR

プルリクエストをクローズする

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[GithubActions]プライベートリポジトリにあるアクションを他のリポジトリで使う

この記事はチームラボエンジニアリングアドベントカレンダー17日目の記事です。

はじめに

組織内でGithubActionsを使いまわしたいけど、外部に公開したくない!と言う要件は結構あるかと思います。
現在、残念ながらGitHubActionsではプライベートリポジトリに作成したアクションは他のリポジトリから参照できません。
https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/configuring-a-workflow

プライベートリポジトリで定義されているアクションを使用するには、ワークフローファイルとそのアクションが同じリポジトリになければなりません。 同じOrganizationにある場合でも、他のリポジトリで定義されているアクションは、ワークフローで使用できません。

なんとかしてプライベートのリポジトリにあるアクションを使いまわしたい。。。

サブモジュールとしてアクションを取り込む

なんとかならないものかと頭を捻らせていると、同じリポジトリ内にあれば使えると言うことを思い出しました。

プライベートリポジトリで定義されているアクションを使用するには、ワークフローファイルとそのアクションが同じリポジトリになければなりません。

ならば、アクションが入ってるリポジトリをサブモジュールとして取り込めば、ワークフローファイルと同じリポジトリにアクションファイルが置けますね!

GithubActions.png

早速やってみます。。。
あ、アクションの入っているリポジトリと、そのアクションを使いたいプロジェクトを作成したリポジトリはすでに作成してあることを前提に説明させていただきます。
今回の説明ではそれらのリポジトリを以下のように呼ばせてもらいます。

  • プロジェクトリポジトリ -> アクションを使用するリポジトリ
  • アクションリポジトリ -> アクションが登録してあるリポジトリ

ちなみにサンプルコードというほどでもないですが、GitHubにサンプルで作ったプルリクエストがあります。

パーソナルアクセストークンの取得

GitHub Actionsでプライベートのリポジトリの情報を取得するには、そのリポジトリのアクセス権限を持ったアクセストークンが必要です。以下の資料を参考にしてトークンを取得します。

(この記事ではPERSONAL_ACCESSTOKENと言う名前でトークンを設定したことを前提に説明していきます。)

コマンドライン用の個人アクセストークンを作成する

次のサブモジュール設定でアクセストークンの文字列を使用しますので、コピーをとっておきましょう。

アクションを使いたいプロジェクトにサブモジュールの設定

それではプロジェクトリポジトリにサブモジュールとしてアクションリポジトリを設定していきます。
GitHub Actionsでサブモジュールの取得にパーソナルアクセストークンを使用するために、以下のような手順が必要となります。
また、パーソナルアクセストークンはsshではなく、httpsでしか使用できないので注意が必要です。

  • 取得したパーソナルアクセストークンを~/.netrcに設定してhttpsでローカルからアクションリポジトリにアクセスできるようにする 参考: GitHubでユーザ名・パスワード省略(push, pull)

    ~/.netrcに以下を追記

    ~/.netrc
    machine github.com
    login [{GitHubのユーザ名}]
    password [{所得したパーソナルアクセストークンの文字列}]
    
  • プロジェクトリポジトリにサブモジュールとしてアクションリポジトリを追加 参考: Git submodule の基礎

    プロジェクトリポジトリに移動して下記のコマンドでサブモジュールを追加(アクションリポジトリのURLは必ず https で!)

    git submodule add https://{アクションリポジトリのURL} .github/actions
    

    上記のコマンドでは、.githubディレクトリ内のactionsディレクトリにサブモジュールを設定していますが、他の場所でも大丈夫です。

  • 変更をコミット

これでアクションをサブモジュールとして追加できました!
が、GitHub Actionsでサブモジュールを使うにはもう少し設定が必要です。

プロジェクトリポジトリからアクションリポジトリのアクションを使ってみる

GitHub Actionsでサブモジュールを取得するために、パーソナルアクセストークンを使用します。
ワークフローにパーソナルアクセストークンを直書きしてもサブモジュールを取得できますが、セキュリティの観点から、プロジェクトリポジトリのsecretsに登録する方法を説明します。

パーソナルアクセストークンをプロジェクトリポジトリのsecretsに登録

プロジェクトリポジトリのsecrets情報としてパーソナルアクセストークンを以下の手順で登録していきます。

  1. タブでSettingsを選択
  2. メニューバーでSecretsを選択
  3. Add a new secretを選択
  4. NameにPERSONAL_ACCESSTOKENを、Valueに先ほど取得したパーソナルアクセストークンの文字列を入力
  5. Add secret スクリーンショット 2019-11-29 11.44.12.png

これでやっとプロジェクトリポジトリでアクションを追加する準備が全て完了しました!

workflowの作成

ワークフローファイルでのサブモジュールにしたアクションの使い方は、同じリポジトリ内にアクションがある時と同様にプロジェクトのルートからのパスを指定してあげます。また、サブモジュールをチェックアウトする記述も必要です。

/.gihub/workflow/pull_request.yml
name: Using Private Repositroy Sample

on:
  pull_request:
    branches:
    - master
jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: checkout with submodule
      uses: actions/checkout@v1
      with:
        submodules: true
        token: ${{ secrets.PERSONAL_ACCESSTOKEN }}

    - name: hoge
      uses: ./.github/actions/hoge

    - name: huga
      uses: ./.github/actions/huga

サブモジュールをチェックアウトする記述は以下の部分ですね。サブモジュールを取得するにはcheckoutのアクションを使用してwithの所にtokenを渡す必要があります。

tokenには先ほどsecretsに登録したパーソナルアクセストークンを指定してあげます。

- name: checkout with submodule
  uses: actions/checkout@v1
  with:
    submodules: true
    token: ${{ secrets.PERSONAL_TOKEN }}

実行結果

上記の例ではプルリクエストを作成時にアクションを実行してくれます。
実際にプルリクエストを作ってみると・・・!できました!!!
スクリーンショット 2019-11-29 12.10.31.png

まとめ

いかがでしたでしょうか。トークンの扱いが少し面倒ですが、アクションのコードが一元管理できるのは結構いいのかなと個人的には思います。

まぁ、GitHubがプライベートリポジトリに作成したアクションを使用できるようにしてくれれば、最高なんですけどね

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[GihubActions]プライベートリポジトリにあるアクションを他のリポジトリで使う

この記事はチームラボエンジニアリングアドベントカレンダー17日目の記事です。

はじめに

組織内でGithubActionsを使いまわしたいけど、外部に公開したくない!と言う要件は結構あるかと思います。
現在、残念ながらGitHubActionsではプライベートリポジトリに作成したアクションは他のリポジトリから参照できません。
https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/configuring-a-workflow

プライベートリポジトリで定義されているアクションを使用するには、ワークフローファイルとそのアクションが同じリポジトリになければなりません。 同じOrganizationにある場合でも、他のリポジトリで定義されているアクションは、ワークフローで使用できません。

なんとかしてプライベートのリポジトリにあるアクションを使いまわしたい。。。

サブモジュールとしてアクションを取り込む

なんとかならないものかと頭を捻らせていると、同じリポジトリ内にあれば使えると言うことを思い出しました。

プライベートリポジトリで定義されているアクションを使用するには、ワークフローファイルとそのアクションが同じリポジトリになければなりません。

ならば、アクションが入ってるリポジトリをサブモジュールとして取り込めば、ワークフローファイルと同じリポジトリにアクションファイルが置けますね!

GithubActions.png

早速やってみます。。。
あ、アクションの入っているリポジトリと、そのアクションを使いたいプロジェクトを作成したリポジトリはすでに作成してあることを前提に説明させていただきます。
今回の説明ではそれらのリポジトリを以下のように呼ばせてもらいます。

  • プロジェクトリポジトリ -> アクションを使用するリポジトリ
  • アクションリポジトリ -> アクションが登録してあるリポジトリ

ちなみにサンプルコードというほどでもないですが、GitHubにサンプルで作ったプルリクエストがあります。

パーソナルアクセストークンの取得

GitHub Actionsでプライベートのリポジトリの情報を取得するには、そのリポジトリのアクセス権限を持ったアクセストークンが必要です。以下の資料を参考にしてトークンを取得します。

(この記事ではPERSONAL_ACCESSTOKENと言う名前でトークンを設定したことを前提に説明していきます。)

コマンドライン用の個人アクセストークンを作成する

次のサブモジュール設定でアクセストークンの文字列を使用しますので、コピーをとっておきましょう。

アクションを使いたいプロジェクトにサブモジュールの設定

それではプロジェクトリポジトリにサブモジュールとしてアクションリポジトリを設定していきます。
GitHub Actionsでサブモジュールの取得にパーソナルアクセストークンを使用するために、以下のような手順が必要となります。
また、パーソナルアクセストークンはsshではなく、httpsでしか使用できないので注意が必要です。

  • 取得したパーソナルアクセストークンを~/.netrcに設定してhttpsでローカルからアクションリポジトリにアクセスできるようにする 参考: GitHubでユーザ名・パスワード省略(push, pull)

    ~/.netrcに以下を追記

    ~/.netrc
    machine github.com
    login [{GitHubのユーザ名}]
    password [{所得したパーソナルアクセストークンの文字列}]
    
  • プロジェクトリポジトリにサブモジュールとしてアクションリポジトリを追加 参考: Git submodule の基礎

    プロジェクトリポジトリに移動して下記のコマンドでサブモジュールを追加(アクションリポジトリのURLは必ず https で!)

    git submodule add https://{アクションリポジトリのURL} .github/actions
    

    上記のコマンドでは、.githubディレクトリ内のactionsディレクトリにサブモジュールを設定していますが、他の場所でも大丈夫です。

  • 変更をコミット

これでアクションをサブモジュールとして追加できました!
が、GitHub Actionsでサブモジュールを使うにはもう少し設定が必要です。

プロジェクトリポジトリからアクションリポジトリのアクションを使ってみる

GitHub Actionsでサブモジュールを取得するために、パーソナルアクセストークンを使用します。
ワークフローにパーソナルアクセストークンを直書きしてもサブモジュールを取得できますが、セキュリティの観点から、プロジェクトリポジトリのsecretsに登録する方法を説明します。

パーソナルアクセストークンをプロジェクトリポジトリのsecretsに登録

プロジェクトリポジトリのsecrets情報としてパーソナルアクセストークンを以下の手順で登録していきます。

  1. タブでSettingsを選択
  2. メニューバーでSecretsを選択
  3. Add a new secretを選択
  4. NameにPERSONAL_ACCESSTOKENを、Valueに先ほど取得したパーソナルアクセストークンの文字列を入力
  5. Add secret スクリーンショット 2019-11-29 11.44.12.png

これでやっとプロジェクトリポジトリでアクションを追加する準備が全て完了しました!

workflowの作成

ワークフローファイルでのサブモジュールにしたアクションの使い方は、同じリポジトリ内にアクションがある時と同様にプロジェクトのルートからのパスを指定してあげます。また、サブモジュールをチェックアウトする記述も必要です。

/.gihub/workflow/pull_request.yml
name: Using Private Repositroy Sample

on:
  pull_request:
    branches:
    - master
jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: checkout with submodule
      uses: actions/checkout@v1
      with:
        submodules: true
        token: ${{ secrets.PERSONAL_ACCESSTOKEN }}

    - name: hoge
      uses: ./.github/actions/hoge

    - name: huga
      uses: ./.github/actions/huga

サブモジュールをチェックアウトする記述は以下の部分ですね。サブモジュールを取得するにはcheckoutのアクションを使用してwithの所にtokenを渡す必要があります。

tokenには先ほどsecretsに登録したパーソナルアクセストークンを指定してあげます。

- name: checkout with submodule
  uses: actions/checkout@v1
  with:
    submodules: true
    token: ${{ secrets.PERSONAL_TOKEN }}

実行結果

上記の例ではプルリクエストを作成時にアクションを実行してくれます。
実際にプルリクエストを作ってみると・・・!できました!!!
スクリーンショット 2019-11-29 12.10.31.png

まとめ

いかがでしたでしょうか。トークンの扱いが少し面倒ですが、アクションのコードが一元管理できるのは結構いいのかなと個人的には思います。

まぁ、GitHubがプライベートリポジトリに作成したアクションを使用できるようにしてくれれば、最高なんですけどね

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitでローカルに残った不要なディレクトリを削除

Gitでリソースを管理している際に、リモートでは消えているはずのディレクトリが、ローカルでは残ったままになっていることがあったので、解決策のメモ。

git clone

ローカルのリポジトリを削除して、リモートからクローンし直す。これが1番手っ取り早いし、確実にリモートとローカルが一致する。ただ、如何せん脳筋っぽいし、どうせならスタイリッシュにやりたい。

git clean

追跡していないファイルを作業ディレクトリから削除するコマンド。

  • git clean -n 追跡していないファイルを確認
  • git clean -f 追跡していないファイルを削除
  • git clean -f PATH パスを指定して追跡していないファイルを削除
  • git clean -df 追跡していないディレクトリも含めて削除

今回のケースだとgit clean -dnで削除されるディレクトリを確認、問題なければgit clean -dfで削除といった流れ。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

git で checkout せずに他のブランチのファイルを見たい

git で、あるブランチ x で作業しているときに、他のブランチ y で追加されたファイル hoge.rb の内容を知りたくなった。そういうときにどうするか。
git show にブランチ名を与えると見ることができるらしい。リダイレクトすれば取り出す事もできる。

git show y:hoge.rb 
git show y:hoge.rb > file 

https://stackoverflow.com/questions/7856416/view-a-file-in-a-different-git-branch-without-changing-branches

Emacs では M-x magit-find-file の後にブランチ名、そしてパス付きのファイル名を与えれば同じことができる。
Refs モードなら、カーソルがあたっているところがデフォルトのブランチ名になる。

https://emacs.stackexchange.com/questions/7655/how-can-i-open-a-specific-revision-of-a-file-with-magit

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

reference brokenでgit pullできなくなったときの対策

環境

この記事では、vagrant上のCentOS 7 、git 2.12.0 を使用している。

$ cat /etc/redhat-release 
CentOS Linux release 7.3.1611 (Core) 
$ git --version
git version 2.12.0

症状と原因

git pull で最新のコミットを取ってこようとすると、以下のエラーが出て失敗。
GITの参照が壊れているから、参照先が解決できないので、ローカルの参照は更新できませんよ~、と。

$ git pull
error: cannot lock ref 'refs/tags/v1.3.38': unable to resolve reference 'refs/tags/v1.3.38': reference broken
From github.com:netsea/shopping-site
 ! [new tag]           v1.3.38    -> v1.3.38  (unable to update local ref)

その壊れているファイルはどうなっているかと言うと、

$ cat .git/refs/tags/v1.3.38 
$ 

空のファイルとなっていた。
このディレクトリにはバージョンのハッシュが記載されたファイルが配置されている。
だが v1.3.38 に関しては空なので参照することができないとのことだ。
ブルースクリーンでPCが落ちてからこの症状が続いているので、書き換え中か何かに落ちたか、ディスクが壊れたのかと思われる。

対策

以下のgit gcコマンドを実行すると、余計なファイルが削除されて最適化されて直る場合があるそうだ。

だが、今回のケースでは直らなかった。

$ git gc --prune=now
$ git remote prune origin

なので、手動で壊れたファイルを削除する。

$ rm .git/refs/tags/v1.3.38
$ git pull
From github.com:netsea/shopping-site
 * [new tag]           v1.3.38    -> v1.3.38
Updating 3b1491d2..0ffa0fcb
Fast-forward
...
...
$ cat .git/refs/tags/v1.3.38
7e5aaf5ac820aaafa75329def011e3111a9c3f87

削除したタグのファイルが復活して、マージされた。
これで解決😉

参考にした文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

肥大化した.git ファイルのtmpファイルを探して削除

なにがしたい

200GくらいあるでかいGitリポジトリを使用していた.
気がつけば100Gくらい容量が膨れ上がった.
調べてみると.git以下のファイルが肥大化していた.

対処

git gcで失敗した際のtempファイルが悪さをしていたみたい.
以下コマンドで思いファイルを探す.

find . -iname "*temp*" -o -iname "*tmp*" -print0| xargs -0 du -sh

このファイル一覧の中に
tmp_pack_AbCdEfg
のようなものがいれば消しても良いはず. git gc時に中断してしまった際のtmpファイルのようだ.

自分の場合はlfs管理しているところで80Gほどのtmpファイルが作成されていた.

参考

https://www.reddit.com/r/git/comments/324ejz/can_i_safely_delete_tmp_pack_files_in/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【初心者】【バージョン管理】中央集中型システムと分散型システムについて

はじめに

ここでは,2つのバージョン管理システム,中央集中型システムと分散型システムについて基本的なことを記述しました.

バージョン管理とは何なのか?SVNとGitの違いは何か?
中央集中型バージョン管理とは?,分散型バージョン管理とは?等のバージョン管理システムについて,基本的なことを知りたい方向けに書いたものになります.
私自身習いたての身であり,まだまだ不十分な点があると思いますが,ご容赦ください.

バージョン管理とは

バージョン管理とは,一言でいうと成果物の変更を管理することです.
成果物,ドキュメント類の変更を管理することは,複数人で作業を進める上で全体の作業効率を向上することに起因します.
複数の作業者がある1つのエクセルファイルを同時に編集して競合コピーが発生してしまった,など複数の作業者内でのドキュメントの変更・編集による障害を防止するのもバージョン管理システムの役割の1つになります.

成果物(ソースコードやドキュメント類等)は時間が経つにつれて変化あるいは進化していくもので,変化の過程に追従していくことは重要になってきます.なぜなら,どこに誰がいつどんな変更をしたかを知ることは素直に便利であることが多いというのは想像できると思います.

バージョン管理システムが主に3つの機能を提供します.以下の3つ機能は,複数の作業者が同一のファイルを取り扱う上で必要な機能であると考えます.

  • ファイルの共有
  • ファイルの同期
  • ファイルのバックアップ

バージョン管理システムには2つの種類があります.

  • 中央集中型システム ⇒ Subversion(SVN),Concurrent Version System(CVS)
  • 分散型システム ⇒ Git, Mercurial, Bazaar, Fossil

中央集中型バージョン管理システムについて

中央集中型バージョン管理システムの原理について説明します.

複数の作業者が同じファイル群を扱うものとします.
ある1つのサーバで中央集中型システムは稼働し,だれでもそのサーバからファイルのコピーを取得して作業ができます.
変更した内容はサーバにある内容に反映(コミット)できます.
また,他の利用者が更新操作を行ったことにより,サーバ内のファイルが変更されると,その内容も自分の環境に同期できます.ここで,サーバ内にあるファイル群のことをリポジトリと呼びます.
中央集中型VCS.png

サーバ側では全ての変更過程を記録しているので,この記録をもとにどんな変更でも前の状態に戻したり,変更した時に何が行われたかをわかることができます.

変更をサーバに保存するとリビジョン番号というものが生成・増加されます.リビジョン番号は,書籍で例えると,改訂版の番号(第1版,第2.3版等)にあたるようなもので,変更を識別する一意のシンボルになります.

中央集中型のデメリットとして,オフラインの状態では最新のファイルをリポジトリに取得・反映することができません.

分散型バージョン管理システム

分散型システムは中央集中型と違って,主となるサーバは持っていません.その代わりに,だれもが独立したリポジトリを用意して,他のリポジトリと同期することができます.中央集中型ではリポジトリを用意できるのは1つのサーバだけでした.それに対し,分散型は複数のリポジトリを持つことができます.
なので,中央集中型ができないことを分散型では可能になります.リポジトリを複数存在することから「分散型」と呼ばれます.

分散の戦略

中央集中型のように,ある1つのサーバ(「中央サーバ」と便宜上呼称)にリポジトリを置き,中央サーバから複数の作業者がリポジトリを①ローカルにコピー(「pull」と呼ぶ)→②変更→③中央サーバに反映(「push」と呼ぶ)という流れは分散型でもあります.

ただし,この分散型における中央サーバの目的は中央集中型とは異なります.また,上記の流れは中央集中型と同じ使い方であり,分散型の優位性を活かせていません.

分散型における中央サーバの目的は全ての作業者,開発者が個々の変更を単一の場所で共有・集約する場所となり,開発者のリポジトリ間でpullやpushをする代わりに使われます.
このような単一の中央サーバにあるリポジトリ(中央リポジトリ)は,全ての作業者それぞれのリポジトリにおけるすべての変更を追う為のバックアップにつながります.

分散型バージョン管理システムでは,中央リポジトリでファイルを共有するために中央集中型とは異なるアプローチが可能です.
複数のリポジトリを1つのサーバに用意して,それぞれ異なるレベルでアクセスする方法です.(ここ図がほしいかも)
複数のリポジトリには,開発版リポジトリ,安定板リポジトリ,リリースリポジトリ(リリースごとに用意),などがあります.

  • 開発版リポジトリ:だれもが変更をpushできます.
  • 安定板リポジトリ:管理者以外の全員が読み取りのみ可能で,管理者は開発版リポジトリの変更を吟味して,どれを安定版に 取り込むか判断します.
  • リリースリポジトリ:リリースごとにリポジトリを用意し,読み取り専用とします.

これにより,メンバーは作業に集中し,マネージャーはその内容を安定版リポジトリに反映する前にレビューを行えます.

運用面における中央集中型と分散型のそれぞれの特徴

中央集中型では
全てのユーザはサーバから自分のPCにコピーを,常に中央にあるリポジトリと同期する責任があります.これにより,自分の変更を他のユーザが取得できるようにしておく必要があります.
ローカル(自分のPC)で変更したものと同じファイルをだれかが同時に編集した場合に,中央サーバにチェックイン(変更分を反映)する時点で変更が競合してしまう可能性があります,
また,中央サーバに接続できない環境の場合(例えばネットがつながらない環境),最新のファイルを取得・反映ができません.

分散型集中型では
ローカルのリポジトリにはそれぞれにリビジョン番号がありますが,全てのリポジトリで一貫した共通のリビジョン番号というものは存在しません.これに対する方法として,タグというもの使って,バージョンの識別をわかりやすくします.タグはいわば,ラベルのようなもので,特定の変更記録にラベルをつけます.
バックアップについて,作業者それぞれが彼らのリポジトリをバックアップする責任が伴います.

中央集中型システムの欠点を補うための手法 ~ブランチとマージについて~

ブランチとマージがなぜ必要なのか?どういう経緯で生まれた思想なのか,少し知りたくなったので,ちょっと調べてみた結果を記述します.

中央集中型では,時間がかかる複雑な変更を多くのがファイルに行っている場合,全体の作業が完了するまで全ての作業者のPC内のファイル(ローカルファイル)を更新せずに維持しなければなりません。つまり,全体の作業あるいは編集している作業者が完了しないと,自分の作業ができない状態に陥ります.
これにより,以下の問題が浮上します.

  • すべての変更は作業者のコンピュータ上で行われ,バックアップができません.
  • 全体の作業が完了して中央サーバに反映するまで,他の作業者と変更内容を共有するのが難しくなります.もし全体の作業が全て完了せずに中央サーバに反映してしまうと,リポジトリ内のファイルが不安定な状態になりかねません.これは他の作業者の迷惑になります.

これを解決する手段として,ブランチとマージという手法があります.
これはメインの作業ラインから分岐させて,作業専用のラインを作成し,作業用のラインで作業が完成次第,変更分をまた元のメインのラインに戻す手法です.分岐するラインをブランチにあたり,ブランチからメインのラインに変更を反映することをマージにあたる.
これより,作業者自身の作業専用ラインの変更履歴をたどることでバックアップが容易になると.中央集中型バージョン管理について,このようにコンテキストをたどると少しだけなるほどねーとなりました.

ただし,中央集中型バージョン管理システムには,ブランチとマージを適用できますが,極めて難しい作業であるようです.(引用:エキスパートPythonプログラミング第二版)

まとめ

  • バージョン管理システムは複数の作業者が特定のファイル群を扱い,それらの変更履歴を管理したい場合に使用される,
  • バージョン管理管理システムには中央集中型と分散型が存在する.
  • 中央集中型ではリポジトリが1つであるのに対し,分散型ではリポジトリが複数存在する.
  • 作業効率化,バックアップの効率化を図るためにバージョン管理システムではブランチとマージの手法を適用する.

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

dockerコンテナ内で最新のgitをソースコードからインストールする

はじめに

本記事では、dockerコンテナ内でgitの最新版をソースコードからインストールする方法について説明します。

全体の流れ

以下の7ステップで、gitの最新版をソースコードからインストールします。
以下は作業は全てrootユーザで実施しています。

  1. apt-getをupdateとupgradeする
  2. コンテナに最初から入っているgitをアンインストールする
  3. ビルドに必要なパッケージをインストールする
  4. gitのソースコードを公式リポジトリからダウンロードする
  5. ビルドする
  6. gitのパスを通す
  7. 動作確認

apt-getをupdateとupgradeする

既に実施していれば以下は不要です。

# apt-get update
# apt-get upgrade

コンテナに最初から入っているgitをアンインストールする

# apt-get remove git

ビルドに必要なパッケージをインストールする

# apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev unzip

gitのソースコードを公式リポジトリからダウンロードする

任意の作業ディレクトリにgitの公式リポジトリから最新のソースコードをダウンロードします。
ダウンロードにはwgetコマンドを使います。
本記事では、 /tmp を作業ディレクトリとします。

cd /tmp
# wget https://github.com/git/git/archive/vX.X.X.zip

「X.X.X」には最新のバージョンを入れてください。
最新のバージョンは、公式リポジトリの「branch master」→「tags」から確認できます。

(例)
2019年11月29日時点での最新は、2.24.0なので、
v2.24.0
となります。

ビルドする

# unzip vX.X.X.zip 
# cd git-X.X.X/
# make prefix=/usr/local all
# make prefix=/usr/local install

gitのパスを通す

.bashrcを編集するので、vimをインストールしておきます。
なお、編集さえできればよいので、エディタや手段は何でもよいです。

# apt-get install vim
# cd /
# vim .bash_profile
# source .bash_profile

.bash_profileの中に以下の1行を書き込みます

export PATH=$PATH:/tmp/git

動作確認

適当な場所で以下を入力し、意図するバージョンが返ってくれば成功です

# git --version
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む