Skip to content

Instantly share code, notes, and snippets.

@akkunchoi
Created November 10, 2010 09:30
Show Gist options
  • Save akkunchoi/670603 to your computer and use it in GitHub Desktop.
Save akkunchoi/670603 to your computer and use it in GitHub Desktop.
Git

Git

基本(とりあえずこれ覚えればOK)

$ git init hoge # git リポジトリを作成。または...
$ git clone [email protected]:myrepo.git # 外部から取得
... some change
$ git add *
$ git commit -m "my commit"
$ git status # 状態を見る
$ git push origin master  # remoteに送信
$ git pull

ログ

http://progit.org/book/ja/ch2-3.html

$ git log -p     # diffも出力する
$ git log --stat # 変更したファイルの一覧
$ git log --pretty=oneline #1行で
$ git log --pretty=format:"%h - %an, %ar : %s" # 独自のフォーマットで
$ git log --since=2.weeks # 日付指定
$ git log -(n) # n件

commit --amend や reset --hard HEAD^^ とかして見えなくなったコミットを確認する

$ git reflog

コミット

直前のコミットをやり直しできる!

$ git commit --amend

直前のコミットをなかった事にして一つ前のコミット状態に戻す

$ git reset --hard HEAD^
$ git reflog # HEAD履歴を確認できる。間違えた場合はそれも戻せる

ステージングの取り消し

$ git reset HEAD hoge.txt

svn revertのようなもの

$ git checkout -- hoge.txt

ブランチ

http://progit.org/book/ja/ch3-1.html HEADは「あなたが作業しているローカルブランチへのポインタ」

testingブランチを作成(切り替えはしない)

$ git branch testing

切り替える

$ git checkout testing

作成して切り替える

$ git checkout -b issue53

マージする 通常はFast forward ポインタを前に進めるだけ。

$ git merge issue53
$ git merge --no-commit issue53 # "Merged branch ..." とコミットされるが、それをしない
$ git merge --no-squash issue53 # 変更をワーキングツリーに適用する。マージもコミットもしない。ブランチ上での履歴は無くなる。
$ git merge --no-ff issue53     # [ToDo]

mergeは二本に分かれた枝を一本に合わせる。 rebaseはmergeとrebaseの違いは後述

$ git rebase master

あるコミットの変更分だけを適用する

$ git cherry-pick {commit}

タグ

タグの一覧

$ git tag

タグを作成

$ git tag v0.1

注釈付きタグの作成(コミットするかどうかの違いらしいが、どう使い分けるのか分からん)

$ git tag -a v1.4 -m 'my version 1.4'

タグの共有 $ git push origin v1.5 $ git push origin --tags # 共有されてないもの全部 $ git push origin :missing_tag # リモートのタグを削除

共有

http://progit.org/book/ja/ch3-5.html

「こっちの serverfix で、リモートの awesomebranch を更新しろ」

$ git push origin serverfix:awesomebranch

$ git push origin master
$ git push # 省略できる

リモートにデータを送信 「こっちの (何もなし) で、向こうの [remotebranch] を更新しろ」 ドッカーン。これでブランチはサーバーから消えてしまいました。

$ git push origin :serverfix

リモートのデータを取得

$ git fetch origin

fetchしたものとマージ

$ git merge origin/master

origin/serverfix が指す先から作業を開始するためのローカルブランチができあがりました。 $ git checkout -b serverfix origin/serverfix

追跡ブランチ: cloneすると自動的に追跡ブランチする。これが引数なしでgit pushやgit pullが動作する理由。

これは同じ意味。

$ git checkout --track origin/serverfix
$ git checkout -b serverfix origin/serverfix

fetch とmergeを自動でやってくれる

$ git pull

リモートブランチを削除しても、別の場所してクローンされてるとずっと残る。追加は自動だけど削除は自動でしてくれない。そういう場合に prune を使う。

# 状態を確認する
$ git remote show origin
$ git remote prune origin

サブモジュール

http://progit.org/book/ja/ch6-6.html

$ git submodule add git://github.com/chneukirchen/rack.git rack

submoduleのあるリポジトリをcloneした後、

$ git submodule init
$ git submodule update

サブモジュールの外部の変更を取り込むには毎回これをやる

