git-flow 云々

とりあえずでびあんパケジは以下から入手。

これを書いてる時点では git-flow_0.4.1-2_all.deb というモノがありますのでそれをオトしてきておもむろに dpkg -i したら無事導入できました。

確認

nvie/gitflow の README.mdown によればざっくりな使い方てきには以下?

  • 初期化
    • git flow init
  • feature
  • release
  • hotfix
  • support

feature 以外は master に commit されるとありますね。そしてどうもそれぞれリモートへの push は自分で、な模様。

初期化

とりあえず以下らしい。今回は空っぽなリポジトリで動作確認。

git flow init [-d]

  • d つけたら何も聞かれずデフォ設定らしい。適当なディレクトリ掘って試験。
$ git flow init -d
Initialized empty Git repository in /home/rms/tmp/git-flow-test/.git/
Using default branch names.
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master] 
Branch name for "next release" development: [develop] 

How to name your supporting branch prefixes?
Feature branches? [feature/] 
Release branches? [release/] 
Hotfix branches? [hotfix/] 
Support branches? [support/] 
Version tag prefix? [] 
$

ええと branch の状態はどうなってるのかな。

$ git branch
* develop
  master
$

.git/config の中身はというと以下。

$ cat .git/config 
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[gitflow "branch"]
        master = master
        develop = develop
[gitflow "prefix"]
        feature = feature/
        release = release/
        hotfix = hotfix/
        support = support/
        versiontag = 
$

リモート追加するとどうなるんかな。そういやリモートブランチってどうやって作るんだっけ、と言いつつ自分エントリ検索したら以下が出てきた。

上記エントリだと branch を一気に作ってますね。github にスペース確保したのでちょっとやってみます。

$ git remote add origin git@github.com:yamanetoshi/git-flow-test.git
$ cat .git/config
[core]
        repositoryformatversion = 0
        filemode = true
        bare = false
        logallrefupdates = true
[gitflow "branch"]
        master = master
        develop = develop
[gitflow "prefix"]
        feature = feature/
        release = release/
        hotfix = hotfix/
        support = support/
        versiontag = 
