カテゴリー別アーカイブ: git

git tag

タグをつける

$ git tag v0.0.0

リモートリポジトリに反映する

$ git push origin v0.0.0

過去のコミットにタグをつける

$ git tag v0.0.0 [コミットID]

タグをすべてリモートリポジトリに反映する

$ git push origin --tags

タグの削除

$ git tag -d [タグ名]
$ git push origin :[タグ名]

git stash pop でコンフリクトが発生した場合の解決方法

手動マージ

マーキングされた部分を手動で修正する方法です.

++<<<<<<< Updated upstream
// 現在のコミット
++=======
// コンクリフトした内容
++>>>>>>> Stashed changes

git checkout

現在のコミットにする場合

$ git checkout --ours .

checkoutを実行後, コンフリクトを解決するためにgit addが必要となります.

stashにする場合

$ git checkout --theirs .

checkoutを実行後, コンフリクトを解決するためにgit addが必要となります.

git stash

HEADと作業ディレクトリに差異がある場合 (つまり, 作業中の場合), ブランチの切り替えやgit rebaseなどはできません.

そういった一時的に作業内容をのけておく (スタックに積んでおく) ためにあるのが, git stashです

$ git stash

これで, 作業内容を保存し, 作業ディレクトリとインデックスをHEADと同じ状態にしたので, ブランチの切り替えやgit rebaseが可能になります.

また, 作業内容を復元するには,

$ git stash pop

とします.

ちなみに, 複数git stashしている場合は以下のように指定することで, ターゲットとなる内容を復元することができます

$ git stash list
stash@{0}: WIP on master: 4e99baf Commit Gruntfile.js
stash@{1}: WIP on gh-pages: 2efe8bc Add section for installation
....

$ git stash pop stash@{1}

ちなみに, git stash popは,

$ git stash pop stash@{0}

と等価です.

参考 : git stash 使い方

git reset のオプション

git reset のオプションでよく利用するものとしては,

  • –hard オプション
  • –mixed オプション (もしくは, オプションを指定しない)
  • –soft オプション

の3つがあります.

例えば, HEADの1つ前を対象に戻したい場合,

オプション 作業ディレクトリ インデックス コミット
$ git reset –hard HEAD~ HEAD~に戻る HEAD~に戻る HEAD~に戻る
$ git reset (–mixed) HEAD~ そのまま HEAD~に戻る HEAD~に戻る
$ git reset –soft HEAD~ そのまま そのまま HEAD~に戻る

git commit –amendの取り消し

git commit –amendでviエディタを起動してしまうと, そのまま終了してもコミットされてしまいます.

その状態で,

$ git reset --soft HEAD@{1}

とすれば, ヘッドの内容 (コミット) だけを直前の状態に戻すこと = git commit –amendを取り消すことが可能です.

ちなみに,

$ git reflog
2efe8bc HEAD@{0}: checkout: moving from master to gh-pages
4e99baf HEAD@{1}: checkout: moving from gh-pages to master
2efe8bc HEAD@{2}: checkout: moving from master to gh-pages
4e99baf HEAD@{3}: checkout: moving from gh-pages to master
2efe8bc HEAD@{4}: checkout: moving from master to gh-pages
4e99baf HEAD@{5}: checkout: moving from gh-pages to master
...

これで指定するコミットの内容のリストを表示できます.

git push オプションu

git pushのオプションuは追跡設定するためのオプションです.

$ git push -u origin master

追跡設定をすることで, それ以降は, git pushやgit pullの際にリモートリポジトリ名やブランチ名を省略可能になります. こんな感じで.

$ git push

で, リモートリポジトリにコミット可能になります.

ちなみに, git pushのオプションuは以下のコマンドと等価です.

$ git push --set-upstream origin master

git 過去のコミットの修正

gitを利用していると, どうしても過去のコミットを修正したい衝動が出てしまいます.

直前のコミットの修正であれば,

git commit --amend

を利用すれば, 簡単に修正可能です.

次に, 直前より過去のコミットを修正したい場合は, git rebaseコマンドを利用します.

rebaseコマンドを使う前準備として, 現在のディレクトリ・インデックスをHEADと同じ状態にしておく必要があります.

そして, HEADから3つ前のコミットを修正したい場合,

git rebase -i HEAD~~~

