rcmdnk's blog

Github

vim-markdownをアップデートvim-markdown をアップデートした、という話をしましたが、 このレポジトリはもともとForkしたもので、元のレポジトリの変化を追いつつ アップデートしたので(というか今回は元のレポジトリのアップデートをマージしただけ) その流れについてまとめておきます。

レポジトリ設定

plasticboy/vim-markdown というレポジトリをForkして rcmdnk/vim-markdown というレポジトリを作りました。

元々のレポジトリにはmastermaster-hartsteinというブランチがありますが、 master-hartsteinというのは最初に他からインポートしたもの?か何かで 基本masterを使っています。

これをForkした rcmdnk/vim-markdown では、modというブランチを作ってここで変更を行っています。

masterは元のレポジトリを追いかける用に。

GitHubの方の設定で、レポジトリの Settings Default branchでデフォルトになるブランチをmodに変更しておきます。

Setting the default branch · GitHub Help

これで通常git clone...するとremotes/origin/HEADorigin/modを指すようになり、 最初にこのブランチが現れる様になります。

Fork元のレポジトリにつなげる

まず、元のレポジトリをremoteとして加えます。

$ git remote add plasticboy [email protected]:plasticboy/vim-markdown

次に、このplasticboy/masterorigin/masterに同期させたいわけですが、 その前に色々チェックしたいのでplasticboyfetchしておきます。

$ git fetch plasticboy
$ git br -a
  master
* mod
  remotes/origin/HEAD -> origin/mod
  remotes/origin/marc-hartstein
  remotes/origin/master
  remotes/origin/mod
  remotes/plasticboy/marc-hartstein
  remotes/plasticboy/master

これで

$ git diff origin/master plasticboy/master

plasticboy側でのその後の変化を見たり、

$ git diff origin/mod origin/master

で自分の所でどうアップデートしたのかを確認しておきます。

それから後でチェックするのを簡単にするため

$ git checkout master
$ git checkout -b master-tmp
$ git checkout mod
$ git checkout tag -a v0.0.1 -m "first version"
$ git push --tag

と、masterの現在地をテンポラリーブランチにとして作っておいて 1modの現在地の方はタグにしてGitHubの方へも送って置きました 。

元のレポジトリのアップデートをmasterにpull

$ git pull plasticboy master:master

plasticboyのmasterを意味するmaster:の部分は省略可能ですが、 これでplasticboyのmasterをローカルのmasterブランチにpull

masterブランチは何もいじってないので特に問題なくアップデート出来ます。

modをmaster(=Fork元の最新版)にrebase

$ git rebase master mod

これで上手く行ったらpushして終了。 ただ、大概コンフリクトが出るのでその処理を。

$ git rebase master mod
First, rewinding head to replay your work on top of it...
Applying: first modified version
Using index info to reconstruct a base tree...
M       README.md
M       syntax/mkd.vim
Falling back to patching base and 3-way merge...
Auto-merging syntax/mkd.vim
CONFLICT (content): Merge conflict in syntax/mkd.vim
Auto-merging README.md
Failed to merge in the changes.
Patch failed at 0001 first modified version
The copy of the patch that failed is found in:
   .../vim-markdown/.git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".

mergetoolでマージ

git mergetoolという便利なコマンドがあるのでこれを使います。 vimdiffをこのコマンド内の編集用として使いたいので、 ~/gitconfig

[merge]
    tool = vimdiff
    keepBackup = false

を加えておきます 2

これで、上の様なコンフリクトが起きた時に、

$ git mergetool

とするだけでvimdiffによるマージ編集が立ち上がります。 この時に、keepBackuptrueだと編集終了後に*.origというバックアップが 出来ますが、falseにしておくとこのバックアップ生成を無くすことが出来ます。

立ち上げると、

$ git mergetool
Merging:
syntax/mkd.vim

Normal merge conflict for 'syntax/mkd.vim':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (vimdiff):

こんな感じでどのファイルを修正するか表示してから編集に入ります。

編集画面は

|-----------------------|
|       |      |        |
| LOCAL | BASE | REMOTE |
|       |      |        |
|-----------------------|
|                       |
|        MERGED         |
|                       |
|-----------------------|

の様な4分割画面になります。 それぞれ:

  • LOCAL: merge前の状態(上の場合ではpullした後のmasterの状態)
  • BASE: LOCALとREMOTEの共通祖先の状態(上の場合ではpullする前(=master-tmp))の状態)
  • REMOTE: LOCALとREMOTEの共通祖先の状態(上の場合ではmerge前のmodの状態)
  • MERGED: 最終的にmerge後のファイル