[remote "origin"]
        url = git@github.com:yamanetoshi/git-glow-test.git
        fetch = +refs/heads/*:refs/remotes/origin/*
$

で、checkout するのか。

$ git checkout -t -b develop origin/develop
fatal: git checkout: updating paths is incompatible with switching branches.
Did you intend to checkout 'origin/develop' which can not be resolved as commit?
$

あわわ。よく考えたら develop な branch はスデに存在してますな。ええと、git push origin development で良いのかな。

$ git push origin development
ERROR: Repository not found.
fatal: The remote end hung up unexpectedly
$

ちょっとマテ。中身を入れて master を push しよう。

$ ls
1.scm
$ git add .
$ git commit -m 'add 1.scm'
$ git checkout master
$ git merge develop --no-ff
$ git push origin master
ERROR: Repository not found.
fatal: The remote end hung up unexpectedly
$

あら。一旦 remote なナニを削除してリトライ。

$ git remote add origin git@github.com:yamanetoshi/git-flow-test.git
$ git push origin master
Counting objects: 6, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 1.59 KiB, done.
Total 6 (delta 1), reused 0 (delta 0)
To git@github.com:yamanetoshi/git-flow-test.git
 * [new branch]      master -> master
$

なんだったのかな。んで develop を checkout してこっちも push か。

$ git checkout develop
$ git push origin develop
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:yamanetoshi/git-flow-test.git
 * [new branch]      develop -> develop
$

なんか整形外科でリハビリやってる年寄り感満点ですね。github 確認したらリモートブランチもちゃんとあります。
あるいは git branch -a が以下。

$ git branch -a
* develop
  master
  remotes/origin/develop
  remotes/origin/master
$

では、修正を盛り込んでみます。

git flow feature

ええと、以下で良いのかな。

$ git flow feature start chapter2
Switched to a new branch 'feature/chapter2'

Summary of actions:
- A new branch 'feature/chapter2' was created, based on 'develop'
- You are now on branch 'feature/chapter2'

Now, start committing on your feature. When done, use:

     git flow feature finish chapter2

$ git branch
  develop
* feature/chapter2
  master
$

ええと branch について add および commit は自分でするのね (当たり前)。

$ git status
# On branch feature/chapter2
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       2.scm
nothing added to commit but untracked files present (use "git add" to track)
$

ファイルを一つ追加。

$ git add .
$ git commit -m 'add 2.scm'

で、git flow feature finish か。

$ git flow feature finish chapter2
Switched to branch 'develop'
Updating aafe317..13d1b80
Fast-forward
 2.scm |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)
 create mode 100644 2.scm
Deleted branch feature/chapter2 (was 13d1b80).

Summary of actions:
- The feature branch 'feature/chapter2' was merged into 'develop'
- Feature branch 'feature/chapter2' has been removed
- You are now on branch 'develop'

$

をを、--no-ff で develop に merge したのか。で、branch も削除と。

$ git branch
* develop
  master
$

ぬ。これって手動でやってた時って

  1. feature ブランチで commit
  2. develop ブランチに移動
  3. git pull で最新の状態を確保
  4. git merge

で merge の時に衝突発生したら云々、ってヤッてましたがこのあたりはどうなんでしょ。出力見てる限りではそこまで懇切丁寧ではないように見えます。

衝突発生させてみる

ええとどうすりゃ良いかな。別場所に clone してみます。

$ git branch
* master
$ ls
1.scm
$

ぬ。よく考えたらこれも git-flow なナニにしなきゃ、なのか。

$ git flow init -d

で、どーすりゃ良いのだろ。ってもう片方のナニを push しとらんな

$ git push origin develop

もう片方と差分が出てるはずですが

$ git fetch origin
remote: Counting objects: 4, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 3 (delta 0)
Unpacking objects: 100% (3/3), done.
From github.com:yamanetoshi/git-flow-test
   aafe317..13d1b80  develop    -> origin/develop
$ git merge origin/develop
Merge made by recursive.
 2.scm |   25 +++++++++++++++++++++++++
 1 files changed, 25 insertions(+), 0 deletions(-)
 create mode 100644 2.scm
$

わーを、素晴しひ。ということは git flow feature finish の前に git fetch origin 及び git merge origin/develop しなさい、というルール設定になるのかな。
衝突を発生させてみます。
まず片側で以下。

$ git flow feature start modify-chapter2-1
Branches 'develop' and 'origin/develop' have diverged.
And local branch 'develop' is ahead of 'origin/develop'.
Switched to a new branch 'feature/modify-chapter2-1'

Summary of actions:
- A new branch 'feature/modify-chapter2-1' was created, based on 'develop'
- You are now on branch 'feature/modify-chapter2-1'

Now, start committing on your feature. When done, use:

     git flow feature finish modify-chapter2-1

$

で、もう片方で以下。

$ git flow feature start modify-chapter2-2
Switched to a new branch 'feature/modify-chapter2-2'

Summary of actions:
- A new branch 'feature/modify-chapter2-2' was created, based on 'develop'
- You are now on branch 'feature/modify-chapter2-2'

Now, start committing on your feature. When done, use:

     git flow feature finish modify-chapter2-2

$

およ、なんか出力が異なっておりますな。構わず修正。同じファイル (2.scm) を修正して衝突を故意に発生させます。modify-chapter2-1 の方からやります。

$ git add .
$ git commit -m 'modify 2.scm'
$ git fetch origin
$ git flow feature finish modify-chapter2-1
Switched to branch 'develop'
Updating fd152ab..e31fd6b
Fast-forward
 2.scm |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
Deleted branch feature/modify-chapter2-1 (was e31fd6b).

Summary of actions:
- The feature branch 'feature/modify-chapter2-1' was merged into 'develop'
- Feature branch 'feature/modify-chapter2-1' has been removed
- You are now on branch 'develop'

$

で、git push か。

$ git push origin develop
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 538 bytes, done.
Total 4 (delta 1), reused 0 (delta 0)
To git@github.com:yamanetoshi/git-flow-test.git
   13d1b80..e31fd6b  develop -> develop
$

で modify-chapter2-2 に。

$ git add .
$ git commit -m 'modify 2.scm'
$ git fetch origin
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 1), reused 4 (delta 1)
Unpacking objects: 100% (4/4), done.
From github.com:yamanetoshi/git-flow-test
   13d1b80..e31fd6b  develop    -> origin/develop
$

何らかの更新が入っている模様です。ので merge するのか。

$ git merge origin/develop
Auto-merging 2.scm
CONFLICT (content): Merge conflict in 2.scm
Automatic merge failed; fix conflicts and then commit the result.
$

を、ここで検出できるのか。素晴しい。自動なナニは失敗してる模様。ソースもマージ失敗なナニになっております。微妙な衝突のさせ方したので中身も微妙。
ここはワシの言う通りにせい、ってことで直して push してみるか。

$ git add 2.scm
$ git commit -m 'fix conflict'
[feature/modify-chapter2-2 986625f] fix conflicts
$ git flow feature finish modify-chapter2-2
Switched to branch 'develop'
Merge made by recursive.
 2.scm |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)
Deleted branch feature/modify-chapter2-2 (was 986625f).

Summary of actions:
- The feature branch 'feature/modify-chapter2-2' was merged into 'develop'
- Feature branch 'feature/modify-chapter2-2' has been removed
- You are now on branch 'develop'

$

で、リモートに投げるのか。

$ git push origin develop
Counting objects: 9, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 623 bytes, done.
Total 5 (delta 2), reused 0 (delta 0)
To git@github.com:yamanetoshi/git-flow-test.git
   e31fd6b..e3bccf7  develop -> develop
$

で、もう片方で fetch したらどうなるか。

$ git fetch origin
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 5 (delta 2), reused 5 (delta 2)
Unpacking objects: 100% (5/5), done.
From github.com:yamanetoshi/git-flow-test
   e31fd6b..e3bccf7  develop    -> origin/develop
$

はい、変更かかってますー。ので merge を。

$ git merge origin/develop
Updating e31fd6b..e3bccf7
Fast-forward
 2.scm |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)
$

いやはや。こちら側が盛り込んだ修正は台無しになっておりますが。

まとめ

流れてきには

  1. git flow init -d で開始 (最初から、でも clone した場合でも同じ)
  2. git flow feature start で修正盛り込みを開始
  3. 修正して試験パスしたら git add して git commit
  4. feature なナニが終了したら git fetch origin でリモートの修正確認
    1. リモート修正を git merge で取り込む
    2. ここで衝突発生が分かる
    3. 衝突発生してたら修正して git add して git commit
  5. git flow feature finish で develop と merge
  6. リモートに push

とは言え、push で衝突したら南無阿弥陀仏ですな。てか fetch して merge な流れになるはず。社内勉強会で git ネタなナニを依頼されてるんですが、このあたりのハンズオンをしてみるのは良い取り組みかもしれません。
てーか、git-flow イマサラですが良いですね。

補足

release は finish したら master に merge してタグも打ってくれる (master に) 模様。処理が終わったらカレントな branch は develop になるみたいです。これは hotfix も同じ形になっているようです。あ、hotfix は master に merge されるんですね。
ここも別途で良いので動作を確認してみたいと思います。ただリモートとのやりとりについては、finish する前に fetch して差分があれば merge する、というフローは変わらないはず。