すると, viエディタが起動して, 以下のような表示がされます.

  1 pick 45ad73f Commit JavaScripts, Stylesheets and Images
  2 pick 30b42a6 Commit index.html
  3 pick 1f89baf Add Google Analytics code
  4 
  5 # Rebase f0949cc..1f89baf onto f0949cc
  6 #
  7 # Commands:
  8 #  p, pick = use commit
  9 #  r, reword = use commit, but edit the commit message
 10 #  e, edit = use commit, but stop for amending
 11 #  s, squash = use commit, but meld into previous commit
 12 #  f, fixup = like "squash", but discard this commit's log message
 13 #  x, exec = run command (the rest of the line) using shell
 14 #
 15 # These lines can be re-ordered; they are executed from top to bottom.
 16 #
 17 # If you remove a line here THAT COMMIT WILL BE LOST.
 18 #
 19 # However, if you remove everything, the rebase will be aborted.
 20 #
 21 # Note that empty commits are commented out

ここで, HEADから3つ前までのコミットが表示されていることに着目してください. 3つ前のコミットを修正したいので, 3つ前のコミットの ‘pick’ の部分を ‘edit’ (‘e’) に変更して保存してviエディタを終了します.

そのあとは, ファイルの修正をして, インデックスに追加して, git comit –amendでコミットします. なぜかといいますと, git rebaseの編集によって, HEADが一時的に指定したコミット (この例であれば, HEADから3つ前のコミット) に移動しているからです. つまり,

  1. 一時的に直前のコミットとみなす
  2. 直前のコミットなので, git commit –amendで修正可能

となるわけですね.

ところで, git commit –amendしただけでは, HEADの位置が本来の位置に戻らないので, この例では, HEADとその1つ前のコミットがない状態になってしまいます.

HEADの位置を本来の位置に戻すために, 最後の仕上げとして,

git rebase --continue

を実行することで, HEADを元の位置に戻し, なおかつ, 指定したコミットが修正された状態になります.
このとき, 修正したコミットより後のコミットは, 再コミットされるので, コミットIDは新しく割り振られることに注意してください.

また, ファイルの競合などが発生すると, このコマンドは失敗することにも注意が必要です.

git / GitHub masterブランチの削除

GitHubのリポジトリで, Webサイトだけ欲しい場合, つまり, gh-pagesのブランチのみが欲しい場合, masterブランチは削除しておきたい場合も多々あると思います.

ローカルリポジトリ, つまり, gitでmasterブランチを削除するのは簡単です.

まずは, masterブランチ (削除したいブランチ) 以外のブランチにチェックアウトします.

$ git branch
* gh-pages
   master

あとは, branchのd (delete) オプションを利用して削除するだけです.

$ git branch -d master

次は, GitHub (リモートリポジトリ側) のmasterブランチを削除します.
まず, GitHubの対象リポジトリのsettingsメニューでデフォルトのブランチをgh-pages (あるいは, 削除対象のブランチ以外) に設定しておきます.

GitHub settings
GitHub settings
GitHub settings Default branch
GitHub settings Default branch

あとは, ローカルリポジトリからGitHubに対してmasterブランチを削除するように指示する必要があります.

$ git push origin :master

 

このコマンドでGitHubのmasterブランチが削除されます.
ちなみに, このコマンドの意味は,

$ git push [プッシュ先のリポジトリ] [ローカルのブランチ]:[リモートのブランチ]

対応関係は以下のようになります.

  • [プッシュ先のリポジトリ] -> origin
  • [ローカルのブランチ]            -> 空のブランチ
  • [リモートのブランチ]            -> (GitHubの) masterブランチ

つまり, ローカルの空のブランチを, (GitHubの) masterブランチにシンクロさせることによって, GitHubのmasterブランチを削除しているわけですね.

参考 : 復習 Git: GitHub のブランチを削除する.

GitHub Pull Request の基本

昨日に引き続き, 今日もHTML5 ROCKSのリポジトリにPull Requestしました.

(備忘録的な意味もこめて, ) Pull Requestを送る手順をメモしておきます.

1. Pull Requestを送るリポジトリをFork

これは, gitの機能ではなく, GitHubの機能です. リポジトリをForkすることで, 自分の思うように変更が可能になります. Forkするには, 対象のリポジトリのGitHubのページの右上にある「Fork」ボタンを押すだけです.

 

GitHub Fork
GitHub Fork ボタン

2. Forkしたリポジトリをclone

Forkしたリポジトリをローカルの開発環境であつかうために, cloneしてきます. 注意していただきたいのは, Forkしたリポジトリをcloneしてください

$ git clone [Forkしたリポジトリ]