$ git merge origin/master
$ git submodule update

サブモジュールはあるポイントしか見ない!!親プロジェクトはそのポイントを記録する

問題点。特定のバージョンをポイントしている(detached head)ので、git submodule updateで手元の変更が失われやすい

.gitmodulesを見ればわかる

git-svn

http://progit.org/book/ja/ch8-1.html http://d.hatena.ne.jp/idesaku/20090323/1237825080

svn checkoutのようなもの svnからgitリポジトリを作成。 -s(standard)オプションはsvnのtrunk/branches/tags構成をそのままインポートする

$ git svn clone file:///tmp/test-svn -s

svnのデータだけ取得

$ git svn fetch

svn upのようなもの svnのデータを取り込む

$ git svn rebase

svn commitのようなもの svnにコミット。gitのコミットIDが書き換わる!注意! コミットできたらgit-svn-id属性が付く。

$ git svn dcommit

git-svnで削除されたリモートブランチをローカルでも削除する方法

$ git branch -r -d my-remote-branch

svnにブランチ作成

$ git svn branch new_branch_name

svnにタグ作成

$ git svn tag new_tag_name

FAQ

  • git-svn dcommit できなかったのでコミットID見たら、違うIDになってた...。

    • patch を作成する

  • ローカルに未コミットの変更があるけどgit-svn-dcommitしたい

    • stashを使う

      $ git stash $ git svn dcommit $ git stash apply

  • svn:externalsのようなことをしたい

  • 空のディレクトリはバージョン管理できない

    • .gitignoreとか何でもいいから空ファイルを作成すればOK。

  • 複数のモジュールを含むSubversionリポジトリをGitへ移行する。http://iteman.jp/blog/2009/02/subversiongit.html

他注意点

  • 部分的なチェックアウトできない
    • svn checkout はパスを指定すればどの階層でもワーキングコピーを作成できる。 git clone すると今までの履歴含め、全てをコピーしなければならない。 なのでプロジェクト/モジュールごとにリポジトリを作成するのがベストだろう。
  • ディレクトリ同士のマージができない。これはどうにもできないかも。
  • trunk, branches, tags
    • Subversionはディレクトリ構造として表現
    • Gitはbranchesとtagsが別のシステムになっている。

パッチ

http://blog.s21g.com/articles/680

直前のコミットとその前との差分でパッチを作成する

$ git format-patch -r HEAD~

パッチを適用する

$ git am 0001-hoge.patch

git merge と git rebaseの違い

masterのHEADはポイントAにあるとする

(master) ---A

Aからブランチしたworkingを作成し、Bまで進める

(master) ---A 
             \
(working)     \----- B

そこからさらに masterでも変更し A' まで進めたとする

(master) -- A ------------ A'
             \
(working)     \----- B

この状態で、

(master) git merge working した場合 A'に B がマージされて C になる。 C の HEAD^(一つ前) は A'

(master) ---A ------------ A' ---- C
             \                   /
(working)     \-----B------------

(master) git rebase working した場合 コミットA'の存在はmasterからはなくなって、 Bからの続きとして AからA'の差分がマージされて A'' になる A'' の HEAD^ は B

First, rewinding head to replay your work on top of it...
Applying: commit B

(master) ---A         ------ A''
             \       /
(working)     \-----B

mergeはブランチの履歴を残して一本にするけど、rebaseすると履歴も含めて一本に作り直す。そのためrebaseは注意が必要。

その他

コンフリクト状態が残ってしまった場合

$ git pull
You have not concluded your merge (MERGE_HEAD exists).
Please, commit your changes before you can merge

$ git reset --merge

git pullでremoteを自動的に指定

(master) $ git pull

You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me, either. Please
specify which branch you want to use on the command line and
try again (e.g. 'git pull <repository> <refspec>').
See git-pull(1) for details.

If you often merge with the same branch, you may want to
use something like the following in your configuration file:

    [branch "master"]
    remote = <nickname>
    merge = <remote-ref>
    
    [remote "<nickname>"]
    url = <url>
    fetch = <refspec>

See git-config(1) for details.

# 手動で指定
(master) $ git pull origin master

# configで指定
$ vi .git/config

[branch "master"]
    remote = origin
    merge = refs/heads/master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment