【Linux】【Git】【book】「入門git」の学習記録【SW】

下記の「入門git」(Travis Swicegood著) を使った学習記録のページです。

入門git

入門git


第I部 分散管理の世界へようこそ

第1章 Git流バージョン管理入門
 1.1 リポジトリ
 1.2 何を格納する?
 1.3 作業ツリー
 1.4 ファイルの操作と同期の維持
 1.5 プロジェクト、ディレクトリ、ファイルの追跡
 1.6 タグでマイルストーンを追跡する
 1.7 ブランチで別の履歴を作る
 1.8 マージ
 1.9 ロックの種類
 1.10 次のステップ

第2章 Gitのセットアップ
 2.1 Gitのインストール
 2.2 Gitの設定
 2.3 GitのGUIを使う
 2.4 Gitに組み込まれたヘルプにアクセスする

第3章 最初のプロジェクトを作る
 3.1 リポジトリの作成
   3.1.txt
 3.2 変更を加える
   3.2.txt
 3.3 プロジェクトの作業を開始する
   3.3.txt
 3.4 ブランチを使って理解する
   3.4.txt
 3.5 リリースのハンドリング
   3.5.txt
 3.6 リモートリポジトリのクローンを作る

第II部 日々のGit

第4章 追加とコミット:Gitの基本
 4.1 ファイルの追加
   4.1.txt
 4.2 変更のコミット
   4.2.txt
 4.3 変化したものを見る
   4.3.txt
 4.4 ファイルの管理
   4.4.txt

第5章 ブランチを理解して使う
 5.1 ブランチとは?
   5.1.txt
 5.2 新しいブランチを作る
   5.2.txt
 5.3 ブランチ間での変更のマージ
   5.3.txt
 5.4 競合に対処する
   5.4.txt
 5.5 ブランチを削除する
 5.6 ブランチの名前を変える

第6章 Gitの履歴を使った作業
 6.1 Gitのログを調べる
 6.2 リビジョンの範囲を指定する
   6.2.txt
 6.3 バージョン間の差分を見る
   6.3.txt
 6.4 誰のしわざか
   6.4.txt
 6.5 コンテンツを追跡する
 6.6 変更をなかったことにする
   6.6.txt
 6.7 履歴を書き換える

第7章 リモートリポジトリを使った作業
 7.1 ネットワークプロトコル
 7.2 リモートリポジトリのクローンを作る
 7.3 最新の状態に保つ
   7.3.txt
 7.4 変更をプッシュする
 7.5 新しいリモートリポジトリを追加する

第8章 リポジトリを整理する
 8.1 タグでマイルストーンに印を付ける
 8.2 リリースブランチを使う
 8.3 タグとブランチに使える有効な名前
 8.4 複数のプロジェクトを追跡する
 8.5 外部のリポジトリを追跡するのにGitのサブモジュールを使う

第9章 基礎を越えて
 9.1 リポジトリの履歴を圧縮する
 9.2 自分のリポジトリをエクスポートする
 9.3 ブランチのリベース
 9.4 参照ログを使う
 9.5 リポジトリを二等分する

第III部 管理

第10章 Gitへの移行
 10.1 Subversionとやり取りする
 10.2 git-svnが利用できるか確認する
 10.3 Subversionリポジトリをインポートする
 10.4 Subversionリポジトリに追随する
 10.5 Subversionに変更をプッシュする
 10.6 CVSからのインポート

第11章 GitosisでGitサーバを動かす
 11.1 依存関係に問題がないか確かめる
 11.2 Gitosisのインストール
 11.3 管理者の証明書を作成する
 11.4 サーバにGitosisのための設定をする
 11.5 Gitosisを初期化する
 11.6 Gitosisを設定する
 11.7 新しいリポジトリを追加する
 11.8 公開リポジトリを設定する
 11.9 おわりに

第IV部 付録
付録A Gitコマンドリファレンス

 A.1 設定と初期化
 A.2 日常の作業
 A.3 ブランチ
 A.4 履歴
 A.5 リモートリポジトリ
 A.6 GitとSubversionの橋渡し
 B.1 Gitに付随しているツール
 B.2 サードパーティ製のツール
 B.3 Gitリポジトリのホスティング
 B.4 オンラインの情報源

 
 
 

3.1

 

3.1.txt

空っぽのリポジトリを作る。

% mkdir mysite
% cd mysite/
% git init
Initialized empty Git repository in /home/neko/work/PragmaticVersionControlUsingGit/3.1/mysite/.git/

 
 

3.2

 

3.2.txt

次の変更を加える。

  • 空っぽのリポジトリに index.html ファイルを作る
  • 「Hello World」という見出し(h1)を追加する。
% vim index.html 
<html>
    <body>
        <h1>Hello World!</h1>
    </body>
</html>
% git status
ブランチ master

No commits yet

追跡されていないファイル:
  (use "git add <file>..." to include in what will be committed)

	index.html

nothing added to commit but untracked files present (use "git add" to track)
% git add index.html
% git commit -m "add in hello world HTML"
[master (root-commit) fde7439] add in hello world HTML
 1 file changed, 5 insertions(+)
 create mode 100644 index.html

 
 

