【Git第5回】ブランチ・マージ・コンフリクト発生時の対応/ハンズオン

【Git第5回】ブランチ・マージ・コンフリクト発生時の対応/ハンズオン

GitとGitHubのプログラミングメモ第5回です。何回かに分けてメモを投稿していきます。

なお、この記事はプログラミングメモですのでどんどん追記していきます。

【参考資料】
>> 【Udemy】Git: もう怖くないGit!チーム開発で必要なGitを完全マスター

【関連記事】

ブランチのハンズオン

ブランチの仕組み

  • 複数の機能を並行して開発するための仕組み
  • ブランチはコミットを指したポインタ
  • ブランチの作成や切替、マージが他のバージョン管理ツールより高速

Gitのファイルの持ち方

  • Gitのコミットが保持する情報:tree情報、auther情報、またコミット2以降は親情報(parent)をハッシュで保持する
  • コミットはスナップショット それが時系列順に連なる
  • コミットするとブランチが指すコミットファイルが変わる
  • HEAD:現在作業中のブランチへのポインタ

ブランチの切替/新規追加する

# command
git checkout            # 切替までは行わない/HEADは現在のブランチを向いたまま
git checkout -b         # ブランチの作成と切替を一度にしてくれる

# 確認コマンド git branch # ブランチの一覧を表示する
git branch -a           # 全てのブランチを表示する

Hands On その1

実際にブランチの切替とファイルの新規追加をハンズオンしてみる。

# カレントブランチを確認
$ git branch
master
* tutorial

# featureブランチを作成し、切替する
$ git checkout -b feature
Switched to a new branch 'feature'

# カレントブランチを確認/feature ブランチに切り替わったことを確認
# これにより、分岐して作業が可能になる
$ git branch
* feature
master
tutorial

# テストファイルを作成
$ ./feature/feature.txt
$ vim feature/feature.txt

# 以下を記載
feature branch test

# git status で状況を確認
On branch feature
Changes not staged for commit:
Untracked files:
(use "git add ..." to include in what will be committed)
feature/

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

# add commit pushしていく
$ git add feature/feature.txt
$ git commit -m "test commit at feature"
[feature 0f9902a] test commit at feature
1 file changed, 1 insertion(+)
create mode 100644 feature/feature.txt

# 別なブランチに「feature/feature.txt」が存在しないことを確認
$ git checkout tutorial
$ git branch
feature
master
* tutorial
# tutorial ブランチに切替 → ls で確認
$ ls -l
drwxr-xr-x@ 6 yoshi staff 192 Feb 9 15:45 tutorial_PowerShell
drwxr-xr-x 4 yoshi staff 128 Feb 12 12:27 tutorial_git
drwxr-xr-x 3 yoshi staff 96 Feb 12 09:03 tutorial_linux
drwxr-xr-x 13 yoshi staff 416 Feb 12 08:28 tutorial_php
drwxr-xr-x 3 yoshi staff 96 Feb 12 09:04 tutorial_sql

# git pushする
# ローカルの feature ブランチを、origin 上の feature ブランチに push
$ git push origin feature:feature

# 注意点
# 修正した内容をpushしようとすると、以前のコミットとコンフリクトしてエラーとなり、pushできない
# そのため、「-f」オプションをつけて強制的にpushする必要がある
$ git push -f origin HEAD

Hands On その2

新たなブランチの作成→ファイルの作成→リモートへのプッシュが確認できたので、いったんブランチを削除する。

# 別なブランチに移動
$ git checkout tutorial

# カレントブランチを確認
$git branch
feature
master
* tutorial

# ブランチの削除/ローカル
git branch -d # -d オプション:削除対象のブランチがリモートブランチにプッシュおよびマージ済みの場合のみ削除を実行
git branch -D # プッシュ、マージされていないブランチを強制的に削除したい場合

# example
$ git branch -d feature

# ブランチの削除/リモート
$ git push --delete

# example git push origin --delete feature

マージのハンズオン

マージとは

他の人の変更内容を取り込む作業のこと

# command example
$ git merge $ git merge <remmote-name/branch-name>
$ git merge origin/tutorial

