cangoxina

生産性向上見習いのブログ的な何かです

gitをシンプルでわかりやすくするツールGitlessの紹介[和訳]

この記事は、gitをシンプルでわかりやすくするツールGitlessの紹介[和訳] - Qiitaアーカイブです。

gitについていろいろ調べていたら、Gitlessというgitのわかりにくい部分をシンプルにするツールを見つけましたが、日本語ドキュメントが現在(2017/02/19)さっぱりなかったので、勉強のために公式サイトの紹介ページを和訳してみました。

Google翻訳を多用しており、残りは意訳しています。Gitless自体理解しきれていないためよくわからずに訳した部分もあります。それは違うよ!という部分がありましたらコメントにてご指摘いただけると幸いです。

Gitless vs. Gitの比較画像はうまい載せ方を見つけられずに翻訳できていません。ご容赦くださいm( )m ※ 本文に出てくる実行画面の部分は訳さずに載せています。<*数字>は原文にはありません。


目次


About

Gitlessは、Git上に構築されたバージョン管理システムです。 多くの人がGitは使いにくいと訴えています。私たちは、Gitの基本的なシステムの中で、ユーザインタフェースよりも深い場所に問題はあると考えています。 Gitlessは、基本的なシステムを変更するベニア板をアプリケーション上に置くとどうなるかを調べるための実験です。GitlessはGit上に実装されているので(いわゆるGitのプロが「磁器」と呼ぶものです)、いつでもGitに戻ることができます。 もちろん、あなたとリポジトリを共有している同僚が、あなたがGitの愛好家ではないことを知ることは決してありません。

Gitlessを開始するには、Documentationをチェックしてください。

  • バージョン管理を初めてお使いの方は、Documentationを十分に活用して始めてください。
  • あなたが愛するGitとは何が違うのかを見たいGitのプロの方は、Gitless vs. Gitで違いを見つけることができます。
  • ソフトウェアデザインに興味があり、Gitlessの研究についてもっと学びたい場合は、Researchを参照してください。

Documentation

目次:Interfaceリポジトリの作成コミットブランチタグ付けリモートリポジトリの操作

Interface

  • gl init - 空のリポジトリを作成、または既存のリモートリポジトリからリポジトリを作成する
  • gl status - リポジトリのステータスを表示する
  • gl track - ファイルへの変更の追跡を開始する
  • gl untrack - ファイルへの変更の追跡を停止する
  • gl diff - ファイルへの変更の比較を表示する
  • gl commit - ローカルリポジトリの変更を記録する
  • gl checkout - コミットされたバージョンのファイルにチェックアウトする
  • gl history - コミット履歴を表示する
  • gl branch - ブランチの一覧表示、作成、編集または削除をする
  • gl switch - ブランチを切り替える
  • gl tag - タグの一覧表示、作成または削除をする
  • gl merge - あるブランチの変更を別のブランチにマージする
  • gl fuse - あるブランチの変更を別のブランチにヒューズする
  • gl resolve - コンフリクトを解決したファイルにマークを付ける
  • gl publish - アップストリームにコミットを公開する
  • gl remote - リモートの一覧表示、作成、編集または削除をする

リポジトリの作成

"foo"ディレクトリをリポジトリにしたいとします。これは、gl initコマンドで行います。これにより、現在の作業ディレクトリが空のリポジトリに変換され、foo内ファイルの変更の保存を開始する準備が整いました。

$ mkdir foo
$ cd foo/
$ gl init
✔ Local repo created in /MyFiles/foo *1

*1 ローカルリポジトリ/MyFiles/fooを作成しました

ほとんどの場合、空のリポジトリで作業を始めるのではなく、既存のリモートリポジトリをクローンして作業をしたいでしょう。 リモートリポジトリをクローンをローカルに作成するには、同じgl initコマンドの後にリポジトリのURLを与えることで実現できます。

$ mkdir experiment
$ cd experiment/
$ gl init https://github.com/spderosso/experiment
✔ Local repo created in /MyFiles/experiment *2
✔ Initialized from remote https://github.com/spderosso/experiment *3

2 ローカルリポジトリ/MyFiles/experimentを作成しました 3 リモートリポジトリhttps://github.com/spderosso/experimentから初期化しました

コミット

