ソフトウェア工学
nバージョン管理
• バージョン管理の必要性,diff/patch,分散リポジトリ,gitコ
マンド,gitフロントエンド
玉木徹(名工大)
バージョン管理
バージョン管理とは
n変更履歴を保存すること
• 後から戻すこともあるため
• 機能の履歴を残すため
nバージョン管理しないと
• 直接ファイルを上書き
• 元に戻れない
• コードが動かなくなる
• 以前の記録がなくなる
• 不具合が生じた場合に以前の
バージョンに戻せなくなる
• 並行して機能追加できない
• チーム開発では致命的
ver 1.0
ver 1.1
def myfunc(x, y):
z = 2 * x - y
return z
def myfunc(x, y):
z = 2 * x - y + 1
return z
単純な方法1:ファイル単位
nファイル名で管理
nフォルダに分けて管理
n多数の問題点
• フォルダが古いファイルで汚染される
• ファイルが増える
• どれが最新なのか不明
• 「最新バージョン」の乱立
• 変更履歴が追えない
• 追跡可能性の低下
• 誰が作成したのか不明
• チーム開発ができない
単純な方法2:コメント
nコードをコメントアウトして管理
n多数の問題点
• コードが汚染される
• 最新バージョン以外の不要なコードも
残る
• 通常のコメントと区別がつかない
• 可読性の低下
• いつ誰が変更したのか不明
• チーム開発ができない
diff/patch
以下からzipをダウンロードして展開してください
https://github.com/se-nitech/08_01_diff/archive/refs/heads/main.zip
https://github.com/se-nitech/08_02_patch/archive/refs/heads/main.zip
後で説明するgit cloneでもOKです
diffとpatch:ファイル間の差分
ndiff
• ファイル間の差分を見るコマンド
• 英単語difference(違い;名詞)の略
npatch
• ファイル間の差分を適用するコマンド
• 英単語patch(継ぎ当て;名詞・動詞)
diff
nファイル間の行単位の差
分を抽出する
• コードを並べて見ても,人
間は見落としてしまう
ndocker-compose.yml
version: "3"
services:
myubuntu:
build: ./
volumes:
- ./:/mnt
tty: true
docker-composeの準備
ndockerfile
FROM ubuntu:20.04
RUN apt -y update ¥
&& apt -y install diffutils patch git
WORKDIR /mnt
起動する:
$ cd 08_01_diff/
$ docker-compose build
$ docker-compose up -d
確認する:
$ docker-compose ps
diffの出力
nファイル間の行単位の差分を抽出
ファイルAで
変更された行
diffコマンド
(コンテナで)
実行するコマンド
古いファイルA 新しいファイルB
ファイルBで
対応する行
$ docker compose exec myubuntu diff main_old.py main.py
4c4
< z = 2 * x - y + 1
---
> z = 2 * x - y
$
diffの出力:unified形式(現在の標準)
nファイル間の行単位の差分を抽出
-u:unified形式で出力
+:ファイルBで
追加される行
-:ファイルAから
削除される行
ファイルB
ファイルA
ファイルBで対応す
る開始行,終了行
ファイルAで対応す
る開始行,終了行
各ファイルのタイム
スタンプ
$ docker compose exec myubuntu diff -u main_old.py main.py
--- main_old.py 2022-04-12 02:26:14.433608707 +0000
+++ main.py 2022-04-12 02:26:14.433331280 +0000
@@ -1,7 +1,7 @@
def myfunc(x, y):
- z = 2 * x - y + 1
+ z = 2 * x - y
return z
$
$ docker compose exec myubuntu diff -u main.py main_new.py
--- main.py 2022-04-12 02:26:14.433331280 +0000
+++ main_new.py 2022-04-12 02:26:14.433474365 +0000
@@ -5,14 +5,12 @@
return z
-def myfunc_2(a):
- for i in range(5):
- myfunc(a[i], a[i + 1])
-
def myfunc_3(a):
for i in range(5):
myfunc(a[i], a[i + 1])
+def myfunc_4(a):
+ z = a[1] + a[2]
def main():
a = [1, 2, 3, 4, 5]
$
diffの例
ファイルBで追加
ファイルAから削除
diffファイル
nunified形式のdiffの出力をファイ
ルにしたもの
• 最近のエディタで表示すると分かり
やすく色がつく
n更新の配布方法
• diffファイルを相手に送付
• 相手はdiffファイルで更新
• ただし古いやり方
• 現在はほとんど使われない
ndiff形式での表示はよく使われる
• gitでもGitHubでも
ファイルBで追加
ファイルAから削除
リダイレクトで標準出
力をファイルに保存
拡張子は.diffが一般的
$ docker compose exec myubuntu diff -u main.py main_new.py > main.py.diff
$
patch:diffファイルを用いた更新
nコードを更新する方法
• 新しいものに全体を入れ替える
• ファイルが大量になる
• こちら側が修正中のコード
まで上書きされてしまう
• 変更された部分の差分だけを利
用する
• 相手側で変更されたファイ
ルだけが更新される
• これがdiff/patch
npatchコマンド
• diffファイルを手元のファイル
に適用
• 「パッチを当てる」と言う
diffファイル
更新前のファイル
ndocker-compose.yml
version: "3"
services:
myubuntu:
build: ./
volumes:
- ./:/mnt
tty: true
docker-composeの準備
ndockerfile
FROM ubuntu:20.04
RUN apt -y update ¥
&& apt -y install diffutils patch git
WORKDIR /mnt
起動する:
$ cd 08_02_patch/
$ docker-compose build
$ docker-compose up -d
patch
npatch:diffファイルを手元の
ファイルに適用
• patchに標準入力からdiffファイ
ルを入力する
• diffファイルに従ってコードを更
新する(上書き)
n問題点
• diffにない変更がある場合(コン
フリクト)は手動で調整が必要
• バージョン管理自体はできない
更新後のファイル
リダイレクトで標準入力か
らdiffファイルを入力
$ docker compose exec -T myubuntu patch < main.py.diff
(Stripping trailing CRs from patch; use --binary to disable.)
patching file main.py
$
docker-composeで標
準出力を受け付けるオ
プション
patch (win)
nWindowsの場合
• PowerShellは標準入力に「<」を
使えないので,catでdiffファイル
を表示して,それをパイプ「|」
でコンテナに渡します
• (ちなみにこれはmacでも動作
します)
docker-composeで標
準出力を受け付けるオ
プション
PS C:¥...¥08_02_patch> cat main.py.diff | docker compose exec -T myubuntu patch
(Stripping trailing CRs from patch; use --binary to disable.)
patching file main.py
PS C:¥...¥08_02_patch>
• Git for Windowsをインストールしてgit cloneした場合の
注意点:
• 最初からインストール時に改行コードを「checkout
as-is, commit Unix-style line endings」にしておく
• もしくはインストール後に以下を実行し,git clone
しなおす
• git config --global core.autocrlf input
パイプで標準入力からdiff
ファイルを入力
バージョン管理専用のツール
nConcurrent Versions System (csv) https://www.nongnu.org/cvs/
• 90年代に使われたが現代では廃れた
nsubversion (SVN) http://subversion.apache.org
• 中央管理型.クライアントサーバ
• ある人が編集するとロックがかかり,他の人が編集できない
ngit:近年の業界標準 https://git-scm.com
• 分散管理型
• 複数のリポジトリが別々に管理される
• レクチャーではgitを紹介
nMercurial https://www.mercurial-scm.org
• 分散型
• gitと並んでよく使われてる
gitを使う
gitを自分のPCにインストールしてください
git for macOS
nおすすめ
• Xcodeをインストール
n上級者
• HomebrewでもOK
https://git-scm.com/download/mac
Git for windows
ngit for windowsをインストール
https://gitforwindows.org
Git for Windowsのインストール注意点
VScodeにする(おすすめ)
Git for Windowsのインストール注意点
mainにする
checkout as-is, commit Unix-style line endings
にする(改行コードの問題)
もしくはインストール後に以下を実行
git config --global core.autocrlf input
Sourcetree
ngitのフロントエンド
(GUI)
nmac & win
https://www.sourcetreeapp.com
Vscodeによる開発
Visual Studio Code (vscode)
n統合開発環境
• 各種拡張機能あり
• Dockerコンテナ内
での開発も可能
• ターミナルも完備
nその他のエディタ
• vi / vim
• Emacs
• Eclips
• Sublime Text
https://azure.microsoft.com/ja-jp/products/visual-studio-code/
拡張機能:Git Graph
ngitのフロント
エンドあり
n拡張機能でグ
ラフ表示あり
Git Graph
をインストール
Git Graph
で検索して
拡張機能で
拡張機能:Git Graph
ngitのフロント
エンドあり
n拡張機能でグ
ラフ表示あり
git
Git Graphで
グラフ表示
https://github.com/pytorch/pytorch
拡張機能:Git Graph
ngitのフロント
エンドあり
n拡張機能でグ
ラフ表示あり
git
https://github.com/pytorch/pytorch
推奨の拡張機能
拡張機能から
@recomended
と入力して
これを押すと
このワークスペース
の推奨拡張機能を一
括インストール
これを押すと
このワークスペース
の推奨拡張機能を一
括インストール
日本語化もほしいよね
「再読み込みが必要です」
と出たら,それを押して
vscodeを再起動してください
拡張機能:日本語パック
Dockerもインストール
拡張機能:Docker
拡張機能
で
remote developmentを検索
して
インストー
ル
拡張機能:コンテナへの接続
ここを押すと...
実行中のコンテナに接続する
メニューが表示されるので...
先にdocker composeでコンテナを起動し
ておく
拡張機能によるコンテナへのアタッチ
起動中のコンテナ名を選択して接
続
先にdocker composeでコンテナを起動し
ておく
拡張機能によるコンテナへのアタッチ
新しいウィンドウが開いて
起動中のコンテナに接続
次にコンテナ内のフォルダを選択
コンテナ内のフォルダを開く
次にコンテナ内のフォルダを選択
今の設定では/mntにホストをマウ
ントしているので,これを選択
フォルダを選択したらOKを押す
コンテナ内のフォルダを開く
フォルダ内のmain.cを選ぶとそ
のファイルが表示される
/mntフォルダを表示
コンテナ内のフォルダを開く
コンテナ内にも拡張機能がインストールされて
いることを確認する
こちらはホストPCにインストールした拡張機能
拡張機能:ホストとコンテナは別
起動中のコンテナに接続中
コンテナ内への拡張機能のインストール
拡張機能から
@recomended
と入力して
これを押すと
このワークスペース
の推奨拡張機能を一
括インストール
起動中のコンテナに接続中
これを押すと
このワークスペース
の推奨拡張機能を一
括インストール
アッタチしたVScodeのターミナルを利用しよう
ホスト(コンテナの外)
からdockerコンテナ内の
コマンドを実行
コンテナ内のシェル
でコマンドを実行
「docker compose exec
***」で毎回実行,大変
コマンドがすぐ実行できる!
シェルを追加す
るのはここの+
ここを押して
「リモート接続を終了」を選択
VScodeの接続を切断するだけで,コン
テナは動き続けている
コンテナからのデタッチ
VScodeの更新
歯車マークに「青い1」の
マークが出ていたら更新が必
要!(更新して再起動)
手動で更新する場合は歯車
マークから「更新の確認」
拡張機能の更新
拡張機能タブへ行って
「再読み込みが必要です」が表示されていた
ら,それを押して再読み込みする(他の拡張
機能のインストールがすべて終了してから)
「再読み込みが必要です」のままでは,デ
バッグやコードチェックなどの機能が動作し
ない場合があります インストール中
インストール終了
再読み込み必要
インストール終了
再読み込み必要
gitによるバージョン管理
docker composeを利用する
起動する
$ cd 08_03_git
$ docker compose build
$ docker compose up -d
確認する
$ docker compose ps
停止する
$ docker compose down
これ以降はzipファイルダウンロードではなく,
gitコマンド(git clone)でコードを入手します
$ git clone https://github.com/se-nitech/08_03_git.git
分散リポジトリによる管理
nローカルリポジトリ
• 各自で保存するファイル一式と変更履歴
nリモートリポジトリ
• ローカルリポジトリから更新される
• アップロード:push
• ダウンロード:pull
変更
修正
変更
修正
ローカル
リポジトリ
ローカル
リポジトリ
リモート
リポジトリ
GitHub
GitLab
bitbucket
ローカルディスクでも
リモートリポジトリは可能
ローカルリポジトリによるバージョン管理
nローカルリポジトリを利用
• 履歴を保持
• 変更,修正,追加,削除など
ngitコマンド
• リポジトリを管理する
変更
修正 ローカル
リポジトリ
コンテナで実行する場合: ホストで実行する場合:
macos
win
$ docker compose exec myubuntu git --version
git version 2.25.1
$
$ git --version
git version 2.32.1 (Apple Git-133)
以降ではホストで実行
する手順を説明します
コンテナで実行する場
合の注意点はスライド
の最後で説明 PS C:¥...¥> git --version
git version 2.36.1.windows.1
gitにおける変更の流れ
git add git commit
ステージング コミット
作業ツリー
(ワークツリー)
インデックス
(ステージングエリア)
ローカル
リポジトリ
変更
修正
コーディングや
デバッグを行う
コミット用の
一時保管場所
コミットが
保存される
1つのコミットが
1つの「バージョン」
コミット:コードの更新
nバージョンをグラフで表現する
• コミットするたびにノードが移動
• 主幹ブランチの名前
• mainブランチ
• (masterブランチ:後で説明あり)
• HEAD
• 先頭(最新バージョン)
初期コミット
コミット1
コミット2
HEAD
初期コミット
コミット1
HEAD
初期コミット
HEAD
コミットの例
コミット間のdiff
sourcetreeによる表示
(gitフロントエンド)
コミットの例
コミット間のdiff
sourcetreeによる表示
(gitフロントエンド)
コミットの例
コミット間のdiff
sourcetreeによる表示
(gitフロントエンド)
gitコマンド
(推奨)自分のPCにgitをイントールしてあれば,そのままgitコマンドが使
えます
(注意点あり)インストールしていない場合には,dockerコンテナを利用
してください
設定ファイル:.gitconfig
n必須の設定
• 氏名
• メールアドレス
n場所
• linux, macos:ホームディレクトリ直下
• ~/.gitconfig
• windows:「ユーザー名」は自分のユーザー名
• C:¥ユーザー¥ユーザー名¥.gitconfig
n 設定のコマンド
これは自分のPCのユーザー名です
• 本名,英語
• Firstnameが先,Familynameが後
• 先頭だけ大文字
• すべて半角
• 間に半角の空白
[user]
name = Toru Tamaki
email = tamaki.toru@nitech.ac.jp
$ git config --global user.name "Toru Tamaki"
$ git config --global user.email tamaki.toru@nitech.ac.jp
ローカルなgitconfig
nリポジトリ固有の設定
• ローカルなgitconfigに記述
• ローカルはグローバルに優先する
n場所
• 現在のディレクトリ直下
• ./.git/config
n 設定のコマンド例:
$ git config user.name "Toru TAMAKI (local)"
$ git config user.email tamaki.toru@nitech.ac.jp.local
(base) $ ls -la
total 8
drwxr-xr-x 4 tamaki staff 128 4 17 18:32 .
drwx------ 1050 tamaki staff 33600 4 17 18:31 ..
drwxr-xr-x 12 tamaki staff 384 4 17 18:33 .git
(base) $ ls -la .git
total 40
drwxr-xr-x 12 tamaki staff 384 4 17 18:33 .
drwxr-xr-x 4 tamaki staff 128 4 17 18:32 ..
-rw-r--r-- 1 tamaki staff 7 4 17 18:33 COMMIT_EDITMSG
-rw-r--r-- 1 tamaki staff 21 4 17 18:31 HEAD
-rw-r--r-- 1 tamaki staff 212 4 17 18:33 config
-rw-r--r-- 1 tamaki staff 73 4 17 18:31 description
drwxr-xr-x 15 tamaki staff 480 4 17 18:31 hooks
-rw-r--r-- 1 tamaki staff 145 4 17 18:33 index
drwxr-xr-x 3 tamaki staff 96 4 17 18:31 info
drwxr-xr-x 4 tamaki staff 128 4 17 18:32 logs
drwxr-xr-x 10 tamaki staff 320 4 17 18:33 objects
drwxr-xr-x 4 tamaki staff 128 4 17 18:31 refs
普通は前ページのグローバルな設定を使います
git init:リポジトリの初期化
nゼロからローカルリポジトリを作成する
初期化のコマンド
リポジトリの名前
ここにすべて
の情報が保存
される
現在のフォルダの下にリ
ポジトリ名のフォルダが
作成される
この後はファイルを作成し,git add,git commitを行えばよい
$ git init my_first_proj
Initialized empty Git repository in /.../my_first_proj/.git/
$
$ cd my_first_proj
$
$ ls -la
total 0
drwxr-xr-x 3 tamaki staff 96 6 1 15:53 .
drwxr-xr-x 3 tamaki staff 96 6 1 15:53 ..
drwxr-xr-x 9 tamaki staff 288 6 1 15:53 .git
$
git checkout:リポジトリのコピー
n既存のリポジトリをコピーする
• 特にリモートリポジトリから
リポジトリをコピーし
てくるコマンド リモートリポジトリのURLなど
これが便利!
ネット時代に大活躍!
https://github.com/missing-semester/missing-semester
$ git clone https://github.com/missing-semester/missing-semester.git
Cloning into 'missing-semester'...
remote: Enumerating objects: 2101, done.
remote: Counting objects: 100% (561/561), done.
remote: Compressing objects: 100% (90/90), done.
remote: Total 2101 (delta 484), reused 473 (delta 470), pack-reused 1540
Receiving objects: 100% (2101/2101), 15.52 MiB | 10.32 MiB/s, done.
Resolving deltas: 100% (1260/1260), done.
$
補足:このレクチャーのコード
nGitHubにあります
• cloneしてください
• GitHubについては別の回で説明します https://github.com/se-nitech
補足:このレクチャーのコード
nGitHubにあります
• cloneしてください
• GitHubについては別の回で説明します
n以下のコマンドで今回のコードをcloneできます
n以降は対応するディレクトリに移動して実行してください
• 今回なら
https://github.com/se-nitech
git clone https://github.com/se-nitech/08_03_git.git
cd 08_03_git
補足:このレクチャーのコード
nGitHubにあります
• cloneしてください
• GitHubについては別の回で説明します https://github.com/se-nitech
$ git clone https://github.com/se-nitech/08_03_git.git
Cloning into '08_03_git'...
remote: Enumerating objects: 31, done.
remote: Counting objects: 100% (31/31), done.
remote: Compressing objects: 100% (18/18), done.
remote: Total 31 (delta 10), reused 28 (delta 7), pack-reused 0
Receiving objects: 100% (31/31), done.
Resolving deltas: 100% (10/10), done.
$ cd 08_03_git
$
リポジトリをコピーし
てくるコマンド リモートリポジトリのURLなど
git add, commit:ステージングとコミット
このコミット
の統計情報
ステージングす
るコマンド ステージングする
ファイル名
コミットする
コマンド
-m:コミットに付けるコメント
(なぜ・何を変更したのかが後で分
かるように書くことが重要!)
コミットする
ファイル名
まずmain.pyにな
にか修正を加えて
ください.
$ git add main.py
$ git commit -m "change equation" main.py
[main 53e5c93] change equation
1 file changed, 1 insertion(+)
$
git log:コミット履歴
これまでのコミットの
ログを表示
コミットのコ
メント
コミットのID
(ハッシュ値)
1つのコミット
$ git log
commit 53e5c9376984700c265a561023578b738fec22c6 (HEAD -> main)
Author: Toru Tamaki <tamaki.toru@nitech.ac.jp>
Date: Wed Jun 1 16:13:17 2022 +0900
change equation
commit b0b1924365f2ebf6f7871779ace0853c9ed9d3f7 (origin/main, origin/HEAD)
Author: Toru Tamaki <tamaki.toru@nitech.ac.jp>
Date: Thu May 26 15:30:25 2022 +0900
fix workdir pagerの設定がlessになっている場合,
lessを終了するなら"q"
git status:作業ディレクトリの状態
作業ツリーとインデック
スの状態を表示
作業ツリー
で変更され
ているファ
イル
インデック
スにファイ
ルはない
インデック
スにある
ファイル
ステージング
すると
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working direc
modified: main.py
no changes added to commit (use "git add" and/or "git commit -a")
$
$ git add main.py
$ git status
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: main.py
$
git diff:コミット間差分
差分を見るコマンド 差分を取る2つのコミットID
コミットIDを指定しないと,
作業ツリーとインデックスの
差分を表示
$ git diff eb88fd18 8b4c7528e
diff --git a/main.py b/main.py
index 1790121..6a41df2 100644
--- a/main.py
+++ b/main.py
@@ -15,7 +15,7 @@ def myfunc_4(a):
def main():
a = [1, 2, 3, 4, 5]
for _ in range(100):
- myfunc_2(a)
+ myfunc_4(a)
for _ in range(300):
myfunc_3(a)
$ git diff
diff --git a/main.py b/main.py
index 3e3af03..2f991d6 100644
--- a/main.py
+++ b/main.py
@@ -1,7 +1,7 @@
def myfunc(x, y):
- z = 2 * x - y + 1
+ z = 2 * x - y + 2
return z
git mv, git rm:ファイルの操作
nファイルの操作はgitコマンドを使う
• それまでの履歴が失われてしまう
• 通常のmv, rmは使わずgit rm, git mvを使おう
$ mv main.py main2.py
$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working
directory)
deleted: main.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
main2.py
no changes added to commit (use "git add" and/or "git commit -a")
$ git mv main.py main2.py
$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
renamed: main.py -> main2.py
通常のmv:git履歴が失われる git mv:git履歴が残る!
削除されている
新しいファイル
ができている
rename扱い!
git mv, git rm:ファイルの操作
nファイルの操作はgitコマンドを使う
• それまでの履歴が失われてしまう
• 通常のmv, rmは使わずgit rm, git mvを使おう
通常のrm:単に削除 git rm:削除してadd済み
$ rm main.py
$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be
committed)
(use "git restore <file>..." to discard changes in
working directory)
deleted: main.py
$ git rm main.py
rm 'main.py'
$ git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: main.py
削除されている
削除されてadd済みな
のでcommit可能
gitの注意点
バージョン管理する対象
n対象:テキストファイル
• コード
• *.py, *.cpp
• 設定ファイル
• dockerfile
• docker-compose.yml
• ドキュメント
• README.md
n対象外
• バイナリファイル,データ
• 実行形式ファイル
• 画像ファイル
• 音声ファイル
• etc
• 管理する必要のないファイル
• .vscodeなどエディタ設定
• 中間ファイル
• __pycache__
• *.pyc
• 一時ファイル
• .coverageなど(次回)
管理外ファイルの設定
nファイル「.gitignore」
• これに書いたファイルはgit管理か
ら除外される
• 指定内容
• ファイル名
• フォルダ名
• そのフォルダ以下すべて無
視
• ワイルドカード*
• *の部分にマッチするファイ
ル
n例
__pycache__/
.vscode/
*.pyc
htmlcov/
.coverage
coverage.xml
n参考
• [Git] .gitignoreの仕様詳解
• gitignoreの書き方チートシート【テ
ンプレあり】
• https://github.com/github/gitignore
ブランチ
コミット:コードの更新
nバージョンをグラフで表現する
• コミットするたびにノードが移動
• 主幹ブランチの名前
• mainブランチ
• (古いリポジトリはmasterブラン
チの場合もある)
• HEAD
• 先頭(最新バージョン)
初期コミット
コミット1
コミット2
HEAD
初期コミット
コミット1
HEAD
初期コミット
HEAD
現在はmainが主流.masterは使わないようにする.
・現在のブランチ名を変更するには
git branch -M main
・今後すべての新規のデフォルトを変更するなら
git config --global init.defaultBranch main
• Twitter、コードやドキュメント内の用語「Whitelist /
Blacklist」 「Master / Slave」 「Dummy value」などを
好ましい用語へ置き換え、具体例も発表, 2020/7/6
Publickey
• GitHub、これから作成するリポジトリのデフォルトブラ
ンチ名が「main」に。「master」から「main」へ変更,
2020/10/15, Publickey
ブランチ:並行開発
n異なる履歴を表現したい
• ブランチ(branch,枝)を作る
• 「ブランチを切る」という
n用途
• 異なる機能などを並行で開発
• メインの開発は継続しながらバグフィックス
• 安定版の開発を継続しながら追加機能を実装
nブランチの操作
• 作業ツリーを切り替える
• mainで作業
• bugfixで作業
• HEAD
• 現在のブランチの先頭
bugfix
HEAD main
ブランチの作成と切り替え
HEAD main
git branch
ブランチを表示
(*は現在のブランチ)
ブランチ名がmasterだったら変更
・git branch -M main
$ git branch
* main
$ git branch bugfix
$ git branch
bugfix
* main
$ git checkout bugfix
Switched to branch 'bugfix'
$ git branch
* bugfix
main
$
pagerの設定がlessになっている場合
(mac/linux)
lessを終了するなら"q"
ブランチの作成と切り替え
HEAD main bugfix
git branch ブランチ名
新規ブランチを作成
まだmainのまま
$ git branch
* main
$ git branch bugfix
$ git branch
bugfix
* main
$ git checkout bugfix
Switched to branch 'bugfix'
$ git branch
* bugfix
main
$
ブランチの作成と切り替え
HEAD
main bugfix
git checkout ブランチ名
ブランチを切り替え
bugfixブランチに
切り替わった
$ git branch
* main
$ git branch bugfix
$ git branch
bugfix
* main
$ git checkout bugfix
Switched to branch 'bugfix'
$ git branch
* bugfix
main
$
ブランチのマージ
n2つのブランチを統合
n用途
• バグフィックスをメインに反映
• 追加機能を安定版に反映
nマージの方法
• HEADのあるブランチで
• git merge マージするブランチ名
nもしコンフリクトが発生したら
• 例:mainとbugfixで同じ部分を変更していたら
• 手動で修正
bugfix
HEAD main
ブランチの使い方
nbugfixブランチ
• メインの開発は継続しながらバグフィッ
クス
• メインを直接修正してしまうと,修
正に失敗していたら困る
• バグフィックスをメインに反映
• 修正が確実に機能することを確認し
てからマージ
nチーム開発体制の例
• mainブランチのメンテナンスチーム
• bugfixブランチの開発チーム
main
ver 1.1
不具合
調査開始
main
ver 1.0
修正!
bugfix
ブランチ
ブランチの使い方
nfeatureブランチ
• 安定版の開発を継続しながら追加機能を
実装
• 追加機能が完成したら安定版に反映
nチーム開発体制の例
• mainブランチのメンテナンスチーム
• featureブランチの開発チーム
main
ver 2.0
新機能
開発
main
ver 1.0
完成!
feature
ブランチ
実際のブランチ・マージの例 https://github.com/pytorch/pytorch
diff
ブランチ
のマージ
詳細なコミッ
トコメント
リモートリポジ
トリのブランチ
一行コミット
コメント
detached HEAD
n作業ツリーを途中のコミットに
戻したい
• 過去のコミットからブランチを切
りたい場合など
n方法
• そのコミットをcheckoutする
• git checkout コミットID
• するとdetached HEADになる
• 過去にいる現在位置
• mainブランチの最新に戻るには
• git checkout main
bugfix
HEAD main
detached
HEAD
分散リポジトリによる管理
nローカルリポジトリ
• 各自で保存するファイル一式と変更履歴
nリモートリポジトリ
• ローカルリポジトリから更新される
• アップロード:push
• ダウンロード:pull
変更
修正
変更
修正
ローカル
リポジトリ
ローカル
リポジトリ
リモート
リポジトリ
GitHub
GitLab
bitbucket
分散リポジトリによる開発と配布
変更
修正
変更
修正
ローカル
リポジトリ
ローカル
リポジトリ
リモート
リポジトリ
push
pull
(fetch + merge)
push
pull
(fetch +
merge)
開発者A
開発者B
c
h
e
c
k
o
u
t
世界中の
ユーザー
開発者Bの変更を
マージ
開発者Aの変更を
マージ
コンテナ内でgitを使う注意点
.gitconfigの扱い
nホストの場合
• linux, macos:ホームディレクトリ直下
• ~/.gitconfig
• windows:「ユーザー名」は自分のユーザー名
• C:¥ユーザー¥ユーザー名¥.gitconfig
nコンテナの場合
• コンテナ内に.gitconfigが必要
• ユーザーがrootなので/root/.gitconfigが必要
• 方法は2つ
• コンテナ内で作成:毎回作成するので面倒
• ホストの.gitconfigをコピー:ちょっと手間,でも
• ホストとコンテナで同じものが使えるので便利
• VScodeのターミナルを利用するのが楽
.gitconfigをホストからコンテナへコピー:1
ndocker cpコマンド
• docker cp ホストファイル名 コンテナ名:コピー先
• docker compose cp ホストファイル名 サービス名:コピー先
コピーしないとrootユーザー
の.gitconfigは存在しない
いちいち手動でコピー
$ docker compose up -d
[+] Running 1/0
✔ Container 08_03_git-myubuntu-1 Run...
$ docker compose exec myubuntu ls -la /root
total 16
drwx------ 2 root root 4096 Apr 12 02:06 .
drwxr-xr-x 1 root root 4096 May 2 00:24 ..
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
$
.gitconfigをホストからコンテナへコピー:1
ndocker cpコマンド
• docker cp ホストファイル名 コンテナ名:コピー先
• docker compose cp ホストファイル名 サービス名:コピー先
rootユーザーの.gitconfigとし
てコピーされた.これが使
われる
いちいち手動でコピー
$ docker compose up -d
[+] Running 1/0
✔ Container 08_03_git-myubuntu-1 Run...
$ docker cp ~/.gitconfig 08_03_git-myubuntu-1:/root/
$ docker compose exec myubuntu ls -la /root
total 16
drwx------ 2 root root 4096 Apr 12 02:06 .
drwxr-xr-x 1 root root 4096 May 2 00:24 ..
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
-rw-r--r-- 1 501 dialout 90 Apr 17 09:33 .gitconfig
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
$
mac/linux
PS C:¥...¥08_03_git> docker compose up -d
[+] Running 2/2
✔ Network 08_03_git_default Created
✔ Container 08_03_git-myubuntu-1 Started
PS C:¥...¥08_03_git> docker cp C:¥Users¥*****¥.gitconfig 08_03_git-myubuntu-1:/root/
Successfully copied 2.05kB to 08_03_git-myubuntu-1:/root/
PS C:¥...¥08_03_git> docker compose exec myubuntu ls -la /root
total 20
drwx------ 1 root root 4096 May 2 00:39 .
drwxr-xr-x 1 root root 4096 May 2 00:39 ..
-rw-r--r-- 1 root root 3106 Dec 5 2019 .bashrc
-rwxr-xr-x 1 root root 104 Feb 14 07:23 .gitconfig
-rw-r--r-- 1 root root 161 Dec 5 2019 .profile
PS C:¥...¥08_03_git>
.gitconfigをホストからコンテナへコピー:1
ndocker cpコマンド
• docker cp ホストファイル名 コンテナ名:コピー先
• docker compose cp ホストファイル名 サービス名:コピー先
rootユーザーの.gitconfigとし
てコピーされた.これが使
われる
いちいち手動でコピー
win
.gitconfigをホストからコンテナへコピー:2
nvscodeでコンテナへアタッチ(win/mac両方)
• 自動でホストの.gitconfigがコンテナにコピーされる
コンテナ接続時に.gitconfig
がコピーされているのが分
かる
show lowを押すとコンテナ
接続のログが表示される
自動でコピー
おすすめ
.gitconfigをホストからコンテナへコピー:2
nvscodeでコンテナへアタッチ(win/mac両方)
• 自動でホストの.gitconfigがコンテナにコピーされる
+を押せばコンテナのシェル
が新しいターミナルとして
開く(ここで作業すれば
OK)
コンテナ内でも.gitconfigが有効な
ことが分かる
自動でコピー
おすすめ
.gitconfigをホストからコンテナへコピー:2
nvscodeでコンテナへアタッチ(win/mac両方)
• 自動でホストの.gitconfigがコンテナにコピーされる
自動でコピー
おすすめ
もしできなければ設定で
Copy Git Configに
✓をいれる
課題
ndiffとpatchを使う
• なにかのファイルAを用意して,それをコピーして書き換えてファイルBを作
る
• AとBのdiffファイルを作り,それをAにpatchで適用してファイルCを作る
• BとCが一致していることを確認する
ngitを使う
• リポジトリを初期化する
• なにかファイルを作成し,addとcommitを行う
• 以下を数回反復する
• そのファイルを修正し,addとコミットを行う
• コミットログを見る
• 新しいブランチを作成し,そこにコミットする
想定試験問題
nバージョン管理とは何か,その重要性を説明せよ
ndiffとpatchは何をするコマンドかを具体例で説明せよ
ngitのコマンドの意味と使い方を説明せよ
• init, checkout, add, commit, log, status
nファイル.gitignoreの役割を説明せよ
ngitにおけるブランチの役割と,作成の仕方を説明せよ

ソフトウェア工学2023 07 バージョン管理