3.3

 

3.3.txt

HTML に要素を追加する。

  • , を追加する。
  • git add により変更をステージする
% git diff 
diff --git a/index.html b/index.html
index 998d815..a4732d8 100644
--- a/index.html
+++ b/index.html
@@ -1,4 +1,7 @@
 <html>
+    <head>
+        <title>Hello World in Git</title>
+    </head>
     <body>
         <h1>Hello World!</h1>
     </body>
% git status
ブランチ master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")

 
ステージする

% git add index.html
% git status
ブランチ master
コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html

 
コミットする

% git commit -m 'add <head> and <title> to index' \
                            -m 'This allows for more sementic document.'
[master 785a336] add <head> and <title> to index
 1 file changed, 3 insertions(+)
% git log -1
commit 785a336a78f6072310c2dd0df96c45445d29dbe5 (HEAD -> master)
Author: Neko <neko@example.com>
Date:   Sat Jun 30 06:00:22 2018 +0900

    add <head> and <title> to index
    
    This allows for more sementic document.

 
 

3.4

 

3.4.txt

master からブランチ 1.0 (RB_1.0)を作る

% git branch RB_1.0 master
% git branch
  RB_1.0
* master

 
index.html を編集する

% git diff
diff --git a/index.html b/index.html
index a4732d8..8479212 100644
--- a/index.html
+++ b/index.html
@@ -5,4 +5,7 @@
     <body>
         <h1>Hello World!</h1>
     </body>
+    <ul>
+        <li><a href="bio.html">BIography</a></li>
+    </ul>
 </html>

 

% git status
ブランチ master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   index.html

no changes added to commit (use "git add" and/or "git commit -a")

 
git commit -a により、git add と git commit を同時に行う

% git commit -a

% git status
ブランチ master
nothing to commit, working tree clean

 
ブランチ 1.0 (RB_1.0)を切り替えて、ファイル index.html を編集し、コミットする。

% git branch -a
  RB_1.0
* master
~/w/P/mysite (master) ><> git checkout RB_1.0
Switched to branch 'RB_1.0'
% git diff
diff --git a/index.html b/index.html
index a4732d8..047c26a 100644
--- a/index.html
+++ b/index.html
@@ -1,6 +1,7 @@
 <html>
     <head>
         <title>Hello World in Git</title>
+        <meta name="description" content="hello world in Git" />
     </head>
     <body>
         <h1>Hello World!</h1>
% git commit -a -m 'Add in a description element to the metadata'
[RB_1.0 272c9d5] Add in a description element to the metadata
 1 file changed, 1 insertion(+)

 
 

3.5

 

3.5.txt

次の処理をする。

  • リリースブランチ 1.0 (RB_1.0) にタグ 1.0 を付与する。
  • リリースブランチ 1.0 (RB_1.0)の内容を master にマージする。
  • 不要になったリリースブランチ(RB_1.0)を破棄する。
  • RB_1.0 をマージした master から タグ1.0 を指定してリリース物を作成する

 

バージョン1.0 (RB_1.0)にタグを付与する。

% git tag 1.0 RB_1.0
% git tag
1.0

 
現在のブランチは以下である。
f:id:dnkrnka:20180630065417p:plain

これを以下のように取り込みたい。
f:id:dnkrnka:20180630070118p:plain
 
RB_1.0 の内容を master へ取り込む。

% git checkout master
Switched to branch 'master'

% git branch
  RB_1.0
* master
% git rebase RB_1.0 
First, rewinding head to replay your work on top of it...
Applying: add in a bio link

取り込めたことを確認する

~% git log --oneline --graph
* 32a2d7e add in a bio link
* 272c9d5 Add in a description element to the metadata
* 785a336 add <head> and <title> to index
* fde7439 add in hello world HTML

 
御役御免になったリリースブランチ 1.0 (RB_1.0) を破棄する。

% git branch
  RB_1.0
* master

% git branch -d RB_1.0
Deleted branch RB_1.0 (was 272c9d5).

% git branch
* master

 
もしも RB_1.0 の内容が必要になったら、タグを指定してブランチを作成すれば良い。

% git branch RB_1.0.1 1.0

% git branch RB_1.0.1 1.0
~/w/P/mysite (master) ><> git branch
RB_1.0.1

master

% git checkout RB_1.0.1
Switched to branch 'RB_1.0.1'

% git branch

RB_1.0.1

master
|

 

RB_1.0 をマージした master から タグ1.0 を指定してリリース物を作成する。
単にコピーする場合と異なり, .git ディレクトリが存在しなくなる。

% git archive --format=tar --prefix=mysite-1.0/ 1.0 | gzip > mysite-1.0.tar.gz

 
 

4.1

 

4.1.txt

パッチモードでステージする。(その後、コミットする)

  • git add に「-p」オプションを付与すればパッチモードとなる。
% git add -p
diff --git a/index.html b/index.html
index 922330d..c9412a1 100644
--- a/index.html
+++ b/index.html
@@ -7,6 +7,6 @@
         <h1>Hello World!</h1>
     </body>
     <ul>
-        <li><a href="bio.html">BIography</a></li>
+        <li><a href="about.html">About</a></li>
     </ul>
 </html>
