git rebase -iで過去のコミットを編集する

git rebase -iで過去を改竄する。

git rebase -i ブランチ名 で過去のコミットを編集することが出来ます。
細かいことはこちら古いコミットを書き換える: 歴史修正主義者のための git rebase -i 入門 - 学習する機械、学習しない人間 Next Generation

  1. git rebase -iして出てくる指示書に何をしたいのか書き、過去の変更が始まったらそれぞれのフェーズにあった変更を行います。
  2. 変更が終わったら必要ならgit addし、git commit --amendして変更をコミットします。
  3. git commit --amendすると変更内容のコミットと同時にcommitメッセージの変更を行えるので、適宜編集します。
  4. コミットしたらgit rebase --continueで次のコミットの編集に移動します。

途中で失敗した場合はgit rebase --abortで全てを無かった事にしてgit rebase -iを行う直前に戻れます。

リモートリポジトリの過去を改竄する。

複数ヶ所のPCから同じリモートリポジトリに対して作業を行なっている場合、リモートリポジトリを通してやりかけの作業を共有できると便利です。
ただしこの場合、リモートリポジトリのコミットログを変更できないとコミットログがグッチャグチャになってしまいます。
これもgit rebase -iで解決できます。

  1. git checkout -b ローカルのブランチ名 origin/リモートのブランチ名 でブランチを切ります。
  2. git rebase -iします。
  3. git push origin +ローカルのブランチ名:リモートのブランチ名 して強制的にコミットツリーを変更します。
  4. 他のリポジトリから変更を取得する際は、git fetchしてgit rebase origin/リモートのブランチ名 としましょう。

なお、rebase -iで行った編集が、「HEADから順にいくつかのコミットを削除した」だけだと、他のcloneしたリポジトリで変更後のリモートリポジトリの内容をfetchしてrebaseしても、直接pullしても反映されないので注意。

Gitの使い方

すごく簡単に。

リポジトリ作成

git init : ローカルリポジトリ
git --bare init : 公開用リポジトリ

リポジトリのクローンの作成

git clone URI
git svn clone URI : git-svnの場合

コミット用のファイルのスナップショットの一時保存。

git add ファイル名又はディレクトリ名
この時点でのファイル情報がコミットする際に使用される。

コミット

git commit -m "ログメッセージ"

Subversionリポジトリへのコミット

git commit を行った後に、git svn dcommit

ローカルリポジトリからcheckout

git checkout .
git checkout 対象ファイル/ディレクトリ名

ローカルブランチ作成

git branch ブランチ名

ローカルブランチの一覧表示

git branch

ファイルツリーを直前のコミットの状態に戻す

git reset --hard

Subversionリポジトリとローカルリポジトリの同期

git svn rebase


--- 5/12 Subversionとの連携運用についての補足 ---
参考:分散型バージョン管理システム「Git」タスク単位ブランチ運用のための10のステップ: the true power

とにかくmasterリポジトリを中心として運用することにより、運用の単純化を図る。
以下、理解できた所だけまとめ。

1:リポジトリクローンを作成

$ git svn clone URL PATH

2:タスク毎のブランチを作成

$ git checkout master
$ git branch BRANCH-NAME
必ずmasterのブランチとする。

3:定期的にmasterブランチをsvnリポジトリの最新と同期させる。

$ git checkout master
$ git svn rebase
rmとかmvファイラで削除とか移動とかしちゃったファイルがある場合はその事をコミットする前に、
$ git checkout FILE-NAME
も追加で行う。ただし git rm FILE-NAME とかやってた場合は復元不能
git rm FILE-NAME とかやってた場合は
$ git reset --hard
を行うと1つ前のコミットされたファイルツリーの状態に戻る。ただしファイルツリー全体が元に戻る。

4:ブランチの切り替え

$ git checkout BRANCH-NAME

5:コミット

$ git add FILE1 FILE2 FILE3 ...
$ git commit -m "ログメッセージ"
既存ファイルの編集のみなら以下も可。
$ git commit -a -m "ログメッセージ"

6:masterの変更を指定したブランチに取り込む。

$ git checkout masterの変更を取り込むブランチ
$ git merge master
特にブランチの作業内容をmasterにマージする前に必ず行う事。
そうしないとsvnリポジトリ上での編集履歴が意味不明になる、らしい。

7:指定したブランチの変更をmasterに取り込む。

$ git checkout master
$ git merge 取り込み先ブランチ名
6の逆の操作。
この操作を行う前に必ず対象ブランチに対して6の操作を行うこと。

8:svnリポジトリにコミット

$ git checkout master
$ git svn dcommit
カレントブランチの内容をtrunkとしてコミットしちゃうので必ずmasterに移動する。