3. 開発用のブランチを作成

masterブランチはいわゆるトピックブランチ (最新の状態で, 常に正常に動作する. 戻りたいときの目印的な役割) としておいたほうがいいので, 新たにブランチを作成します. ブランチ名は適当に決めてください. とりあえず, ここではmy-workとします.

$ git branch
* master
$ git branch  my-work
$ git branch
* master
   my-work
$ git checkout my-work
   master
* my-work

また, checkoutに-bオプションをつければ, ブランチの作成とチェックアウトを同時にできます.

$ git checkout -b my-work

4. git add / git commit

上記の手順までできていれば, あとはふつうにgitでバージョン管理するようにリポジトリを更新していくだけです. Forkしたリポジトリなのでどんな変更をしようが問題ないですし, トピックブランチ (masterブランチ) があるので, いつでも開始状態に戻ることが可能です.

5. リモートブランチの作成

リポジトリの更新をGitHubのForkしたリポジトリに反映するには, GitHub側にもブランチを作成する必要があります.

$ git push origin my-work
$ git branch -r
 remotes/origin/HEAD -> origin/master
 remotes/origin/my-work
GitHub branch
GitHub branch

ブランチをGitHubにも作成すると, リポジトリのページでbranchの切り替えができるはずです.
そこで, リポジトリを更新したbranchであるmy-workに切り替えると, 更新した内容が反映されているはずです.

6. Pull Request

いよいよ最後の手順です. ここまでの作業は言わば自分だけに影響することだったので, そんなに神経質になる必要もなかったのですが, Pull Requestは更新したリポジトリをFork元のリポジトリの制作者に依頼するわけなので, 少し慎重になりましょう.

Pull Request
Pull Request

Pull Requestをするには, Forkした自分のリポジトリの「Pull Request」ボタンを押します.
すると, Pull Requestを送るためのページに切り替わります.

Create Pull Request
Create Pull Request

テキスト入力の箇所は, Pull Requestをした理由を記載します.

「Commits / File Changed」タブで, Pull Requestに含まれるコミットやファイルの差分を確認できます.

以上を確認して問題がなければ, 「Create pull request」ボタンを押します. これで, Fork元のリポジトリの制作者に通知されます.

あとは,  Fork元のリポジトリの制作者が確認をして問題がなければmergeしてくれて, 自分にもその通知が届きます.

* リポジトリのアップデート

Fork + clone してきたリポジトリのmasterブランチはトピックブランチにしておくとメモしましたが, そのままの状態で最新の状態に保たれるわけではないので, 定期的にアップデートして最新の状態にすることが必要です.

1. アップデート用のリモートリポジトリを作成

アップデート用のリポジトリ名をupstreamとします.

$ git remote add upstream [Fork元のリポジトリ]

ここでのポイントは, Fork元のリポジトリを指定することです. そうでないと, 最新のリポジトリの状態を参照することにならないからです,

2. 更新

更新するために, トピックブランチであるmasterブランチにチェックアウトします.

$ git checkout master

そして, 最新のリポジトリのデータを取得します.

$ git fetch upstream
   remote: Counting objects: 14, done.
   remote: Compressing objects: 100% (12/12), done.
   remote: Total 14 (delta 7), reused 6 (delta 2)
   Unpacking objects: 100% (14/14), done.
   From https://github.com/html5rocks/www.html5rocks.com
   13498ed..2cfc907  master     -> upstream/master
    //... etc

最後に, 取得した最新のリポジトリのデータをトピックブランチ (masterブランチ) にマージします.

$ git merge upstream/master
   Updating 0dd88ed..2cfc907
   Fast-forward
   CALENDAR.md                                        |  2 +-
   content/tutorials/webaudio/intro/en/index.html     |  2 +- 
   content/tutorials/webaudio/intro/ja/index.html     | 35 ++++++++-----
   .../webaudio/intro/static/js/filter-sample.js      |  3 +-
   .../webaudio/positional_audio/ja/index.html        | 58 ++++++++++++----------
    5 files changed, 59 insertions(+), 41 deletions(-)
    // ...etc

ちなみに, 既に最新の状態である場合には, 「Already up-to-date」と表示されます.

$ git merge upstream/master
   Already up-to-date.

以上が, Pull Requestを送る基本となります. 最初は手順が多そうに感じますが, やってみると案外そうでもないです.
Pull Requestは敷居が高そうで実はそうでもなく, でも素晴らしい機能なのでどんどん利用しましょう.