これでローカルリポジトリが完成しましたので、ファイルへの変更の保存を開始しましょう。Gitlessのファイルは、 trackeduntracked、またはignoreすることができます。

  • tracked fileは、Gitlessが変更を検出するファイルです。追跡されたファイルは変更があった場合、自動的にコミットの対象になり(gitで言うadd)、ステータスの「Tracked files with modifications」セクションに表示されます。
  • untracked fileは、Gitlessが変更を検出しないファイルです。これらは自動的にはコミットの対象にはならず、ステータスの「Untracked files」セクションに表示されます。
  • ignore fileは、Gitlessによって完全に無視されるファイルであり、ステータスの出力に現れません。

gl statusコマンドの出力例です。foo.pybar.pyは変更が加えられたtracked file.gitignoreは変更が加えられていないtracked filebaz.pyuntracked filefoo.pycignore file です

$ ls
bar.py  baz.py  foo.py  foo.pyc .gitignore
$ gl status
On branch master, repo-directory //

Tracked files with modifications: *4
  ➜ these will be automatically considered for commit
  ➜ use gl untrack <f> if you don't want to track changes to file f
  ➜ if file f was committed before, use gl checkout <f> to discard local changes

    foo.py
    bar.py

Untracked files: *5
  ➜ these won't be considered for commit)
  ➜ use gl track <f> if you want to track changes to file f

    baz.py
変更が加えられた追跡ファイル:
  ➜ これらは自動的にコミットの対象になります
  ➜ ファイル<f>の変更を追跡したくない場合は、gl untrack <f>を使用します
  ➜ 以前にファイル<f>がコミットされている場合は、gl checkout <f>を使用してローカル変更を破棄します
追跡されていないファイル:
  ➜ これらはコミットの対象にはなりません
  ➜ ファイル<f>の変更を追跡する場合は、gl track <f>を使用します

さて、これらの3つの異なる状態の間でファイルはどのように動くのでしょう?

.gitignoreファイルに記述されているignore指定と一致するファイルは無視されます。上記の例では、内容が *.pycの.gitignoreファイルがあります。foo.pycはそのパターンと一致しているので無視されます。

ignore specでマッチしない新しいファイルは、最初はuntracked fileです。あなたがそれを追跡したいならば、gl trackコマンドでそれを行うことができます。gl untrackコマンドを使用すると、追跡されたファイルに対する変更の追跡を停止することができます。gl checkoutコマンドを使用すると、ファイルを以前のバージョンにいつでも戻すことができます。

$ gl track baz.py
✔ File baz.py is now a tracked file *6
$ gl track baz.py
✘ File baz.py is already a tracked file *7
$ gl untrack baz.py
✔ File baz.py is now an untracked file *8
$ gl checkout foo.py
You have uncommitted changes in foo.py that would be overwritten by checkout. Do you wish to continue? (y/N) *9
> y
✔ File foo.py checked out successfully to its state at HEAD *10

6 ファイルbaz.pyは追跡されたファイルになりました 7 ファイルbaz.pyは既に追跡されたファイルです 8 ファイルbaz.pyが非追跡ファイルになりました 9 チェックアウトによって上書きされるコミットされていないfoo.pyの変更があります。続行しますか?(y/N) *10 ファイルfoo.pyがHEADの状態に正常にチェックアウトされました

ファイルへの変更を保存するには、gl commitコマンドを使用します。 デフォルトでは、変更されたすべての変更ファイルはコミットされますが、o/onlye/exclude、およびi/includeフラグを使用して、コミットするファイルのセットをカスタマイズできます。

$ gl commit -m "foo and bar"
$ gl commit -m "only foo" -o foo.py
$ gl commit -m "only foo and baz" -o foo.py baz.py
$ gl commit -m "only foo" -e bar.py
$ gl commit -m "only foo and baz" -e bar.py -i baz.py
$ gl commit -m "foo, bar and baz" -I baz.py

コミットするファイルのセグメントをインタラクティブに選択できるp/partialフラグもあります。

gl diffコマンドを使用して、作業バージョンとコミット済みバージョンのファイルの違いを確認することができます。コミットのように、diffのデフォルトのファイルセットはすべての変更されたファイルのセットですが、o/onlye/exclude、およびi/includeフラグでカスタマイズできます。

ファイルの削除は、OSの機能(Unixのrmコマンドを使用するなど)を利用して簡単に行えます。Gitlessでは、ファイルが追跡されている場合に削除を検出し、ステータスで削除されたものとしてに表示します。 Gitlessは現在、名前の変更を検出しません。ファイルの名前を変更した場合、Gitlessでは古い名前のファイルが削除され、新しい名前と内容の新しいファイルが作成されたとして解釈します。名前を変更したファイルを再び追跡するには、gl trackをする必要があります。