Stage this hunk [y,n,q,a,d,e,?]? y

 

% git status
ブランチ master
コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

	modified:   index.html
% git commit -m 'changed BIography to About'

 
 

4.2

 

4.2.txt

変更のコミット。

  • git commit を使う。
  • ログの編集に使うエディタを指定する。

エディタは以下の順で起動する。

1. $GIT_EDITOR
2. core.editor  # Git の設定値
3. $VISUAL
4. $VEDITOR
5. 設定がなければ、vi を起動する

 
上記 2 の core.editor は下記の vim 定義行のことである。

[user]
	email = neko@example.com
	name = Neko
[color]
	ui = auto
[core]
	editor = vim -c \"set fenc=utf-8\"
[commit]
	template = /home/neko/.gitmesg.tmpl

 
 

4.3

 

4.3.txt

差分を見る。

比較対象が異なると、git diff のオプションも異なる。

比較対象 コマンド
WorkTree vs StashArea git diff
StashArea vs Repository git diff --cached あるいは git diff --staged
WorkTree vs Repository git diff HEAD^ あるいは git diff HEAD^..HEAD

f:id:dnkrnka:20180630080231p:plain


 

% git diff HEAD^ 
diff --git a/index.html b/index.html
index 922330d..c9412a1 100644
--- a/index.html
+++ b/index.html
@@ -7,6 +7,6 @@
         <h1>Hello World!</h1>
     </body>
     <ul>
-        <li><a href="bio.html">BIography</a></li>
+        <li><a href="about.html">About</a></li>
     </ul>
 </html>

 
 

4.4

 

4.4.txt

ファイル名の変更。

  • git mv を使う。
% git mv index.html hello.html
% git commit -m 'git mv index.html hello.html'
[master 49c53a5] git mv index.html hello.html
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename index.html => hello.html (100%)


無視するファイルを設定には下記ファイルを作成し、リポジトリにコミットすれば良い。

  • .gitignore に書く (全体で共通の設定を書くと良い)
  • .git/info/exclude に定義する (個別で無視するファイルを書くと良い)

/tmp/.gitkeepだけは例外として、tmpディレクトリの中身を全て無視する。

.gitignore