となっています 3

LOCAL(左)とBASE(真中)を比較しFork元のアップデートを確認、 REMOTE(右)とBASE(真中)を比較して自分の変更を確認、といった感じ。

Fork元のアップデートしたものに対して 自分の変更をマージする、という形なので ちょっとやっててLOCALとREMOTEの逆感を感じましたが。

そして、下のMERGEDの所にコンフリクトの結果の

....
<<<<<<< HEAD
aaaaaa
=======
bbbbbb
>>>>>>> master

といった感じの部分があるので、これらを編集してコンフリクトを解消していきます。

最終的にMERGEDが思い通りになったら保存して他のウィンドウの物は 編集せずにそのまま終了すればOK。

一つ解消できたら

$ git rebase --continue

で先ほどのrebaseの続きを実行。 で、これでコンフリクトが出てこなくなるまで頑張ります。

originにpush

$ git push origin master

でmasterを送って、 modの方は変更がコンフリクトするので強制上書きするため-fを使って

$ git push -f origin mod

で送ってあげます。

以上で終了。

以下はおまけ。

操作の取り消し等

ファイルの変更の取り消し

file.txtに対する変更を取り消して元に戻したいときは

$ git checkout -- file.txt

--は通常は必要ないですが、もし、戻したいファイル/ディレクトリと同名の ブランチがあるとき、checkoutがブランチの変更になってしまうので、 そのようなときは--を付けてあげるとファイル/ディレクトリに対する操作になります。

すべて戻したいときは

$ git checkout .

もし、作業中の物を全部破棄して前回コミット直後まで戻りたいときは

$ git reset --hard HEAD

で、綺麗サッパリに元通りに。

commitの取り消し

HEADと同様に、適当なコミット状態をgit log等で見つけてきてそこまでもどりたいときは

$ git reset -hard 84984ad457bd4d8b38731207b226b0b763ed56b0

な感じでリビジョン番号を指定してあげればOK。

commitのやり直し

$ git commit --amend -m "re-commit..."

--amendオプションで前回commitの上書き。 前回commit後にaddとかしてなければメッセージだけ変更、 addしてるものがあれば前回のとまとめて一つのcommitを作ります。

rebaseを取り消す

rebaseするとcommitも順番が色々変わるので 上の方法だと上手くありません。

戻るにはgit reflogでHEADの変更を確認して

$ git reflog
48fa912 HEAD@{0}: rebase finished: returning to refs/heads/mod
48fa912 HEAD@{1}: rebase: Update README.md
5e61711 HEAD@{2}: rebase: added bitdeli
f20f6e9 HEAD@{3}: rebase: fixed liquied tags
1b053fd HEAD@{4}: rebase: update comment (valid for non-single like tag)
1427250 HEAD@{5}: rebase: added liquid output
...
03e10b1 HEAD@{47}: checkout: moving from mod to master
edf3bc9 HEAD@{48}: clone: from [email protected]:rcmdnk/vim-markdown


$ git reset --hard HEAD@{48}
HEAD is now at edf3bc9 Update README.md

こんな感じで適当なところへHEAD@{n}と指定して戻ります。

pushの取り消し

上の場合なんかでrebaseしたものをpushした後にやっぱり戻したいとき等。

まず、ローカルを上の方法で元に戻します。

その後、

$ git push -f origin mod

の様に-fでリモートのmodを元に戻したローカルのmodで強制上書き。

Sponsored Links
  1. とりあえず色々ごちゃごちゃしてわからなくなった時に確認出来るように。。。

  2. 。 もしくはコマンドラインから

    $ git config --global mergetool.tool vimdiff
    $ git config --global mergetool.keepBackup false
    

    また、もし、デフォルトのmergetoolを他のにしておきたい場合でも vimdiffを使いたい場合は

    $ git mergetool -t vimdiff
    

    でその時だけvimdiffが使えます。

  3. MERGED(file.txtとすると)と同じディレクトリにそれぞれ

    • file.txt.LOCAL.xxxx.txt
    • file.txt.BASE.xxxx.txt
    • file.txt.REMOTE.xxxx.txt

    と言った名前で生成されていて、mergeが済むと消える様になっています。

Sponsored Links

« vim-markdownをアップデート: Vimスクリプトで関数の最初にs:以外のコロンが使えなくなった sentakuにEmacsキーバインドを実装した »

}