エディタを使って「もの」を書くときには何度も書き足し、書き直せる。 直しているつもりが余計おかしくなったりすることもあるので、 書き直す前のものを保存しておきたいこともよくある。
このような場合には、一つのファイルを新規に作成したときから、現在、未来 に渡って希望する時点の全てのバージョンを記録できるツールを利用する。 これをリビジョン管理システム といい、大切なファイルを 作成する場合には欠かせないものである。
バージョン管理システム(VCS)を使うと、 プログラムのソースやテキストファイル形式の文書の任意の時点の状態を保存でき、 あとから任意のリビジョンを取り出すことができる。VCSを利用してバージョン 管理する場合の流れは以下のようになる。
(最初の一回のみ)履歴管理を行いたいディレクトリを単位として 新規 リポジトリ を作成する
リポジトリ(ディレクトリ)内にファイルを新規作成し、 リポジトリに登録する。
(そのファイルのこのバージョンを保存したいと思ったときに)
ファイルを コミット(チェックイン) する。
そのまま編集作業を続ける
そののち、以前に登録していたバージョンを参照したいときには、
などの操作ができる。
ここではバージョン管理ツールとして最も広く用いられている Gitを利用した作業方法を簡単に説明する。
利用する端末ごとに編集者登録を行う。 以下の2つのコマンドをターミナル実行する。
git config --global user.email 《自分のemailアドレス》 git config --global user.name "《自分のローマ字名》"
まず、リポジトリを新規作成する。2パターンある。
順に説明する。
新規にディレクトリを作成し、そこで初期化するコマンドを打つ。
この例では myrepo
というディレクトリをリポジトリとする。
mkdir myrepo # ディレクトリを作成 cd myrepo # そこに移動 git init # リポジトリ初期化 echo "My repository" > README.md # ひとまずREADME.mdファイルを作る ls # 確認 README.md git add README.md # README.mdをリポジトリに登録 git commit -m "Start my repository" # 更新を登録
リモートGitサーバにアカウントを持っている場合は、 リポジトリサーバ上でリポジトリ作成し、それを手元のディレクトリに クローンしてくるのがよい。手順を簡潔にまとめると以下のとおり。
編集するファイルをGit管理下に置くには、git add する。 通常はコマンドラインで行う。
cd リポジトリのディレクトリ git add 管理下に置きたいファイル名
Emacsを利用してファイルをGit管理するととても簡単である。
C-x v v をタイプすると、 そのファイルが未登録の場合は即座にリポジトリに登録される。
C-x v v をタイプすると説明を入れるバッファが 現れるので、更新の意図を表す短文を入れて C-c C-c をタイプする
キー操作として、C-x v v だけを覚えておけばよい。 実際にやってみよう。
ここで、foo.html
をGit管理するやり方を追ってみよう。
リポジトリとなるディレクトリ内でのファイル作成・操作であると仮定する。
foo.html
を作成する
簡単のためファイルの内容は以下のとおりとする。
<!DOCTYPE html> <html lang="ja"> <head><title>foo!</title></head> <body> <h1>fooについて</h1> </body> </html>
ファイルが書けたら保存する(C-x C-s)。
C-x v vをタイプする。一度addすれば以後は そのファイルが履歴管理されるようになる。
新しい文章を書き加えよう。以下のように修正する。
<!DOCTYPE html>
<html lang="ja">
<head><title>foo!</title></head>
<body>
<h1>fooについて</h1>
<p>fooは「ふー」と読みます。</p>
</body>
</html>
追加が終わったら保存する。
C-x v vをタイプする。隣にログメッセージを 入力するためのバッファが現れるので、他者にも伝わる更新メモを残す。 何も書かなくてよいが、あとでそのバージョンを取り出す手がかりとなるので、 できるだけ「何故そうしたか」を書く。C-x v v をタイプしたときに出てくるが、ログメッセージを書き終わったら C-c C-c をタイプする。
<!DOCTYPE html> <html lang="ja"> <head><title>foo!</title></head> <body> <h1>fooについて</h1> <p>fooは「ふー」と読みます。</p> </body> </html> |
-[あ]-E.E:%%-F1 foo.html ALL L7 RCS:1.1 (yahtml Fill) [1]-- |
Summary: 読み方を足したよ
|
ログメッセージを書いたら C-c C-c で履歴登録(コミット)が完了する。
以後、まとまりのある修正が完了するごとにコミットを繰り返していく。
過去にコミットしたものをいつでも取り出せる。そのときには、 コミット時のログメッセージが手がかりとなる。
C-x v l をタイプする(最後は log のエル)。 下のウィンドウに過去にチェックインしたときのログがあらわれる。
commit 10c7471c59b86df760478a558bbace28aa6d8e35 Author: HIROSE Yuuji <ta01002@e.koeki-u.ac.jp> Date: Sun Apr 16 17:08:13 2023 +0859 「こんにちは」を足した。 commit fc0a0e763b2ee2431ff87354689fcc6ff7f8ec5a Author: HIROSE Yuuji <ta01002@e.koeki-u.ac.jp> Date: Sun Apr 16 17:07:48 2023 +0859 Dupliate yeah commit 43bad956b86bab4086f57f51a9956fc2d043c955 Author: HIROSE Yuuji <ta01002@e.koeki-u.ac.jp> Date: Sat Apr 15 18:16:05 2023 +0859 index.htmlを新規作成した
直前のリビジョンとの差分を見るには C-x v = を タイプする。
もっと古いリビジョンと比べたいときは、C-x v l の
ログ一覧から比較したいバージョンが、今のものから何個前かを見ておく。
3つ前のバージョンと比べたければ
C-u C-x v = のあと master~3
とタイプする。
Older revision (default master~1): master~3 (古いリビジョン番号を入力する) Newer version (default: current source): (そのまま[Enter])
現在のソースとの比較結果が下のバッファにあらわれる。
diff --git a/index.html b/index.html index eda1664..e07dbaf 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,7 @@ <body> <h1>でざいんする!</h1> -<p>やあ</p> +<p>やあやあ</p> +<p>こんにちは。</p> </body> </html>
行の先頭にマイナスのついているのが、元のソースから消えた行、 プラスのついているのが新しい方に現れた行を意味する。
よく使う割り当てキーの一覧を示す。
C-x v v | チェックイン or チェックアウト |
C-x v l | ログ一覧を見る |
C-x v g | Annotate |
C-x v = | 直前のリビジョンとの差分を見る |
C-u C-x v = | 指定したリビジョンとの差分を見る |
Gitの全ての機能を利用するにはコマンドを利用する。
コミットには、git commit
コマンドを使う。
git commit [オプション] ファイル
ファイルをチェックインする。よく使うオプションは以下のとおり。
-m "ログメッセージ"
(ほぼ必須)ログメッセージを指定する
-a
前回のコミットから修正のあったファイルをすべてコミットする。
-m "文"
をつけずに git commit
するとログメッセージの入力を求めてくる。
viエディタが上がる設定の場合は以下のような画面になる。
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch master # Your branch is ahead of 'origin/master' by 3 commits. # (use "git push" to publish your local commits) # # Changes to be committed: # modified: index.html
(※重要※)キーボードで小文字のi(アイ)を打ってから短文を入れ、
ESC Z Z と(ESCキーのあと大文字Zを2回)押す。
viの使い方を知らないと迷子になるので git commit
のあとの
-m "ログメッセージ"
は欠かさずつけたほうがよい。
古いバージョンのファイルを取り出すことをチェックアウト という。
編集中の1つのファイルの昔のバージョンを見たいだけの場合はEmacsから
C-x v g (vc-annotate) を呼び出す。まとめて取り出したいときは
コマンドラインから git checkout
を使う。
押した瞬間に以下のような画面が現れる。
43bad956 (HIROSE Yuuji 2023-04-15 1) <!DOCTYPE html> 43bad956 (HIROSE Yuuji 2023-04-15 2) <html lang="ja"> 43bad956 (HIROSE Yuuji 2023-04-15 3) <head> 43bad956 (HIROSE Yuuji 2023-04-15 4) <title>でざいんするぜ!</title> 43bad956 (HIROSE Yuuji 2023-04-15 5) <link rel="stylesheet" type="text/css" href="main.css"> 43bad956 (HIROSE Yuuji 2023-04-15 6) </head> 43bad956 (HIROSE Yuuji 2023-04-15 7) 43bad956 (HIROSE Yuuji 2023-04-15 8) <body> 43bad956 (HIROSE Yuuji 2023-04-15 9) <h1>でざいんする!</h1> fc0a0e76 (HIROSE Yuuji 2023-04-16 10) <p>やあやあ</p> 10c7471c (HIROSE Yuuji 2023-04-16 11) <p>こんにちは。</p> 43bad956 (HIROSE Yuuji 2023-04-15 12) </body> 43bad956 (HIROSE Yuuji 2023-04-15 13) </html>
-U:%*- *Annotate index.html (rev master~1) All L8 (Annotate from index.html) --
モードライン(最下行反転部)にある rev master~1
が、
現行バージョンから何個前のバージョンを示す。
チェックアウトで特定のバージョンの複数のファイルをまとめて取り出したいときはコマンドラインで
p | 1つ前(古い)バージョンに移動 |
n | 1つ次(新しい)バージョンに移動 |
j | カーソル行のバージョンに移動 |
w | ワーキング中のバージョンに移動 |
d | 該当バージョンとの差分表示 |
l | 該当バージョンのコミットログ表示 |
v | 左にある注釈表示のON/OFF |
f | 該当バージョンのファイルをチェックアウトして開く |
最後の f は、作業ディレクトリにそのバージョンのファイルを バージョン番号付きの名前で取り出すのでやりすぎるとディレクトリに 不要なファイルがたくさんできる(以下はEmacs vc-annotate でf を押してファイルを開いたあとにコマンドラインでlsしたもの)。
ls README.md index.html.~43bad956~ main.css index.html index.html.~fc0a0e76~
ファイル名の最後が ~
となっているのが
一時的にチェックアウトされたファイルである。大抵の場合不要であるため
Emacsから一気に消す方法を示す。
Emacsでindex.html
を開いたままfind-file
(C-x C-f)し、ファイル名を打たずにディレクトリのまま
[Enter]するとディレクトリエディタ(dired)が立ち上がる。
/home/irhome/c101/ta01002/public_html/2023-yuuji: total used in directory 1 available 1 TiB drwxr-xr-x 3 ta01002 st2001 4096 Apr 16 18:15 . drwxr-xr-x 4 ta01002 st2001 4096 Apr 15 18:30 .. drwxr-xr-x 8 ta01002 st2001 4096 Apr 16 17:30 .git -rw-r--r-- 1 ta01002 st2001 121 Apr 15 18:21 README.md -rw-r--r-- 1 ta01002 st2001 264 Apr 16 17:30 index.html -rw-r--r-- 1 ta01002 st2001 209 Apr 16 17:48 index.html.~43bad956~ -rw-r--r-- 1 ta01002 st2001 215 Apr 16 18:15 index.html.~fc0a0e76~ -rw-r--r-- 1 ta01002 st2001 54 Apr 15 18:38 main.css
ここでバックアップファイルをマークする ~ をキー入力すると以下のように削除マーク(D)が付く。
/home/irhome/c101/ta01002/public_html/2023-yuuji: total used in directory 1 available 1 TiB drwxr-xr-x 3 ta01002 st2001 4096 Apr 16 18:15 . drwxr-xr-x 4 ta01002 st2001 4096 Apr 15 18:30 .. drwxr-xr-x 8 ta01002 st2001 4096 Apr 16 17:30 .git -rw-r--r-- 1 ta01002 st2001 121 Apr 15 18:21 README.md -rw-r--r-- 1 ta01002 st2001 264 Apr 16 17:30 index.html D -rw-r--r-- 1 ta01002 st2001 209 Apr 16 17:48 index.html.~43bad956~ D -rw-r--r-- 1 ta01002 st2001 215 Apr 16 18:15 index.html.~fc0a0e76~ -rw-r--r-- 1 ta01002 st2001 54 Apr 15 18:38 main.css
続けてキーボード x をタイプするとファイルが消される。
diredはファイルを選んで消したいときに利用できる。 消したいファイルの行で d を押すと削除マーク(D)が付くので 消したいタイミングで x を押せばよい。
コマンドラインでリポジトリディレクトリにcdしてから、
git checkout
の後ろに戻したいバージョンを指定する。
戻したいバージョンは git log
で確認する(これがgitの不便なところ)。
commit 9fd4a5a57ccc03eb75c3f28f4497a54d404b7908 (origin/master, origin/HEAD) Author: HIROSE Yuuji <ta01002@e.koeki-u.ac.jp> Date: Sat Apr 15 18:38:38 2023 +0859 背景色を変更した commit 855b51cbc289f8963a6dd4abb02008aedb0da030 Author: HIROSE Yuuji <ta01002@e.koeki-u.ac.jp> Date: Sat Apr 15 18:36:26 2023 +0859 main.cssファイルを足した commit 80d327c1f3e02c83db1c9568222d27759695c842 Author: HIROSE Yuuji <yuuji@yatex.org> Date: Sat Apr 15 18:20:12 2023 +0900 index.htmlへのリンクを張った commit 43bad956b86bab4086f57f51a9956fc2d043c955 Author: HIROSE Yuuji <ta01002@e.koeki-u.ac.jp> Date: Sat Apr 15 18:16:05 2023 +0859 index.htmlを新規作成した commit ebef68bd4903afc2094b3619812864ee1dddb2d0 Author: HIROSE Yuuji <yuuji@yatex.org> Date: Sat Apr 15 18:13:34 2023 +0900 Initial commit
"commit" の後ろにある16進数文字列がリビジョン番号で、
これを指定する(長すぎるのでコピペするしかない)。
もしくは目で何個前か数えて git checkout -f master~3
などとする。
指定したリビジョンとの差分を見るには git diff
コマンド
を使う。
とするとリビジョン の時点のものと現在のファイル の差分が表示される。リビジョン を省略すると、 最後にコミットしたバージョン、「ファイル」を省略するとすべての ファイルが対象となる。
C-x v = でソースの変更した箇所を調べたときに出てきた 内容は GNU diff 形式 という。テキストファイルの変更点のみを 記したもので、元のファイルがどんなに大きくても、修正点が少なければ diff形式はその部分だけで済む。大きなソースを配布する場合に 新しいリビジョンの変更点のみをdiff形式で配布することにより、 とても少ない通信量で済ませることができる。
diff -ua 旧ファイル 新ファイル > file.diff
として差分を file.diff
に保存する。相手側が
旧ファイル を持っていた場合相手側では
patch < file.diff
とすると、手元にあるファイルが新しいものに書き換えられる。
yuuji@koeki-u.ac.jp