3種類のマージ

  • Fast Foward :  早送りになるマージ : ブランチが枝分かれしていないとき、ブランチのポインタを前に進める
  • Auto Merge :  基本的なマージ : 枝分かれして開発している場合、マージコミットという新しいコミットを作る
  • コンフリクト: 複数人が同じ箇所を別々に編集 → GitHubでどちらの変更を優先して良いかわからない状態

ハンズオン

GitHubで編集 → ローカルに取り込み(マージ)してみる

GitHubで「index.html」を編集

次にターミナルで「git pull」する

$ git pull origin tutorial
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 784 bytes | 196.00 KiB/s, done.
From https://github.com/conti0513/development
* branch tutorial -> FETCH_HEAD
af80a5b..ab20c6d tutorial -> origin/tutorial
Merge made by the 'ort' strategy.
tutorial_git/index.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
---

# index.htmlが変更(マージ)されたことを確認
$ git log --oneline
ab20c6d (origin/tutorial) Update index.html

コンフリクト

複数人が同じ箇所を別々に編集 → GitHubでどちらの変更を優先して良いかわからない状態

コンフリクトの解決方法

  • コンフリクトしたファイルを突き止める
  • コンフリクトしたファイルの内容を(本来やりたかった記述に)書き換える

コンフリクトが起きないようにするための工夫

  • 複数人で同じファイルを変更しない
  • pullやremote push する前に変更中の状態を無くしておく(commitやstashをしておく)
  • pullするときは該当ブランチに移動してから作業する
  • コンフリクトしても慌てない

コンフリクト解消ハンズオン

よくわからなくなったので最初の構成に戻す→やりたい構成にしたい

発生事象

  • 個人開発環境でGitを操作しているうちに、よくわからなくなった
  • git push, git pull, git reset …色々やっているうちによくわからなくなった
  • ごみファイルが大量にある
  • なぜかsubmoduleができた
  • ローカルのフォルダはそのままにして、Gitをキレイにしたい
  • やりたい構成にしたい

やりたかった構成

development(リポジトリ)
|-master(ブランチ/個人開発したツールやWEBサイトの向けに予約)
|-tutorial(ブランチ/各種調査・テスト・学習時のコードはこちら)
|-tutorial_Powershell
|-tutorial_php
|-tutorial_git
|-tutorial_linux
|-tutorial_sql
|-readme.txt(ブランチの概要を記載)
:
:

修正前の構成

development(リポジトリ)
|-master(ブランチ/個人開発したツールやWEBサイトの向けに予約)
|-index.html
|-test.html

|-tutorial(ブランチ/各種調査・テスト・学習時のコードはこちら)
|-tutorial_Powershell
|-tutorial_php
|-tutorial_git
|-tutorial_linux
|-tutorial_sql

発生したエラー

  • なぜかsubmoduleが作成される
  • 全てのローカルのディレクトリが反映されない
  • git diff をすると「-dirty」が発生
  • git addすると怒られる「warning: adding embedded git repository:」
  • git commit すると怒られる
  • git push すると怒られる
  • git pull すると怒られる

対応内容

# ローカルのディレクトリのバックアップを作成
---
Local
|-tutorial_bkup
|-turorial
--

# ローカルで「.gitignore」ファイルを記載し、Gitで管理しないフォルダやファイルを記載
# git rm <fire-name/dir-name>で該当ディレクトリのファイルを削除
# 消えなければ 手動でrm
# ファイルを残したければ、git rm -- cach <fire-name/dir-name>で該当ディレクトリの管理対象からはずす
# ファイルをバックアップから戻す

#GitHubのページで以下になったことを確認

---
development(リポジトリ)
|-master(ブランチ/個人開発したツールやWEBサイトの向けに予約)
|-何もなし
|-tutorial(ブランチ/各種調査・テスト・学習時のコードはこちら)
|-何もなし
---

# ローカルのディレクトリに管理したいファイルやディレクトリをバックアップから戻す

# 再度あらためてgit initから実行

 

ブランチの変更・削除

ブランチの変更

# command
$ git branch -m
$ git branch -m feature

ブランチの削除

# command
$ git branch -d # マージされていない変更が残っている場合削除しない
$ git branch -D # 強制削除