ブランチ

ブランチは独立した開発ラインです。 あなたは常になにかしらのブランチで作業しています。各ブランチには独自の履歴があります(gl historyコマンドで見ることができます)。ブランチを切り替えると、既存のファイルやブランチ上に作成した新しいファイルに対する変更は、他のブランチには反映されません。

新しいブランチを作成するには、gl branchコマンドを使用します。 別のブランチに切り替えるには、gl switchコマンドを使用します。

$ gl branch -c develop
✔ Created new branch develop *11
$ gl switch develop
✔ Switched to branch develop *12

11 新しいブランチ"develop"を作成しました 12 ブランチ"develop"に切り替えしました

すべてのブランチ一覧の表示するには:

$ gl branch
List of branches:
  ➜ do gl branch <b> to create branch b
  ➜ do gl branch -d <b> to delete branch b
  ➜ do gl switch <b> to switch to branch b
  ➜ * = current branch *13

    * master
      develop

*13 *は現在のブランチ

各ブランチにはHEADがあり、そのブランチで最後にコミットされたものです。デフォルトでは、新しいブランチの先頭は現在のブランチのHEADと等しくなります。別のコミットを新しいブランチの頭にしたい場合は、dp/divergent-pointフラグを与えることで可能です。

コミットを指定するには、そのIDを使用するか、"~"を使用して祖先参照で指定できます。HEAD~nは、HEADより前のn番目のコミットを参照します。

現在のブランチのHEADを変更するには、sh/set-headフラグを使用します。shフラグは、例えば最後のコミットを修正するのに便利です。そうするには、gl branch -sh HEAD~1を実行します。現在のブランチのHEADを変更しても作業ディレクトリには反映されませんが、さらに作業ディレクトリを新しいHEADと一致するようにリセットしたい場合は、gl checkoutを使用します。

最終的にブランチは最終的に変化していくでしょう。あるブランチから現在のブランチに変更を加えるには、mergefuseの2つの方法があります。

merge

あるブランチの変更を現在のブランチにマージするには、gl merge developを行います。これにより、現在のブランチの変更に加えて、developブランチの変更を含む新しいマージコミットが作成されます。 f:id:korosuke613:20200925232757p:plain

fuse

ブランチをヒューズすると、マージよりもコントロールがしやすくなります。 あるブランチからの変更を現在のブランチにヒューズするときに、ヒューズするコミットと挿入場所を指定することができます。デフォルトでは、すべてのブランチがヒューズされると、挿入場所は分岐点(あるブランチが現在のブランチから分岐したポイント)になります。

たとえば、次の図は、2つのブランチが存在する状況を示しています。master(現在のブランチ)とdevelopです。2つのブランチが共通している最後のコミットは"A"です。このコミットは「分岐点」(masterとdevelopの分岐点であるため)です。gl fuse developmentを実行した後、開発中のコミットは、masterの分岐点の後ろに挿入されます。

f:id:korosuke613:20200925232845p:plain

他の挿入場所を選択するには、ip/insertion-pointフラグを使用します。コミットID、HEADまたはdp/divergent-pointを与えることができます。

f:id:korosuke613:20200925233129p:plain

o/onlyまたはe/excludeフラグを使用して、ヒューズされるコミットのセットをカスタマイズできます。

f:id:korosuke613:20200925232941p:plain

このプロセス中にコンフリクトが発生する可能性があります。その場合、gl statusコマンドはそれに応じて変更され、競合しているファイルを示します。競合したファイルを編集すると、gl resolve(ファイル名を与えるとそれをマークする)で解決されたものとしてマークされます。すべての競合が解消されたら、"gl commit"を実行してヒューズまたはマージを続けます。

ブランチは「アップストリームブランチ」を持つことができます。ブランチにアップストリームが関連付けられている場合、gl fuseまたはgl mergegl {fuse、merge} upstream_branchの略記として使用できます。現在のブランチのアップストリームブランチを設定するには、gl branch -su <upstream_branch>を使用します。

タグ付け

コミットが何らかの形で特別であることを示すためにタグを使用します。たとえば、gl tagを使用して「v1.0」という名前のタグを作成し、リリースv1.0を表すコミットを指すようにすることができます。

$ gl tag -c v1.0
✔ Created new tag v1.0 *14

*14 新しいタグv1.0を作成した

