Gitを使った開発作業
やること:
- gitコマンドを使うための準備作業をする。
- 「git clone」で ローカルリポジトリ を作る。
- (作業コピー上でプログラム作成)
- 編集結果をローカルリポジトリに コミット。
- リモートリポジトリに push(自分の編集結果をリモートリポジトリに送る)。
参考資料:
オンラインマニュアル:
git help コマンド名
(例えばgit help commit
)または
man git-コマンド名
(例えばman git-commit
)
1. Gitコマンドを使うための準備
やること:
- gitコマンド用のユーザ名・電子メールアドレスを設定する。
- GitHubにアクセスするための 個人アクセストークン (personal access token) を生成し,
.netrc
ファイルに記述する。
1-1. gitコマンドにユーザ名・電子メールアドレスを設定
「誰による コミット (commit)(編集結果の記録)か」を記録するために,ユーザ名 (user.name)・電子メールアドレス (user.email) の設定が必要。両方設定していないとコミットできない。
重要なのは 電子メールアドレス である。Gitでは基本的に,電子メールアドレスで個人を特定する。
- 本科目では,user.email として 必ず学内メールアドレス (270xxxx@ugs.kochi-tech.ac.jp) を設定すること (違う電子メールアドレスによるコミットは 成績評価の対象にならない)。
- 一方,user.name は(人間が編集履歴を見たときに分かりやすくするための)単なるニックネームである。成績評価とは無関係。GitHubユーザ名と同じでも違ってもよい。
- 参考:Pro Git bookの1.6節の「個人の識別情報」の項
設定誤りを防ぐため,WS室では,以下のコマンドを実行して自動設定することを勧める。
$ ~y-takata/Public/git-setup
I will setup your user.name & user.email on git.
Input your user.name: hoge123
Done!
Please check the following list:
user.name=hoge123
user.email=270999x@ugs.kochi-tech.ac.jp
push.default=current
I have also created a .netrc file.
Please edit the file appropriately.
user.name を質問されるので好きな名前を入力する。 user.email は自動設定される。 最後に表示される設定結果を見て,意図通りでなければ,再度実行して上書きすればよい。
(最後のメッセージの .netrc については次の節 1-2 で説明する。)
(自宅のPC等に設定する場合)
上記の git-setup が行っている内容は以下の通り。
$ git config --global user.email 270xxxx@ugs.kochi-tech.ac.jp
$ git config --global user.name hoge123
$ git config --global push.default current
上述の通り,user.email が正確に学内メールアドレスに一致しないと,成績評価の際に無視されるので注意。
3行目の push.default は git push コマンドの動作設定。設定していないと毎回設定を促されるので,ついでに設定している。
[重要] アカウント情報と成績評価に関する補足
GitHubのWebサイト上でもファイルを編集したり追加したりできるが,そのコミットには上記の電子メールアドレスの設定は 反映されない (上記の設定はLinux上のgit
コマンドに対する設定なので当たり前)。
従って,Webサイト上での編集は 成績評価の際は無視される。(仮にGitHubアカウントに学内メールアドレスを登録していても,Webサイト上での編集にはそのアドレスは使われない。自動生成された匿名メールアドレスが使われる。)
Webサイト上での編集機能は(成績に反映されなくてもよい場合以外)使わないことを勧める。
1-2. 個人アクセストークンの生成と .netrc への記述
(2021年8月より,gitコマンドでGitHubにアクセスする際には個人アクセストークンを使うことが必須になった。)
アクセストークンとは,サーバ側がランダムに生成するパスワードのようなもの。流出しても破棄するだけでよい,などの利点がある。 人間が記憶しておくのはまず不可能なので,ここでは .netrc ファイルに保存することにする。
やること:
- GitHub上で個人アクセストークンを生成する.
- 「個人アクセストークンの作成」の説明に従って作業する。 「fine-grained」と「(classic)」の2種類があるが,本科目では「(classic)」を選ぶこと。
- Note(トークン名)は何でもよい。何のために生成したトークンか後で思い出すために付ける名前。
- Expiration(有効期限)は,この5回の授業で使うだけなら 30 days でよい。もっと長い期間も選べるし,短い期限を選んで,期限が切れたら更新してもよい。
- Scopes(付与する権限)は repo を選ぶ。ほかの権限は不要。
- アクセストークンは一度しか表示されないので,次の2.が完了するまでページを閉じないこと。
- .netrcファイルに個人アクセストークン等の情報を記述する。
- 前節で git-setup コマンドを実行すると,ホームディレクトリに .netrc ファイルが作成される。
- .netrc に以下の形式で情報を書き込む。
machine github.com
login GitHubユーザ名
password 個人アクセストークン
(git-setupコマンドを実行した際,.netrc のパーミッションは 600(自分のみ読み書き可能)に設定される。アクセストークンは,破棄は容易だしGitHub以外には使えないが,他人に知られないようそれなりには注意すべき。)
2. ローカルリポジトリの作成 (clone)
下記2.のgit clone
は,全員が同時に行うとサーバの応答が遅くなるので,授業中の指示に従って順番に行うこと。
- 前回の演習1.1-8で作成した自分のGitHubリポジトリのWebページを開き,リポジトリ名を確認する。
q0-warmup-ユーザ名
となっているはず。ユーザ名
はGitHubでのユーザ名である。 次のステップ2.で使うclone用URLは以下のようになる(緑色の Code というボタンを選択するとURLを確認できる)。
https://github.com/kut-info-pl2/q0-warmup-ユーザ名.git
- 端末にて,下記のように
git clone URL
を実行する(新規ディレクトリを作ってその中で実行することを奨める)。$ mkdir git -- 新規ディレクトリを作る $ cd git $ git clone https://github.com/kut-info-pl2/q0-warmup-HogeHoge.git Cloning into 'q0-warmup-HogeHoge'... remote: Enumerating objects: 6, done. remote: Counting objects: 100% (6/6), done. remote: Compressing objects: 100% (4/4), done. remote: Total 6 (delta 0), reused 5 (delta 0), pack-reused 0 Unpacking objects: 100% (6/6), done. $ cd q0-warmup-HogeHoge -- 作業コピーにcdする $ ls README.md chap2 -- 作業コピー中のファイルとディレクトリ $ ls -aF ./ .git/ README.md ../ .gitignore chap2/
( .netrc に記述した情報が誤っていると git clone に失敗する。)
(1
(いち)とl
(エル)などの似ている文字に注意。pl2
(ピー エル 2)は programming lab II(= 実験第2)を表す。)
q0-warmup-ユーザ名
というディレクトリの中に 作業コピー が取り出される。このディレクトリの中の .git
という隠しディレクトリが ローカルリポジトリ の本体だ(.git
の中はいじらない方がよい)。
用語
- リモートリポジトリ … Gitサーバ(この授業ではGitHub)上にあるリポジトリ。
- ローカルリポジトリ … 各自のコンピュータ上にあるリポジトリ。(この授業では)リモートリポジトリを clone(複製)して作る。編集結果はまず自分のローカルリポジトリに コミット (commit) し,その後,リモートリポジトリに push(送信)する。
- 作業コピー … ローカルリポジトリから取り出したファイルのコピー一式。編集作業は作業コピーに対して行い,編集が一段落したらローカルリポジトリにコミットする。その後,リモートリポジトリにpushする。
本授業ではしばらくの間,個人ごとのリポジトリの上で編集作業を行う。 その後,複数人で共有するリポジトリを作成し,その上で共同編集作業を行う。
3. 編集作業
「どのディレクトリにどういう名前のファイルを置くか」等は各演習課題の説明を読むこと。
第2章の演習1.2-xについては,「chap2」サブディレクトリの中に,指定された名前のソースファイルを作成する。
4. ローカルリポジトリへのコミット
- git statusを実行して,変更したファイルを確認する。
上の例では「123.s が新しく作られている」という情報が表示されている。 (末尾の「nothing added to commit」という行に注意。この状態では何もコミットされない。)$ git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # 123.s nothing added to commit but untracked files present (use "git add" to track)
- コミットしたいファイルに対して git add を実行する。
複数のファイルをgit addできる(互いに関連し合う変更は1コミットにまとめた方がよい)。$ git add 123.s
git addした時点でgit statusを実行すると,状態が変わったことが確認できる。
(「Changes to be committed:」の下に表示されているファイルがコミット対象。)$ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: 123.s #
- git commit を実行する。
エディタが起動するので,適切なコミットメッセージを記述すること。
$ git commit -- エディタが起動する -- メッセージを入力してエディタを終了 [master 9c33da0] 123.sを作成 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 chap2/123.s
参考:
- git addを取り消したい場合は「git reset HEAD ファイル名」を実行する(git status で表示されるメッセージを読めば書いてある)。
- .oファイルや実行可能ファイル (a.out) やEmacsが作るバックアップファイルなどは,特別な理由がない限り,リポジトリには追加しないこと。リポジトリのルートディレクトリに
.gitignore
というファイルを作ってその中に無視したいファイル名を書いておくと,gitはそのファイルを無視する。 git commit -m '123.sを作成'
のように,コマンドライン中にコミットメッセージを記述することもできる。この場合はエディタは起動しない(メッセージが空白を含む場合は引用符'
で囲まなければならない。引用符で囲むよう習慣付けておくのが安全)。
[重要] 不要なファイルをコミットしないこと
実行可能ファイルやオブジェクトファイル (.o
) など,「ソースファイルから生成されるファイル」はコミットしない(バージョン管理の対象にしない)こと。
基本的に「自分が記述したファイル」のみコミットすること。
実行可能ファイル等がリポジトリに登録されていると,成績評価時の自動テストに支障を来すことがある。
(実行可能ファイル等は,同一のソースファイルをアセンブルした場合でも,OSやアセンブラやリンカのバージョンの違いやその他の理由により,完全には同一にならないことがある。そのため,成績評価者やチームのメンバーがアセンブルやコンパイルを行うだけで「管理対象ファイルを変更した」ことになってしまい,その変更をコミットするか履歴を遡って取り消すかしないと先に進めなくなる。
また,これらのファイルは機械的に生成できるのだから,それを登録するのは容量の無駄でもある。)
コミットメッセージ
コミットメッセージとは,変更履歴(ログ)に記録されるコメントだ。 git logコマンドを実行すると一覧が表示される。
$ git log
commit 9c33da03e8dbaf1d95cf6a997bc9849ef0f510b2
Author: ytakata69 <takata.yoshiaki@kochi-tech.ac.jp>
Date: Thu Sep 15 11:15:47 2016 +0900
123.sを作成
commit 7ac3bf5bb664c07f47c2471ac3b4fbfe676bc264
Author: ytakata69 <takata.yoshiaki@kochi-tech.ac.jp>
Date: Wed Sep 14 19:58:25 2016 +0900
Add chap2 subdirectory
-- 略 --
-- ログが長い場合「ページ単位で表示」モードになる。スペースキーで次ページに進む。qキーで終了する。
--oneline
オプションを付けると簡潔な表示になる。
$ git log --oneline
9c33da0 123.sを作成
7ac3bf5 Add chap2 subdirectory
23b0570 Add Emacs backup files and LaTeX aux files to .gitignore
85b1bb2 Remove '*.hex' from .gitignore
31073cb Initial commit
「これまでどういう変更を行ってきたか,ログを見れば概ねわかる」ように書くのが適切だ。また,「ある変更を行った時点のファイルを取り出したい」と思ったとき,コミットメッセージを適切に書いていれば,メッセージを検索することで容易に該当コミットを見つけられる。
例えば,「123.sを更新」「123.sを更新」「123.sを更新」…と同じメッセージが続くようなログは適切でない。メッセージが具体的でないのでどういう変更を行ってきたか推測できないし,後で検索するときにも困る。 適切でないコミットログが多い場合,成績評価時に減点することがある。
[重要] 一度記録したコミットは変更できない
コミットは「後へ後へ」足していくものであり,一度記録したコミット自体は原則として取り消したり変更したりできない(一度編集したファイルを再度編集して「次のコミット」に記録するのは全く問題ない。コミット自体を「なかったことに」したりはできない,という意味)。
コミットメッセージの変更も「コミットの変更」に当たるのでできない。
ただし,次項の「push」をまだしていない場合に限って(つまり変更が自分のローカルリポジトリの中にしかない場合),コミットの変更は可能である。
もしコミットの変更が必要な場合は,git commit
の--amend
オプションについて自分で調べなさい。
なお,すでに「push」しているのに git commit --amend
でコミットを変更してしまった場合,(1) それ以降「push」できなくなる,(2) 無理やりpushすると,成績評価者やチームメンバーがそのリポジトリを使えなくなる。つまり,どちらにしろ それ以降実験を継続できなくなる。
git commit --amend
は非常に危険と認識した上で,もし使うとしても「たった今行ったコミットのコミットメッセージを変更する」程度にだけ使うのがよいだろう。
5. リモートリポジトリへのpush
以下のコマンドを実行すると,リモートリポジトリにまだ送信していないコミットがリモートリポジトリに送られる。
$ git push
pushしていないコミットは自分にしか見えない。 pushすることで,成績評価者やチームメンバーにも編集結果が見えるようになる。
ただし,pushしたコミットは 取り消しや修正ができなくなる。
なお,コミット1回ごとにpushする必要はなく,複数のコミットを貯めてからpushしてもよい。pushすると,その時点で未送信のコミットがすべて送られる。
[重要] 強制push (push -f
) は 絶対行わないこと。履歴が破壊されて 成績評価者もチームメンバーもそのリポジトリから読み出せなく なり,それ以降実験を継続できなくなる。