/tmp/*
!/tmp/.gitkeep
https://qiita.com/anqooqie/items/110957797b3d5280c44f

.git/info/exclude

# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.*.swp
.*~

 
 

5.1

 

5.1.txt

master ブランチの名称を変更する。

% git branch 
* master

git branch -m を実行する。

% git branch -m master mymaster
% git branch
* mymaster

元に戻すことも可能である。

% git branch -m mymaster master
% git branch 
* master

 
 

5.2

 

5.2.txt

ブランチを作成する。

  • git checkout -b を使って git branch alternate ; git checkout alternate を同時に実行する
% git checkout -b alternate master
Switched to a new branch 'alternate'
% git branch
* alternate
  master

 
 

5.3

 

5.3.txt

以下の操作をする。

  • 直接マージ
    • alternate ブランチに空っぽの about.html を追加登録する。
    • master ブランチに対して alternate ブランチの内容をマージする(コミットする)。

f:id:dnkrnka:20180630093841p:plain
 
alternate ブランチに切り替える。

% git branch
* alternate
  master

 
空っぽの about.html を作り、git add → git commit する。

%  touch about.html
% git add about.html
% git status
ブランチ alternate
コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

	new file:   about.html
% git commit -m 'add the skeleton of an about page'
[alternate 7d94ef8] add the skeleton of an about page
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 about.html
% git log --pretty=oneline --graph
* 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (HEAD -> alternate) add the skeleton of an about page
* 49c53a5155af00458bc859da3143820b676a82d3 (master) git mv index.html hello.html
* 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
* 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
* 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
* 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
* fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

 
alternate から master にマージする

% git checkout master
Switched to branch 'master'
% git merge alternate 
Updating 49c53a5..7d94ef8
Fast-forward
 about.html | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 about.html
% git log --pretty=oneline --graph
* 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (HEAD -> master, alternate) add the skeleton of an about page
* 49c53a5155af00458bc859da3143820b676a82d3 git mv index.html hello.html
* 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
* 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
* 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
* 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
* fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

以下の操作をする。

  • 圧縮コミット
    • master ブランチに対して contact ブランチの内容をマージする(コミットする)。
    • git merge --squash contact するだけ

f:id:dnkrnka:20180630093728p:plain
 
contact ブランチを作成する

% git checkout -b contact master
Switched to a new branch 'contact'

 
contact.html を作成して編集し、コミットする。

% vim contact.html 
<html>
    <body>
        <h1>My Name is NekoChan</h1>
    </body>
</html>

% git add contact.html

% git commit -m 'add contact file with Name'
[contact 2ea356d] add contact file with Name
 1 file changed, 5 insertions(+)
 create mode 100644 contact.html

 

さらに contact.html 編集してコミットする。

% git diff
diff --git a/contact.html b/contact.html
index 997f0eb..efc6975 100644
--- a/contact.html
+++ b/contact.html
@@ -1,5 +1,6 @@
 <html>
     <body>
         <h1>My Name is NekoChan</h1>
+        <h1>Tel: 090-1234-5678</h1>
     </body>
 </html>

% git add contact.html

% git commit -m 'add contact file with Tel'
[contact d8bb157] add contact file with Tel
 1 file changed, 1 insertion(+)

この時点ではコミットが2つに分かれている。

    % git log --pretty=oneline --graph
★ * d8bb157952da27581669fff760ad6224faf5628f (HEAD -> contact) add contact file with Tel
★ * 2ea356d780d0e6f7ceaec3cd160507a9308df2cb add contact file with Name
  * 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (master, alternate) add the skeleton of an about page
  * 49c53a5155af00458bc859da3143820b676a82d3 git mv index.html hello.html
  * 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
  * 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
  * 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
  * 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
  * fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

 

contact → master へマージする。

% git checkout master

圧縮マージをする。

% git merge --squash
fatal: No remote for the current branch.

% git merge --squash contact
Updating 7d94ef8..d8bb157
Fast-forward
Squash commit -- not updating HEAD
 contact.html | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 contact.html

直接マージとは違い、この時点ではコミットされていない。

% git status
ブランチ master
コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

	new file:   contact.html

コミットする。

% git commit -m 'add contact file with Name and Tel'
[master 8869bea] add contact file with Name and Tel
 1 file changed, 6 insertions(+)
 create mode 100644 contact.html

コミットが 1つにまとめられた。(Name と Tel が 1まとめになった)

    % git log --pretty=oneline --graph
★  * 8869beadc153eabcfbaa11df5ac0b2504a356f2a (HEAD -> master) add contact file with Name and Tel
    * 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (alternate) add the skeleton of an about page
    * 49c53a5155af00458bc859da3143820b676a82d3 git mv index.html hello.html
    * 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
    * 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
    * 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
    * 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
    * fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

チェリーピック。
コミットの1つだけを取り出して、別ブランチにマージする方法である。
 

contact ブランチに移って、さらに変更を追加コミットする。

% git branch
  alternate
* contact
  master

% git diff 
diff --git a/contact.html b/contact.html
index efc6975..9b6e337 100644
--- a/contact.html
+++ b/contact.html
@@ -2,5 +2,6 @@
     <body>
         <h1>My Name is NekoChan</h1>
         <h1>Tel: 090-1234-5678</h1>
+        <h1>Type: Hachiware</h1>
     </body>
 </html>

% git add .

% git commit -m 'add contact file with Type'
[contact 88f5199] add contact file with Type
 1 file changed, 1 insertion(+)

 
最後の変更のコミットID を取得する。

% git log -1
commit 88f51993f8f6f162242349d12aee9a2a58d3f4a2 (HEAD -> contact)
Author: Neko <neko@example.com>
Date:   Sat Jun 30 09:57:31 2018 +0900

    add contact file with Type

 
contac ブランチから master ブランチへチェリーピックをする。
git cherry-pick を実行すると、コミットまで行われる。

% git checkout master

% git branch
  alternate
  contact
* master

% git cherry-pick 88f5199
[master 0cbba49] add contact file with Type
 Date: Sat Jun 30 09:57:31 2018 +0900
 1 file changed, 1 insertion(+)

チェリーピックで複数個をマージする。

  • -n オプションを使って、マージまで行うもののコミットはしないように指示する。


これまでのコミット記録を見る。

% git branch
  alternate
  contact
* master
    % git log --pretty=oneline --graph
☆  * 0cbba49830a091c231ece77c9e15542fce40a26a (HEAD -> master) add contact file with Type
☆  * 8869beadc153eabcfbaa11df5ac0b2504a356f2a add contact file with Name and Tel
★  * 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (alternate) add the skeleton of an about page
    * 49c53a5155af00458bc859da3143820b676a82d3 git mv index.html hello.html
    * 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
    * 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
    * 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
    * 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
    * fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

★ の時点まで巻き戻す。☆を削除する。

% git reset --hard HEAD^^
    % git log --pretty=oneline --graph
    * 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (alternate) add the skeleton of an about page
    * 49c53a5155af00458bc859da3143820b676a82d3 (HEAD -> master) git mv index.html hello.html
    * 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
    * 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
    * 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
    * 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
    * fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

 
contact ブランチに戻り、Commit ログを確認する。

% git checkout contact

下記行頭「#」の2つをチェリーピックする。
CommitID が長いので、ショート版で表示する。

    % git log --oneline  
☆   88f5199 (HEAD -> contact) add contact file with Type
    d8bb157 add contact file with Tel
☆   2ea356d add contact file with Name
    7d94ef8 (alternate) add the skeleton of an about page
    49c53a5 (master) git mv index.html hello.html
    5fbe9b0 changed BIography to About
    32a2d7e add in a bio link
    272c9d5 (tag: 1.0) Add in a description element to the metadata
    785a336 add <head> and <title> to index
    fde7439 add in hello world HTML

contact → master へマージする。このとき、古い順にマージすること。

% git checkout master
% git cherry-pick -n 2ea356d
% git cherry-pick -n 88f5199
% git cherry-pick -n 88f5199
error: 88f5199を適用できませんでした... add contact file with Type
ヒント: after resolving the conflicts, mark the corrected paths
ヒント: with 'git add <paths>' or 'git rm <paths>'

チェリーピックで複数個をマージする。

  • -n オプションを使って、マージまで行うもののコミットはしないように指示する。


これまでのコミット記録を見る。

% git branch
  alternate
  contact
* master
    % git log --pretty=oneline --graph
☆  * 0cbba49830a091c231ece77c9e15542fce40a26a (HEAD -> master) add contact file with Type
☆  * 8869beadc153eabcfbaa11df5ac0b2504a356f2a add contact file with Name and Tel
☆  * 7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (alternate) add the skeleton of an about page
★  * 49c53a5155af00458bc859da3143820b676a82d3 git mv index.html hello.html
    * 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
    * 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
    * 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
    * 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
    * fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

★ の時点まで巻き戻す

% git reset --hard HEAD^^^
    % git log --pretty=oneline --graph
    * 49c53a5155af00458bc859da3143820b676a82d3 (HEAD -> master) git mv index.html hello.html
    * 5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
    * 32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
    * 272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
    * 785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
    * fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

 
contact ブランチに戻り、Commit ログを確認する。

% git checkout contact

下記行頭「#」の2つをチェリーピックする。

    % git log --pretty=oneline 
☆   88f51993f8f6f162242349d12aee9a2a58d3f4a2 (HEAD -> contact) add contact file with Type
    d8bb157952da27581669fff760ad6224faf5628f add contact file with Tel
☆   2ea356d780d0e6f7ceaec3cd160507a9308df2cb add contact file with Name
    7d94ef878fefe1a5fed09b3808e414cc589ad1f1 (alternate) add the skeleton of an about page
    49c53a5155af00458bc859da3143820b676a82d3 (master) git mv index.html hello.html
    5fbe9b056aeda943fb9200318f878b4e12e180d6 changed BIography to About
    32a2d7e1085d2ef30406da4b1567762500afa0cc add in a bio link
    272c9d5f531cf20cfca6180f5fd9dd4433bbab3e (tag: 1.0) Add in a description element to the metadata
    785a336a78f6072310c2dd0df96c45445d29dbe5 add <head> and <title> to index
    fde7439d82e08046731b780c48c8beffacaaa430 add in hello world HTML

CommitID が長いので、ショート版で表示する。

    % git log --oneline  
☆  88f5199 (HEAD -> contact) add contact file with Type
    d8bb157 add contact file with Tel
☆  2ea356d add contact file with Name
    7d94ef8 (alternate) add the skeleton of an about page
    49c53a5 (master) git mv index.html hello.html
    5fbe9b0 changed BIography to About
    32a2d7e add in a bio link
    272c9d5 (tag: 1.0) Add in a description element to the metadata
    785a336 add <head> and <title> to index
    fde7439 add in hello world HTML

 
contact → master へマージする。このとき、古い順にマージする。
まずは 2ea356d をチェリーピックする。

% git checkout master

% git cherry-pick -n 2ea356d

% git diff --staged
diff --git a/contact.html b/contact.html
new file mode 100644
index 0000000..997f0eb
--- /dev/null
+++ b/contact.html
@@ -0,0 +1,5 @@
+<html>
+    <body>
+        <h1>My Name is NekoChan</h1>
+    </body>
+</html>

 
次に 88f5199 をチェリーピックする。
が、コンフクトが起きた。対策方法は後述する。

% git cherry-pick -n 88f5199
error: 88f5199を適用できませんでした... add contact file with Type
ヒント: after resolving the conflicts, mark the corrected paths
ヒント: with 'git add <paths>' or 'git rm <paths>'

% git diff 
diff --cc contact.html
index 997f0eb,9b6e337..0000000
--- a/contact.html
+++ b/contact.html
@@@ -1,5 -1,7 +1,10 @@@
  <html>
      <body>
          <h1>My Name is NekoChan</h1>
++<<<<<<< HEAD
++=======
+         <h1>Tel: 090-1234-5678</h1>
+         <h1>Type: Hachiware</h1>
++>>>>>>> 88f5199... add contact file with Type
      </body>
  </html>

 
 

5.4

 

5.4.txt

前述のつづき。次のようにコンフリクトが起きている場合の解決方法。
競合は git mergetool を実行するとマージツールが起動するので、手動でマージするしかない。
 
マージツールの起動順は以下である。

1. merge.tool
2. システムから探す

git mergetool -t vimdiff などとしても良い。
 
起動しなかったので、.gitconfig に merge.tool を定義する。

[merge]
    tool = vimdiff
% git mergetool

(-- コンフリクトを解消する --)

 
コミットする。ただし、チェリーピックではコミット時に -m を付けない。( -n なしの場合は自動的に commit されるため)

% git commit 
[master ad555c1] add contact file with Type
 1 file changed, 6 insertions(+)
 create mode 100644 contact.html

 
vimdiff の場合
f:id:dnkrnka:20180630184819p:plain
 
 

6.2

 

6.2.txt

範囲を指定して、git log を実行する。

ログ全体

% git log --oneline  
ad555c1 (HEAD -> master) add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata
785a336 add <head> and <title> to index
fde7439 add in hello world HTML

 
5fbe9b0 の後ろから HEAD までのログのみを表示する

% git log 5fbe9b0.. --oneline
ad555c1 (HEAD -> master) add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html

 
5fbe9b0 から HEAD までのログのみを表示する
5fbe9b0^ としている箇所を ~1 としても同じである。

% git log 5fbe9b0^.. --oneline
ad555c1 (HEAD -> master) add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About

 
5fbe9b0 の後ろから HEAD の1つ手前までのログを表示する

% git log 5fbe9b0..HEAD^ --oneline
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html

 
タグ 1.0 の後ろからブランチ alternate までのログを表示する

% git log 1.0..alternate --oneline
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link

 
タグ 1.0 からブランチ alternate までのログを表示する

% git log 1.0~1..alternate --oneline
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata

 
f:id:dnkrnka:20180630194315p:plain
 
 

6.3

 

6.3.txt

差分比較の方法は前述の git log のリビジョン指定方法と同じである。

% git diff 1.0~..alternate
diff --git a/about.html b/about.html
new file mode 100644
index 0000000..e69de29
diff --git a/index.html b/hello.html
similarity index 50%
rename from index.html
rename to hello.html
index a4732d8..c9412a1 100644
--- a/index.html
+++ b/hello.html
@@ -1,8 +1,12 @@
 <html>
     <head>
         <title>Hello World in Git</title>
+        <meta name="description" content="hello world in Git" />
     </head>
     <body>
         <h1>Hello World!</h1>
     </body>
+    <ul>
+        <li><a href="about.html">About</a></li>
+    </ul>
 </html>

 
変更量を抽出するには diff --stat を使えば良い

% git diff --stat 1.0~..alternate
 about.html               | 0
 index.html => hello.html | 4 ++++
 2 files changed, 4 insertions(+)

変更量 と差分を同時出力させるには -p を追加する。

% git diff --stat -p 1.0~..alternate
 about.html               | 0
 index.html => hello.html | 4 ++++
 2 files changed, 4 insertions(+)

diff --git a/about.html b/about.html
new file mode 100644
index 0000000..e69de29
diff --git a/index.html b/hello.html
similarity index 50%
rename from index.html
rename to hello.html
index a4732d8..c9412a1 100644
--- a/index.html
+++ b/hello.html
@@ -1,8 +1,12 @@
 <html>
     <head>
         <title>Hello World in Git</title>
+        <meta name="description" content="hello world in Git" />
     </head>
     <body>
         <h1>Hello World!</h1>
     </body>
+    <ul>
+        <li><a href="about.html">About</a></li>
+    </ul>
 </html>

 
 

6.4

 

6.4.txt

blame と log を使って変更履歴を洗い出す。
 
今回洗い出す hello.html の元々のファイル名は index.html であった。
そのため、git log hello.html としても index.html 時のログは表示されない。
そこで、ファイル名変更前の情報も含めてログ表示をさせるには、git log --follow とする。

% git log --follow --oneline hello.html 
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata
785a336 add <head> and <title> to index
fde7439 add in hello world HTML

 
blame を実行する。

% git blame hello.html 
^fde7439 index.html (Neko 2018-06-30 05:47:23 +0900  1) <html>
785a336a index.html (Neko 2018-06-30 06:00:22 +0900  2)     <head>
785a336a index.html (Neko 2018-06-30 06:00:22 +0900  3)         <title>Hello World in Git</title>
272c9d5f index.html (Neko 2018-06-30 06:46:00 +0900  4)         <meta name="description" content="hello world in Git" />
785a336a index.html (Neko 2018-06-30 06:00:22 +0900  5)     </head>
^fde7439 index.html (Neko 2018-06-30 05:47:23 +0900  6)     <body>
^fde7439 index.html (Neko 2018-06-30 05:47:23 +0900  7)         <h1>Hello World!</h1>
^fde7439 index.html (Neko 2018-06-30 05:47:23 +0900  8)     </body>
32a2d7e1 index.html (Neko 2018-06-30 06:38:12 +0900  9)     <ul>
5fbe9b05 index.html (Neko 2018-06-30 07:55:38 +0900 10)         <li><a href="about.html">About</a></li>
32a2d7e1 index.html (Neko 2018-06-30 06:38:12 +0900 11)     </ul>
^fde7439 index.html (Neko 2018-06-30 05:47:23 +0900 12) </html>

 
785a336 以降の変化点を調べる

% git blame 785a336.. hello.html
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  1) <html>
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  2)     <head>
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  3)         <title>Hello World in Git</title>
272c9d5f index.html (Neko 2018-06-30 06:46:00 +0900  4)         <meta name="description" content="hello world in Git" />
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  5)     </head>
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  6)     <body>
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  7)         <h1>Hello World!</h1>
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900  8)     </body>
32a2d7e1 index.html (Neko 2018-06-30 06:38:12 +0900  9)     <ul>
5fbe9b05 index.html (Neko 2018-06-30 07:55:38 +0900 10)         <li><a href="about.html">About</a></li>
32a2d7e1 index.html (Neko 2018-06-30 06:38:12 +0900 11)     </ul>
^785a336 index.html (Neko 2018-06-30 06:00:22 +0900 12) </html>

 
785a336 〜 5fbe9b05 までの変化点を調べる。
なお、この区間ではファイル名が hello.html ではなく index.html であったので、引数として指定するファイル名に注意すること。

% git blame 785a336..5fbe9b0 index.html
^785a336 (Neko 2018-06-30 06:00:22 +0900  1) <html>
^785a336 (Neko 2018-06-30 06:00:22 +0900  2)     <head>
^785a336 (Neko 2018-06-30 06:00:22 +0900  3)         <title>Hello World in Git</title>
272c9d5f (Neko 2018-06-30 06:46:00 +0900  4)         <meta name="description" content="hello world in Git" />
^785a336 (Neko 2018-06-30 06:00:22 +0900  5)     </head>
^785a336 (Neko 2018-06-30 06:00:22 +0900  6)     <body>
^785a336 (Neko 2018-06-30 06:00:22 +0900  7)         <h1>Hello World!</h1>
^785a336 (Neko 2018-06-30 06:00:22 +0900  8)     </body>
32a2d7e1 (Neko 2018-06-30 06:38:12 +0900  9)     <ul>
5fbe9b05 (Neko 2018-06-30 07:55:38 +0900 10)         <li><a href="about.html">About</a></li>
32a2d7e1 (Neko 2018-06-30 06:38:12 +0900 11)     </ul>
^785a336 (Neko 2018-06-30 06:00:22 +0900 12) </html>

 
 

6.6

 

6.6.txt

コミットログの修正
git commit や git commit -m でログを書いてしまっていても、 git commit --amend で変更可能である。
 
 

コミットの取り消し
git revert を使うと、直前のコミットを取り消すためのコミットを行う。
 
rever 前のコミットID の状態。

% git log
ad555c1 add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata
785a336 add <head> and <title> to index
fde7439 add in hello world HTML

 
rever する。(-n 無しだと、即座にコミットしてしまう)

% git revert -n HEAD

 
rever による差分を確認する。

% git diff HEAD^..
diff --git a/contact.html b/contact.html
new file mode 100644
index 0000000..91a7122
--- /dev/null
+++ b/contact.html
@@ -0,0 +1,6 @@
+<html>
+    <body>
+        <h1>My Name is NekoChan</h1>
+        <h1>Type: Hachiware</h1>
+    </body>
+</html>

 
commit する。

% git commit

 
rever 後のコミットID の状態。
871aa02 が追加された。

% git commit 
[master 871aa02] Revert "add contact file with Type"
 1 file changed, 6 deletions(-)
 delete mode 100644 contact.html

% git log
871aa02 (HEAD -> master) Revert "add contact file with Type"
ad555c1 add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata
785a336 add <head> and <title> to index
fde7439 add in hello world HTML

 
rever 実施による差分を見る。

% git diff ad555c1 871aa02
diff --git a/contact.html b/contact.html
deleted file mode 100644
index 91a7122..0000000
--- a/contact.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>
-    <body>
-        <h1>My Name is NekoChan</h1>
-        <h1>Type: Hachiware</h1>
-    </body>
-</html>

 
 
 
変更をリセットする

revert のように取り消しコミットすら作らずに取り消しするには、reset を使う。
reset オプションの --soft は Stage に戻し、--hard は Stage に戻すことすらせずに削除してしまう。

% git log --oneline  
871aa02 (HEAD -> master) Revert "add contact file with Type"
ad555c1 add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata
785a336 add <head> and <title> to index
fde7439 add in hello world HTML

直前のコミットを取り消す処理をする。
HEAD^^ や HEAD~3 などとすれば、2つでも3つでも取り消しすることが可能である。

% git reset --soft HEAD^

 
871aa02 が消された。
ちなみに 871aa02 は contact.html を追加した対応だったので、今回の reset により contact.html が削除されることになる。

% git log --oneline  
ad555c1 (HEAD -> master) add contact file with Type
7d94ef8 (alternate) add the skeleton of an about page
49c53a5 git mv index.html hello.html
5fbe9b0 changed BIography to About
32a2d7e add in a bio link
272c9d5 (tag: 1.0) Add in a description element to the metadata
785a336 add <head> and <title> to index
fde7439 add in hello world HTML

 
reset --soft により Stage エリアにデータが残っているので、git diff HEAD^..HEAD で差分を見ることができる。
(--hard の場合のこの確認ができなくなる)

% git diff HEAD^..HEAD
diff --git a/contact.html b/contact.html
new file mode 100644
index 0000000..91a7122
--- /dev/null
+++ b/contact.html
@@ -0,0 +1,6 @@
+<html>
+    <body>
+        <h1>My Name is NekoChan</h1>
+        <h1>Type: Hachiware</h1>
+    </body>
+</html>

 
git status をすれば、実際に Stage エリアに残っていることが分かる。
(--hard の場合のこの確認ができなくなる)

% git status
ブランチ master
コミット予定の変更点:
  (use "git reset HEAD <file>..." to unstage)

	deleted:    contact.html

 
 

7.3

 

7.3.txt

リモートリポジトリの clone をすると、clone してきたリポジトリは以下の2つの機能を持つ。

  • リモートリポジトリの変更追跡
  • ローカルリポジトリの変更追跡

 

% git clone https://nekochango@github.com/nekochango/fishingz

リモートの追跡ブランチ
プレフィクスの「origin/」は単にリモートリポジトリを意味するためのもの。

% git branch -r
  origin/HEAD -> origin/master
  origin/master

ローカルの追跡ブランチ

% git branch

 
 
fetch と pull について
 
リモートリポジトリを clone した直後の状態
f:id:dnkrnka:20180630233534p:plain

リモートリポジトリが更新されたとき
コミットID f071cf4 が追加された。が、ローカルリポジトリ上の「リモートリポジトリの追跡情報」は古い。
そこで追跡リポジトリを更新するが、このときに fetch と pull の2つがある。
f:id:dnkrnka:20180630233948p:plain

 
git fetch の場合

% git fetch
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/nekochango/fishingz
   f46cf48..f071cf4  master     -> origin/master

ただし、ローカルリポジトリへの反映はまだである。

% git log --oneline 
f46cf48 Update README.md
8d063fb Update README_jp.md
30726e3 Modify: Release 1.9.0

以上より、下図のようにローカルリポジトリ上の「リモートリポジトリの追跡情報」が更新できた。
f:id:dnkrnka:20180630234445p:plain

その後は任意のタイミングで次のように git rebase をすればローカルリポジトリも更新できる。

% git rebase origin/master
Current branch master is up to date.
~/w/P/fishingz_fetch (master=) ><> git diff
~/w/P/fishingz_fetch (master=) ><> git log --oneline  |head
f071cf4 Modify: init.fish
f46cf48 Update README.md
8d063fb Update README_jp.md
30726e3 Modify: Release 1.9.0

 
git pull の場合

% git pull 
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/nekochango/fishingz
   f46cf48..f071cf4  master     -> origin/master
Updating f46cf48..f071cf4
Fast-forward
 init.fish | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

ローカルリポジトリにも反映された。

% git log --oneline 
f071cf4 Modify: init.fish
f46cf48 Update README.md
8d063fb Update README_jp.md
30726e3 Modify: Release 1.9.0

以上より、下図のようにローカルリポジトリ上の「リモートリポジトリの追跡情報」と「リポジトリ」の両方が更新できた。
f:id:dnkrnka:20180630235258p:plain


 
git fetch や git pull する前に WorkTree を変更していた場合
次のように WorkTree 上のファイルを変更していた場合。
競合が起きない限り、git pull が可能である。

% git diff
diff --git a/sonar.fish b/sonar.fish
index a02de64..2cd9d5b 100644
--- a/sonar.fish
+++ b/sonar.fish
@@ -1,5 +1,3 @@
-#!/usr/bin/env fish
-
 function sonar \
 --description "locate the file or directory name from DB for fishingz"


 
git fetch や git pull する前に ローカルリポジトリにコミットしていた場合

% git commit -a -m "Modify: sonar.fish changed"
[master 6c69f8c] Modify: sonar.fish changed
 1 file changed, 2 deletions(-)
% git log --oneline 
6c69f8c Modify: sonar.fish changed
f46cf48 Update README.md
8d063fb Update README_jp.md
30726e3 Modify: Release 1.9.0

 
このときのコミットID は下図のようになっている。
f:id:dnkrnka:20180701001219p:plain

 
この状態でリモートリポジトリに push しようとしても「リモートリポジトリの追跡情報」が古くて、先にリモートリポジトリにコミット済みの「f071cf4」とコンフリクトが起きてしまう。
実際にコンフリクトが起きると次のようになる。

% git push origin master 
Password for 'https://nekochango@github.com': 
To https://github.com/nekochango/fishingz
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://nekochango@github.com/nekochango/fishingz'
ヒント: Updates were rejected because the remote contains work that you do
ヒント: not have locally. This is usually caused by another repository pushing
ヒント: to the same ref. You may want to first integrate the remote changes
ヒント: (e.g., 'git pull ...') before pushing again.
ヒント: See the 'Note about fast-forwards' in 'git push --help' for details.

 
以下のようにして、git pull をして最新のリモートリポジトリをマージする。
もちろん、git fetch 〜 git rebase でも良い。
下記は例なのでコンフリクトが起きていないが、実際はコンフリクトが起きることの方が多い。

% git pull 
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (1/1), done.
remote: Total 3 (delta 2), reused 3 (delta 2), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/nekochango/fishingz
   f46cf48..f071cf4  master     -> origin/master
Merge made by the 'recursive' strategy.
 init.fish | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

 
このときのコミットID は以下の通り。

% git log --oneline
6121601 Merge branch 'master' of https://github.com/nekochango/fishingz
6c69f8c Modify: sonar.fish changed
f071cf4 Modify: init.fish
f46cf48 Update README.md
8d063fb Update README_jp.md
30726e3 Modify: Release 1.9.0

 
マージが済んだらリモートリポジトリに push する。以下のようになる。
f:id:dnkrnka:20180701002643p:plain