この場合タグは現在のブランチの先頭を指しますが、ci/commitフラグを付けて他のコミットにタグ付けすることもできます。

$ gl tag
List of tags:
  ➜ do gl tag <t> to create tag t *15
  ➜ do gl tag -d <t> to delete tag t *16

    v1.0 ➜  tags 311bf7c Ready to release

15 gl tag <t>でタグtを作成します 16 gl tag -d <t>でタグtを削除します

リモートリポジトリの操作

リモートリポジトリを参照するのに、そのURLを常に使用することができますが、より簡単な方法はgl remoteコマンドでリポジトリを "リモート"として追加することです。

$ gl remote -c experiment https://github.com/spderosso/experiment
✔ Remote experiment mapping to https://github.com/spderosso/experiment created *17
successfully
  ➜ to list existing remotes do gl remote *18
  ➜ to remove experiment do gl remote -d experiment *19

17 リモートリポジトリhttps://github.com/spderosso/experimentへのリモート"experiment"を作成しました 18 gl remoteで既存のリモート一覧を表示します *19 gl remote -d experimentでリモート"experiment"を削除します

これで、 "experiment"を使ってこのリモートリポジトリを参照し、 experiment/some-branchを使用して、 "experiment"に存在する"some-branch"のブランチを参照することができます。

変更をダウンロードする

リモートブランチからの変更をヒューズまたはマージすることも可能です。たとえば、gl merge experiment/masterを実行すると、ローカルブランチに存在しないリモートブランチの変更がマージされます。また、gl fuseを使用することもできます。

変更のアップロードする

アップストリームで変更を送信するには、gl publishを使用します。パブリッシュコマンドは、入力を与えられていない場合、デフォルトで現在のブランチのアップストリームブランチを更新します。

作成、削除、または一覧表示

リモートブランチを作成、削除、または一覧表示するには、ローカルブランチに使用するのと同じgl branchコマンドを使用します。 "gl branch -c experiment/develop"を実行すると、リモート"experiment"に存在する"develop"ブランチが作成されます。デフォルトでは、この新しいブランチのHEADは現在のブランチのHEADと等しくなるので、リモートに存在しないすべてのコミットがアップロードされることに注意してください。 リモートブランチを表示するには、 gl branchr/remoteフラグを使用します。

タグの作成、削除、または一覧表示

リモートタグを作成、削除、または一覧表示するには、gl tagコマンドを使用します。 gl tag -c experiment/v1.0を実行すると、リモートの"experiment"に新しいタグv1.0が作成されます。 gl tagr/remoteフラグを使ってリモートのタグ一覧を表示することもできます。

リモートからローカルリポジトリを作成すると(gl initコマンドの入力としてURLを渡すことによって)、リモートブランチごとにローカルブランチが作成され、各ローカルブランチは、リモートをアップストリームとして自動的に設定されます。

Gitless vs Git

変更を保存する

Gitlessにはステージングエリアはありません。 これは、柔軟なコミットコマンドと組み合わせることで、リポジトリへの変更を非常に簡単に保存できます。

f:id:korosuke613:20200925233227p:plain

また、ファイルの分類を変更して、追跡したり、非追跡したり、無視したりすることもできます。ファイルがHEADに存在するかどうかは関係ありません。

f:id:korosuke613:20200925233315p:plain

ブランチ

理解しなければならない主な点は、Gitlessではブランチが完全に独立した開発ラインであることです。各ブランチは、ファイルの作業バージョンを互いに分離して保持します。別のブランチに切り替えると、作業ディレクトリの内容が保存され、切り替え先のブランチに対応する内容が取得されます。ファイルの分類も保存されます(ファイルは一部のブランチでは非追跡ですが、別のブランチでは追跡します、Gitlessはこれを覚えています)。

f:id:korosuke613:20200925233403p:plain

つまり、Gitlessでは、コミットされていない変更が切り替え先ブランチの変更と矛盾することを心配する必要はありません。

f:id:korosuke613:20200925233435p:plain

あなたがヒューズまたはマージの途中にいて、コンフリクトの解決を脇に置いておきたい場合は、そうすることができます。あなたがそのブランチに戻ったときにコンフリクトはそこにあります。

f:id:korosuke613:20200925233506p:plain

リモートリポジトリの操作

Gitlessの他のリポジトリとの同期は、Gitと非常によく似ています。

f:id:korosuke613:20200925233537p:plain

Reserch

Gitlessに関連する論文のリスト



スポンサーリンク