facebook twitter hatena line email

「Git/コマンド」の版間の差分

提供: 初心者エンジニアの簡易メモ
移動: 案内検索
(git pushがnon-fast-forwardエラーとなりpushできない際)
(wip運用)
 
(同じ利用者による、間の87版が非表示)
行1: 行1:
 +
==gitのヘルプ==
 +
<pre>
 +
$ git help
 +
$ git clone --help
 +
      git clone [--template=<template_directory>]
 +
                [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
 +
                [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
 +
                [--dissociate] [--separate-git-dir <git dir>]
 +
                [--depth <depth>] [--[no-]single-branch] [--no-tags]
 +
                [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
 +
                [--[no-]remote-submodules] [--jobs <n>] [--sparse]
 +
                [--filter=<filter>] [--] <repository>
 +
                [<directory>]
 +
$ git checkout --help
 +
      git checkout [-q] [-f] [-m] [<branch>]
 +
      git checkout [-q] [-f] [-m] --detach [<branch>]
 +
      git checkout [-q] [-f] [-m] [--detach] <commit>
 +
      git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
 +
      git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...
 +
      git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]
 +
      git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>...]
 +
</pre>
 +
 
==gitクローン作成==
 
==gitクローン作成==
 
  $ git clone ssh://user1@localhost/var/git/project1.git project1
 
  $ git clone ssh://user1@localhost/var/git/project1.git project1
 +
 +
==gitクローン作成時にブランチ指定==
 +
$ git clone -b branch1 ssh://user1@localhost/var/git/project1.git project1
  
 
==gitのインデックスに追加する場合==
 
==gitのインデックスに追加する場合==
行48: 行74:
 
  * master
 
  * master
 
  develop
 
  develop
 +
 +
==ブランチ切り替え==
 +
$ git checkout develop
 +
$ git branch
 +
>  master
 +
> * develop
  
 
==ブランチのマージ==
 
==ブランチのマージ==
行53: 行85:
 
  $ git checkout master
 
  $ git checkout master
 
  $ git merge develop
 
  $ git merge develop
 +
 +
==ブランチのマージで競合(Conflict)が発生した場合==
 +
$ git status # Conflictファイル確認
 +
$ vi file1.php
 +
$ git add file1.php # 修正したConflictを追加
 +
$ git status # 一旦確認
 +
$ git commit -a # mergeコメント確認&"wq!"でmerge
 +
$ git log # log確認
 +
 +
==conflictのHEADの位置==
 +
masterブランチにmaster行を追加して、subブランチにsubsub行を追加して、
 +
subブランチにmasterブランチを取り込んだときの競合の例
 +
<pre>
 +
taro
 +
jiro
 +
saburo
 +
<<<<<<< HEAD
 +
subsub
 +
=======
 +
master
 +
>>>>>>> master
 +
siro
 +
goro
 +
</pre>
 +
現在ブランチがHEADで、別途、取り込み元のブランチ名(master)が記述されるっぽい。
  
 
==ローカルブランチ削除==
 
==ローカルブランチ削除==
行78: 行135:
 
remote branchが古いので以下で更新する
 
remote branchが古いので以下で更新する
 
  $ git fetch
 
  $ git fetch
 +
 +
===リモートブランチ(タグを)ローカルに===
 +
git checkout -b v.1.0.0 refs/tags/v.1.0.0
  
 
==タグ作成==
 
==タグ作成==
  git tag -a v1.0
+
  git tag -a v.1.0.0
  
 
==タグリスト==
 
==タグリスト==
 
  $ git tag
 
  $ git tag
  v1.0
+
  v.1.0.0
 +
 
 +
==作成したタグpush==
 +
git push origin v.1.0.0
  
 
==タグ削除==
 
==タグ削除==
  git tag -d v1.0
+
  git tag -d v.1.0.0
  
 
==タグ削除(リモート)==
 
==タグ削除(リモート)==
  git push origin :v1.0
+
  git push origin :v.1.0.0
  
 
==タグcheckout==
 
==タグcheckout==
  git checkout v1.0
+
  git checkout v.1.0.0
 
+
==作成したタグpush==
+
git push origin v1.0
+
  
 
==エクスポート==
 
==エクスポート==
行128: 行188:
 
以下コマンドで対応
 
以下コマンドで対応
 
  $ git config branch.master.remote origin
 
  $ git config branch.master.remote origin
 +
==git pullをrebaseで取得==
 +
developブランチをリベースで取得する例
 +
git pull --rebase origin develop
 +
rebaseでpullすると、merge時のログが増えない。
 +
 +
参考:https://qiita.com/dys/items/c062b1be0d0287352e37
  
 
==gitデフォユーザ設定==
 
==gitデフォユーザ設定==
  $ git config --global user.name="sampleuser"
+
  $ git config --global user.name "sampleuser"
  $ git config --global user.email="sampleuser@example.com"
+
  $ git config --global user.email "sampleuser@example.com"
 +
 
 +
==gitのリポジトリ内のみのローカルユーザ設定&確認==
 +
$ git config --local user.name "sampleuser"
 +
$ git config --local user.email "sampleuser@example.com"
 +
 
 +
==gitデフォユーザ設定をテキストで変更==
 +
$ vi ~/.gitconfig
 +
<pre>
 +
[user]
 +
    name = sampleuser
 +
    email = sampleuser@example.com
 +
</pre>
 +
 
 +
==gitのリポジトリ内のみのローカルユーザ設定をテキストで変更==
 +
$ vi ./.git/config
 +
<pre>
 +
[user]
 +
    name = sampleuser
 +
    email = sampleuser@example.com
 +
</pre>
  
 
==gitコンフィグ確認==
 
==gitコンフィグ確認==
行143: 行229:
 
  $ git log --name-status --since="2013-07-10 10:10:10" | grep '^M' | grep -v '^Merge' | cut -f 2
 
  $ git log --name-status --since="2013-07-10 10:10:10" | grep '^M' | grep -v '^Merge' | cut -f 2
 
  $ git log --name-status --since="2013-07-10 10:10:10" | grep '^A' | grep -v '^Author' | cut -f 2
 
  $ git log --name-status --since="2013-07-10 10:10:10" | grep '^A' | grep -v '^Author' | cut -f 2
 +
$ git log -- Assets/Main/Main.cs # ファイル削除ログ
  
 
==git差分確認==
 
==git差分確認==
行148: 行235:
 
  $ git show [リビジョンid] test.php #1ファイルのコード差分
 
  $ git show [リビジョンid] test.php #1ファイルのコード差分
 
  $ git show [リビジョンid] --name-only #ファイルだけ
 
  $ git show [リビジョンid] --name-only #ファイルだけ
 +
 +
==git過去ファイル確認==
 +
$ git show [リビジョンid]:test.php
  
 
==gitブランチ比較==
 
==gitブランチ比較==
 
  git diff develop
 
  git diff develop
 
  git diff develop --name-only # ファイル名のみ
 
  git diff develop --name-only # ファイル名のみ
 +
 +
==gitリビジョン間比較==
 +
git diff [リビジョンid1] [リビジョンid2]
 +
 +
==gitのsjis比較==
 +
$ vi .gitattributes
 +
*.* diff=sjis
 +
$ git config diff.sjis.textconv "iconv -f sjis"
 +
 +
参考:https://qiita.com/matsuoshi/items/c93a0b55df827a28514e
 +
 +
==gitの差分の拡張子フィルタ==
 +
cs拡張子だけの差分を確認したいとき
 +
git diff "*.cs"
  
 
==gitで管理しないdir指定方法==
 
==gitで管理しないdir指定方法==
行202: 行306:
 
  # 競合を直す
 
  # 競合を直す
 
  git add -u
 
  git add -u
 +
 +
==複数のコミットを1つに結合する==
 +
新しいコミットを古いコミットに結合する。
 +
 +
直近2件結合の場合
 +
git rebase -i HEAD~2
 +
直近3件結合の場合
 +
git rebase -i HEAD~3
 +
 +
古いコミット順に表示される
 +
pick 20d14a0 コメント1
 +
pick ed3cf5f コメント2
 +
pick 5892c4c コメント3
 +
 +
pickをfixup(もしくは f)へ変更する。一番古い結合元の1つはpickのまま(ちなみに、新しいコミットに古いコミットを結合するとエラーとなるので注意)
 +
 +
pick 20d14a0 コメント1
 +
fixup ed3cf5f コメント2
 +
fixup 5892c4c コメント3
 +
 +
保存すると初回コミットに結合され、2、3件目のコメントは削除される。
 +
 +
$ git log
 +
コメント1
 +
 +
途中でやめる場合(masterブランチに戻る)
 +
rm -fr "/d/ssh/.git/rebase-merge"
 +
git checkout master
 +
 +
既に別コミットでpushしていれば、強制pushしないとエラーとなる。他の人が取得する前のbranchかどうかを確認しておく。
 +
git push -f origin branch1
 +
 +
参考:https://dev.classmethod.jp/tool/git/git-rebase-fixup/
 +
 +
古いコミットに新しいコミットを結合した場合は以下エラーが出る
 +
Cannot 'fixup' without a previous commit
 +
以下コマンドで戻す
 +
git rebase --abort
 +
 +
参考:https://note.mu/engineer_memo/n/n9b4c87557ab2
 +
 +
===squashの場合===
 +
squashの場合は、ログがマージされ残る
 +
 +
直近3件結合の場合
 +
git rebase -i HEAD~3
 +
 +
pickをsquashもしくはsに変更
 +
pick 20d14a0 コメント1
 +
s ed3cf5f コメント2
 +
s 5892c4c コメント3
 +
 +
$ git log
 +
コメント1
 +
コメント2
 +
コメント3
 +
 +
参考:https://www.changesworlds.com/blog/2015/03/git-rebase-squash/
 +
 +
===You are currently editing a commit while rebasing branchが出る場合===
 +
rebaseを中断してよいのであれば、
 +
git rebase --quit
 +
 +
===rebaseのログ===
 +
$ git reflog
 +
<pre>
 +
9bc59b7 (HEAD -> develop_rebase) HEAD@{0}: rebase (finish): returning to refs/heads/develop_rebase
 +
9bc59b7 (HEAD -> develop_rebase) HEAD@{1}: rebase (squash): コメント1
 +
d03690c HEAD@{2}: rebase (squash): # This is a combination of 2 commits.
 +
991315d HEAD@{3}: rebase (start): checkout HEAD~3
 +
</pre>
 +
 +
ローカルのgit内にlogはあるが、一度.gitを消すと、rebaseのログは、消える。
 +
 +
==1つ前のコミット日時を修正==
 +
現状ログ確認
 +
<pre>
 +
$ git log --pretty=fuller
 +
commit 5ed7400b80421a4e8b7ffd0757bb865158e3efd7
 +
Author:    macmac <mac1>
 +
AuthorDate: Wed Oct 28 14:46:38 2020 +0900
 +
Commit:    macmac <mac1>
 +
CommitDate: Wed Oct 28 14:46:38 2020 +0900
 +
</pre>
 +
 +
変更
 +
$ git commit --amend --date="Tue Dec 6 16:43:33 2022 +0900"
 +
 +
CommetDateをAuthorDateに合わせて修正
 +
$ git rebase HEAD~1 --committer-date-is-author-date
 +
 +
参考:https://blog.zzzmisa.com/git_commit_date/
 +
 +
==2つ以上前のコミット日時を修正==
 +
$ git rebase -i HEAD~3
 +
 +
pickをeditに変更
 +
<pre>
 +
pick 5ed7400 hoge
 +
pick abd6e83 a add
 +
pick d62e81c aaaaa
 +
 +
edit 5ed7400 hoge
 +
edit abd6e83 a add
 +
edit d62e81c aaaaa
 +
</pre>
 +
古いものから設定していく。
 +
<pre>
 +
$ git commit --amend --date="Wed Oct 28 10:43:33 2020 +0900"
 +
$ git rebase --continue
 +
$ git commit --amend --date="Wed Oct 28 11:43:33 2020 +0900"
 +
$ git rebase --continue
 +
$ git commit --amend --date="Wed Oct 28 12:43:33 2020 +0900"
 +
$ git rebase --continue
 +
</pre>
 +
 +
CommetDateをAuthorDateに合わせて修正
 +
$ git rebase HEAD~3 --committer-date-is-author-date
 +
 +
曜日一覧
 +
<pre>
 +
日 Sun
 +
月 Mon
 +
火 Tue
 +
水 Wed
 +
木 Thu
 +
金 Fri
 +
土 Sat
 +
</pre>
 +
 +
==1つ前のコミッター名を修正==
 +
<pre>
 +
$ git log --pretty=fuller
 +
commit 5ed7400b80421a4e8b7ffd0757bb865158e3efd7
 +
Author:    macmac <mac1>
 +
AuthorDate: Wed Oct 28 14:46:38 2020 +0900
 +
Commit:    macmac <mac1>
 +
CommitDate: Wed Oct 28 14:46:38 2020 +0900
 +
</pre>
 +
 +
AuthorとCommitが変更される。
 +
$ git commit --amend --author="macmac1 <macmac1>"
 +
 +
CommetDateをAuthorDateに合わせて修正
 +
$ git rebase HEAD~1 --committer-date-is-author-date
 +
 +
参考:https://yoshinorin.net/2018/11/16/update-git-author-and-date/
 +
 +
==2つ以上前のコミッター名を修正==
 +
<pre>
 +
$ git rebase -i HEAD~3
 +
</pre>
 +
pickをeditに変更。
 +
</pre>
 +
 +
<pre>
 +
edit 1f002c9f 333です
 +
edit bdabb172 222です
 +
edit 517bf38e 111です
 +
 +
edit 1f002c9f 333です
 +
edit bdabb172 222です
 +
edit 517bf38e 111です
 +
</pre>
 +
 +
<pre>
 +
$ git commit --amend --author="macmac1 <macmac1>"
 +
$ git rebase --continue
 +
$ git commit --amend --author="macmac1 <macmac1>"
 +
$ git rebase --continue
 +
$ git commit --amend --author="macmac1 <macmac1>"
 +
$ git rebase --continue
 +
</pre>
 +
 +
CommetDateをAuthorDateに合わせて修正
 +
$ git rebase HEAD~3 --committer-date-is-author-date
  
 
==git_cloneが重くなった場合==
 
==git_cloneが重くなった場合==
 
ダンプなどの重いdataをcommitした場合は重くなるので履歴から削除
 
ダンプなどの重いdataをcommitした場合は重くなるので履歴から削除
 
  git filter-branch --tree-filter 'rm -fr db/hoge_dump.tar.gz';
 
  git filter-branch --tree-filter 'rm -fr db/hoge_dump.tar.gz';
 +
 +
==git_cloneを少しづつDL==
 +
最初の履歴を1つつけてclone
 +
  git clone --depth 1 git@bitbucket.org:user1/project1.git
 +
少しづつ履歴を増やしてく
 +
git fetch --depth 100
 +
参考:https://qiita.com/yasshcy/items/bd96469f4f30c0e57312
  
 
==コミット処理を戻す==
 
==コミット処理を戻す==
行219: 行506:
  
 
ちなみにmerge部分を"-m"オプションを使わずに利用しようとするとエラーとなる
 
ちなみにmerge部分を"-m"オプションを使わずに利用しようとするとエラーとなる
  git revert [リビジョンid]
+
  git revert [リビジョンid]
 
  error: Commit  [リビジョンid] is a merge but no -m option was given.
 
  error: Commit  [リビジョンid] is a merge but no -m option was given.
 +
 +
==merge途中でやっぱり戻す場合==
 +
コンフリクト修正前
 +
git merge --abort
 +
コンフリクト修正途中
 +
git reset --hard HEAD
 +
参考:https://qiita.com/chihiro/items/5dd671aa6f1c332986a7
  
 
==branchを指定してcloneする==
 
==branchを指定してcloneする==
 
  git clone -b develop ssh://user1@localhost/var/git/project1.git project1
 
  git clone -b develop ssh://user1@localhost/var/git/project1.git project1
 +
 +
==その時点のコミットハッシュのソースを取得==
 +
コミットハッシュを指定してブランチを作成
 +
git checkout 1234123412341234123412341234123411234567 -b feature/newbranch1
  
 
==ロールバック(ファイルも戻す)==
 
==ロールバック(ファイルも戻す)==
行244: 行542:
 
参考
 
参考
 
https://teratail.com/questions/58184
 
https://teratail.com/questions/58184
 +
 +
==別リポジトリのリビジョンをcherry-pickで追加する方法==
 +
cherry-pickで追加したいリポジトリ内
 +
<pre>
 +
git remote add FIX_REPOSITORY [リポジトリURL]
 +
git fetch FIX_REPOSITORY
 +
git cherry-pick [リビジョンid]
 +
</pre>
 +
 +
参考:https://qiita.com/takeoverjp/items/befdcd616374cf6e0a3b
 +
 +
===追加したリポジトリ削除===
 +
git remote rm FIX_REPOSITORY
 +
 +
===追加したリポジトリにブランチを切り替える===
 +
git checkout -b FIX_REPOSITORY-master FIX_REPOSITORY/master
 +
 +
===追加したリポジトリをcommitした場合のpushの仕方===
 +
git push FIX_REPOSITORY FIX_REPOSITORY-master:master
 +
 +
参考:https://qiita.com/takeoverjp/items/befdcd616374cf6e0a3b
  
 
==コンフリクト解消ツール==
 
==コンフリクト解消ツール==
行269: 行588:
 
リビジョンidから現在までの一覧が以下記述とともにエディタで開く
 
リビジョンidから現在までの一覧が以下記述とともにエディタで開く
 
以下のようにpickをeditに変更する
 
以下のようにpickをeditに変更する
 +
 
変更前
 
変更前
 
  pick af2a169 dev_1
 
  pick af2a169 dev_1
行285: 行605:
 
  git rebase -i HEAD~3
 
  git rebase -i HEAD~3
 
以下のようにpickをsquashに変更する
 
以下のようにpickをsquashに変更する
 +
 
変更前
 
変更前
 
  pick d75ebc5 dev_4
 
  pick d75ebc5 dev_4
 
  pick 3c59fef dev_5
 
  pick 3c59fef dev_5
 
  pick f387ef3 dev_6
 
  pick f387ef3 dev_6
 +
 
変更後
 
変更後
 
  pick d75ebc5 dev_4
 
  pick d75ebc5 dev_4
 
  squash 3c59fef dev_5
 
  squash 3c59fef dev_5
 
  squash f387ef3 dev_6
 
  squash f387ef3 dev_6
 +
 +
コミット
 +
git commit --amend
 +
 +
"Interactive rebase already started"エラーが出てしまうときは以下コマンドで取り消す
 +
$ git rebase --abort
  
 
==コミット内容を修正する==
 
==コミット内容を修正する==
 
  git rebase -i HEAD~3
 
  git rebase -i HEAD~3
 
以下のようにpickをsquashに変更する
 
以下のようにpickをsquashに変更する
 +
 
変更前
 
変更前
 
  pick d75ebc5 dev_4
 
  pick d75ebc5 dev_4
行316: 行645:
  
 
==gitログ検索==
 
==gitログ検索==
  git log --stat -S hogehoge
+
  git log --grep=hogehoge
 +
 
 +
==git差分をlogから検索==
 +
git log hogehoge.java | grep commit | awk '{ print $2 }' | xargs -IXXX git show XXX hogehoge.java
 +
vimが開くので/piyopiyoなどで文字列検索
 +
 
 +
==gitログのコミット者から検索==
 +
git log | grep taro -A 3 -B 1
 +
前1後3行も合わせて表示
  
 
==全ての過去コミット一覧==
 
==全ての過去コミット一覧==
 
  git reflog  
 
  git reflog  
 
rebaseやcherry-pickなどのログも表示される
 
rebaseやcherry-pickなどのログも表示される
 +
 +
==dirの作成がかぶった場合==
 +
競合はしない。
 +
 +
==gitサイズ==
 +
<pre>
 +
$ git count-objects -vH
 +
count: 3204
 +
size: 128.04 MiB
 +
in-pack: 15597
 +
packs: 5
 +
size-pack: 623.93 MiB
 +
prune-packable: 322
 +
garbage: 0
 +
size-garbage: 0 bytes
 +
</pre>
 +
==プロジェクト内で別gitプロジェクト管理(submodule)==
 +
sampleprojectに別プロジェクト(samplelibrary)を追加
 +
git clone --recursive git@hosting:[user1]/sampleproject.git
 +
git submodule add git@hosting:[user1]/samplelibrary.git
 +
cd samplelibrary
 +
git submodule init
 +
git submodule update
 +
 +
改めて別の場所にcloneするとlibraryは取ってこれない・・・
 +
git clone git@hosting:[user1]/sampleproject.git
 +
 +
改めて別の場所に別プロジェクトごとcloneするときはrecursiveオプションを追加する
 +
git clone --recursive git@hosting:[user1]/sampleproject.git
 +
 +
参考:https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB
  
 
==wip運用==
 
==wip運用==
 
*空でcommitできる
 
*空でcommitできる
 
*作業前branchとしてcommitする
 
*作業前branchとしてcommitする
  git commit --allow-empty -m "[WIP] 追加機能"
+
  git commit --allow-empty -m "WIP: 追加機能"
  
 
==参考gitサイト==
 
==参考gitサイト==
 
Gitでやらかした時に使える19個の奥義 http://qiita.com/muran001/items/dea2bbbaea1260098051
 
Gitでやらかした時に使える19個の奥義 http://qiita.com/muran001/items/dea2bbbaea1260098051

2024年11月27日 (水) 18:57時点における最新版

目次

gitのヘルプ

$ git help
$ git clone --help
       git clone [--template=<template_directory>]
                 [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror]
                 [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>]
                 [--dissociate] [--separate-git-dir <git dir>]
                 [--depth <depth>] [--[no-]single-branch] [--no-tags]
                 [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules]
                 [--[no-]remote-submodules] [--jobs <n>] [--sparse]
                 [--filter=<filter>] [--] <repository>
                 [<directory>]
$ git checkout --help
       git checkout [-q] [-f] [-m] [<branch>]
       git checkout [-q] [-f] [-m] --detach [<branch>]
       git checkout [-q] [-f] [-m] [--detach] <commit>
       git checkout [-q] [-f] [-m] [[-b|-B|--orphan] <new_branch>] [<start_point>]
       git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <pathspec>...
       git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] --pathspec-from-file=<file> [--pathspec-file-nul]
       git checkout (-p|--patch) [<tree-ish>] [--] [<pathspec>...]

gitクローン作成

$ git clone ssh://user1@localhost/var/git/project1.git project1

gitクローン作成時にブランチ指定

$ git clone -b branch1 ssh://user1@localhost/var/git/project1.git project1

gitのインデックスに追加する場合

全てのファイル

$ git add .

新しく作成されたファイルも含めるとき

$ git add -A

ローカルの変更を元に戻す場合

$ git checkout file1

全ての場合

$ git checkout .

全ソースをある地点まで戻す

git checkout リビジョンid
git pull origin master // 戻した後、ソースを最新にする場合

git pushがnon-fast-forwardエラーとなりpushできない際

push先の子孫でない場合発生

$ git merge origin master

を実行してからpush

もしくは強制的に・・(これは他の人に怒られる。複数人でやってなければok)

$ git push --force

削除したファイルをコミットするには

$ git add -u
$ git commit

コミット時の差分確認

git commit -v

現在のブランチ確認

$ git branch
* master

現在のブランチ確認(リモートも含める場合

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

ブランチ作成

$ git branch develop
$ git branch
* master
develop

ブランチ切り替え

$ git checkout develop
$ git branch
>   master
> * develop

ブランチのマージ

ブランチをマスターにしてからdevelopブランチをマージ

$ git checkout master
$ git merge develop

ブランチのマージで競合(Conflict)が発生した場合

$ git status # Conflictファイル確認
$ vi file1.php
$ git add file1.php # 修正したConflictを追加
$ git status # 一旦確認
$ git commit -a # mergeコメント確認&"wq!"でmerge
$ git log # log確認

conflictのHEADの位置

masterブランチにmaster行を追加して、subブランチにsubsub行を追加して、 subブランチにmasterブランチを取り込んだときの競合の例

taro
jiro
saburo
<<<<<<< HEAD
subsub
=======
master
>>>>>>> master
siro
goro

現在ブランチがHEADで、別途、取り込み元のブランチ名(master)が記述されるっぽい。

ローカルブランチ削除

$ git branch -d develop

ローカルブランチ削除時にerror: The branch '〜' is not fully mergedのエラーが発生した場合

マージされてないものを含んでいるブランチを消そうとしたときに発生する

消しても問題なければ以下で消せる

$ git branch -D develop

ブランチをpush

$ git branch develop
$ git push origin develop

リモートブランチをローカルに

$ git branch develop origin/develop

(注意)pullするのは危険(現在自分がみているブランチにマージされる恐れがある

別の方法としてcheckout -bでもできる。hotfix例

$ git checkout -b hotfix/kinou1 origin/hotfix/kinou1

以下エラーが出る場合

fatal: Cannot update paths and switch to branch 'hotfix/kinou1' at the same time.

remote branchが古いので以下で更新する

$ git fetch

リモートブランチ(タグを)ローカルに

git checkout -b v.1.0.0 refs/tags/v.1.0.0

タグ作成

git tag -a v.1.0.0

タグリスト

$ git tag
v.1.0.0

作成したタグpush

git push origin v.1.0.0

タグ削除

git tag -d v.1.0.0

タグ削除(リモート)

git push origin :v.1.0.0

タグcheckout

git checkout v.1.0.0

エクスポート

svn exportと同じ(ファイルだけ出力したいとき

$ git archive [branchname] | tar -x -C [filename]
$ git archive master | tar -x -C /var/www/project1

コミット日付をタイムスタンプに復元

for FILE in `git ls-files`; do
  TIME=`git log --pretty=format:%ci -n1 $FILE`
  echo $TIME'\t'$FILE
  STAMP=`date -d "$TIME" +"%y%m%d%H%M.%S"`
  touch -t $STAMP $FILE
done

参考:http://d.hatena.ne.jp/iww/20121011/pretty

コミット日付をタイムスタンプに復元(例:テンプレのみ

for FILE in `git ls-files`; do
  if [[ "$FILE" =~ ^public|fuel/app/views|fuel/app/themes ]]; then
    TIME=`git log --pretty=format:%ci -n1 $FILE`
    echo $TIME'\t'$FILE
    STAMP=`date -d "$TIME" +"%y%m%d%H%M.%S"`
    touch -t $STAMP $FILE
  fi
done

git pull時のエラー

You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in

以下コマンドで対応

$ git config branch.master.remote origin

git pullをrebaseで取得

developブランチをリベースで取得する例

git pull --rebase origin develop

rebaseでpullすると、merge時のログが増えない。

参考:https://qiita.com/dys/items/c062b1be0d0287352e37

gitデフォユーザ設定

$ git config --global user.name "sampleuser"
$ git config --global user.email "sampleuser@example.com"

gitのリポジトリ内のみのローカルユーザ設定&確認

$ git config --local user.name "sampleuser"
$ git config --local user.email "sampleuser@example.com"

gitデフォユーザ設定をテキストで変更

$ vi ~/.gitconfig
[user]
    name = sampleuser
    email = sampleuser@example.com

gitのリポジトリ内のみのローカルユーザ設定をテキストで変更

$ vi ./.git/config
[user]
    name = sampleuser
    email = sampleuser@example.com

gitコンフィグ確認

$ git config --list

git履歴一覧

$ git log
$ git log --stat # ファイル名一覧付き
$ git log --name-status # ファイル名一覧付き M A D付き
$ git log --since=2013-07-10 --until=2013-07-16 # 期間指定
$ git log --name-status --since="2013-07-10 10:10:10" | grep '^M' | grep -v '^Merge' | cut -f 2
$ git log --name-status --since="2013-07-10 10:10:10" | grep '^A' | grep -v '^Author' | cut -f 2
$ git log -- Assets/Main/Main.cs # ファイル削除ログ

git差分確認

$ git show [リビジョンid]
$ git show [リビジョンid] test.php #1ファイルのコード差分
$ git show [リビジョンid] --name-only #ファイルだけ

git過去ファイル確認

$ git show [リビジョンid]:test.php

gitブランチ比較

git diff develop
git diff develop --name-only # ファイル名のみ

gitリビジョン間比較

git diff [リビジョンid1] [リビジョンid2]

gitのsjis比較

$ vi .gitattributes
*.* diff=sjis
$ git config diff.sjis.textconv "iconv -f sjis"

参考:https://qiita.com/matsuoshi/items/c93a0b55df827a28514e

gitの差分の拡張子フィルタ

cs拡張子だけの差分を確認したいとき

git diff "*.cs"

gitで管理しないdir指定方法

.gitignoreをトップdirにおき無視ファイルを記載

$ vi .gitignore
*~
*.bak
Thumbs.db
desktop.ini
.DS_Store
.buildpath
.project
.settings
*.tmproj
fuel/app/logs/*/*/*
fuel/app/cache/*/*
build
nbproject/
.idea
logs/*
# .svnディレクトリ無視
.svn
*.swp

.gitignoreに追加したと同時に無視設定が反映される

空のdirを管理する

空dir内に.gitkeepファイルを作成

$ touch .gitkeep

(no branch)にコミットしたログをマージ

$ git branch # とすると以下のように表示される場合
* (no branch)
  master
$ git checkout master # masterブランチに戻る
> 2516532 readme記述 # などとコミットログが出力される
$ git merge 2516532 #マージする

Previous HEAD position was 923c794... result文言修正

gitログ削除

直近ログ削除なら問題ないが、昔のログ削除は競合しまくって難しいかも。

$ git rebase -i 103b8e948f1fee1e5b024cd444e46dee0d6f0057 # 最もさかのぼりたい過去のコミットを記述
pick 6896fde gitignore修正
pick 630644c version置換対応
pick e12c899 dbダンプ最新
# ↑削除したいものだけddで削除する
git rebase --continue
git status
# 競合を直す
git add -u

複数のコミットを1つに結合する

新しいコミットを古いコミットに結合する。

直近2件結合の場合

git rebase -i HEAD~2

直近3件結合の場合

git rebase -i HEAD~3

古いコミット順に表示される

pick 20d14a0 コメント1
pick ed3cf5f コメント2
pick 5892c4c コメント3

pickをfixup(もしくは f)へ変更する。一番古い結合元の1つはpickのまま(ちなみに、新しいコミットに古いコミットを結合するとエラーとなるので注意)

pick 20d14a0 コメント1
fixup ed3cf5f コメント2
fixup 5892c4c コメント3

保存すると初回コミットに結合され、2、3件目のコメントは削除される。

$ git log
コメント1

途中でやめる場合(masterブランチに戻る)

rm -fr "/d/ssh/.git/rebase-merge"
git checkout master

既に別コミットでpushしていれば、強制pushしないとエラーとなる。他の人が取得する前のbranchかどうかを確認しておく。

git push -f origin branch1

参考:https://dev.classmethod.jp/tool/git/git-rebase-fixup/

古いコミットに新しいコミットを結合した場合は以下エラーが出る

Cannot 'fixup' without a previous commit

以下コマンドで戻す

git rebase --abort

参考:https://note.mu/engineer_memo/n/n9b4c87557ab2

squashの場合

squashの場合は、ログがマージされ残る

直近3件結合の場合

git rebase -i HEAD~3

pickをsquashもしくはsに変更

pick 20d14a0 コメント1
s ed3cf5f コメント2
s 5892c4c コメント3
$ git log
コメント1
コメント2
コメント3

参考:https://www.changesworlds.com/blog/2015/03/git-rebase-squash/

You are currently editing a commit while rebasing branchが出る場合

rebaseを中断してよいのであれば、

git rebase --quit

rebaseのログ

$ git reflog
9bc59b7 (HEAD -> develop_rebase) HEAD@{0}: rebase (finish): returning to refs/heads/develop_rebase
9bc59b7 (HEAD -> develop_rebase) HEAD@{1}: rebase (squash): コメント1
d03690c HEAD@{2}: rebase (squash): # This is a combination of 2 commits.
991315d HEAD@{3}: rebase (start): checkout HEAD~3

ローカルのgit内にlogはあるが、一度.gitを消すと、rebaseのログは、消える。

1つ前のコミット日時を修正

現状ログ確認

$ git log --pretty=fuller
commit 5ed7400b80421a4e8b7ffd0757bb865158e3efd7
Author:     macmac <mac1>
AuthorDate: Wed Oct 28 14:46:38 2020 +0900
Commit:     macmac <mac1>
CommitDate: Wed Oct 28 14:46:38 2020 +0900

変更

$ git commit --amend --date="Tue Dec 6 16:43:33 2022 +0900"

CommetDateをAuthorDateに合わせて修正

$ git rebase HEAD~1 --committer-date-is-author-date

参考:https://blog.zzzmisa.com/git_commit_date/

2つ以上前のコミット日時を修正

$ git rebase -i HEAD~3

pickをeditに変更

pick 5ed7400 hoge
pick abd6e83 a add
pick d62e81c aaaaa
↓
edit 5ed7400 hoge
edit abd6e83 a add
edit d62e81c aaaaa

古いものから設定していく。

$ git commit --amend --date="Wed Oct 28 10:43:33 2020 +0900"
$ git rebase --continue
$ git commit --amend --date="Wed Oct 28 11:43:33 2020 +0900"
$ git rebase --continue
$ git commit --amend --date="Wed Oct 28 12:43:33 2020 +0900"
$ git rebase --continue

CommetDateをAuthorDateに合わせて修正

$ git rebase HEAD~3 --committer-date-is-author-date

曜日一覧

日 Sun
月 Mon
火 Tue
水 Wed
木 Thu
金 Fri	
土 Sat

1つ前のコミッター名を修正

$ git log --pretty=fuller
commit 5ed7400b80421a4e8b7ffd0757bb865158e3efd7
Author:     macmac <mac1>
AuthorDate: Wed Oct 28 14:46:38 2020 +0900
Commit:     macmac <mac1>
CommitDate: Wed Oct 28 14:46:38 2020 +0900

AuthorとCommitが変更される。

$ git commit --amend --author="macmac1 <macmac1>"

CommetDateをAuthorDateに合わせて修正

$ git rebase HEAD~1 --committer-date-is-author-date

参考:https://yoshinorin.net/2018/11/16/update-git-author-and-date/

2つ以上前のコミッター名を修正

$ git rebase -i HEAD~3

pickをeditに変更。 </pre>

edit 1f002c9f 333です
edit bdabb172 222です
edit 517bf38e 111です
↓
edit 1f002c9f 333です
edit bdabb172 222です
edit 517bf38e 111です
$ git commit --amend --author="macmac1 <macmac1>"
$ git rebase --continue
$ git commit --amend --author="macmac1 <macmac1>"
$ git rebase --continue
$ git commit --amend --author="macmac1 <macmac1>"
$ git rebase --continue

CommetDateをAuthorDateに合わせて修正

$ git rebase HEAD~3 --committer-date-is-author-date

git_cloneが重くなった場合

ダンプなどの重いdataをcommitした場合は重くなるので履歴から削除

git filter-branch --tree-filter 'rm -fr db/hoge_dump.tar.gz';

git_cloneを少しづつDL

最初の履歴を1つつけてclone

 git clone --depth 1 git@bitbucket.org:user1/project1.git

少しづつ履歴を増やしてく

git fetch --depth 100

参考:https://qiita.com/yasshcy/items/bd96469f4f30c0e57312

コミット処理を戻す

git revert [リビジョンid]

実行すると戻し修正されて、commitされるので注意。 (競合するとcommitはされない)

mergeコミット処理を戻す

git revert -m 1 [リビジョンid]
-m 1 はマージされた側のオプション(基本はこちらだと思う)
-m 2 はマージした側のオプション

ちなみにmerge部分を"-m"オプションを使わずに利用しようとするとエラーとなる

git revert [リビジョンid]
error: Commit  [リビジョンid] is a merge but no -m option was given.

merge途中でやっぱり戻す場合

コンフリクト修正前

git merge --abort

コンフリクト修正途中

git reset --hard HEAD

参考:https://qiita.com/chihiro/items/5dd671aa6f1c332986a7

branchを指定してcloneする

git clone -b develop ssh://user1@localhost/var/git/project1.git project1

その時点のコミットハッシュのソースを取得

コミットハッシュを指定してブランチを作成

git checkout 1234123412341234123412341234123411234567 -b feature/newbranch1

ロールバック(ファイルも戻す)

git reset --hard [リビジョンid]

指定したリビジョンidが最後にコミットがされた状態まで全体ソースが戻る(ログも全て戻る)

(注)ロールバック前にpushしてしまっていると、ロールバック後にpushができなくなる(別ブランチに変えればpush出来る)

ロールバックで消えた部分はpushでリモート側へは渡されない。

ロールバック(ファイルは維持)

git reset --soft [リビジョンid]

指定したリビジョンIDが最後にコミットがされた状態までログが戻る(ソースは維持)

別ブランチ(同じブランチでもOK)のリビジョンを追加コミットする方法

git cherry-pick [リビジョンid]

過去dateでコミットが追加される

参考 https://teratail.com/questions/58184

別リポジトリのリビジョンをcherry-pickで追加する方法

cherry-pickで追加したいリポジトリ内

git remote add FIX_REPOSITORY [リポジトリURL]
git fetch FIX_REPOSITORY
git cherry-pick [リビジョンid]

参考:https://qiita.com/takeoverjp/items/befdcd616374cf6e0a3b

追加したリポジトリ削除

git remote rm FIX_REPOSITORY

追加したリポジトリにブランチを切り替える

git checkout -b FIX_REPOSITORY-master FIX_REPOSITORY/master

追加したリポジトリをcommitした場合のpushの仕方

git push FIX_REPOSITORY FIX_REPOSITORY-master:master

参考:https://qiita.com/takeoverjp/items/befdcd616374cf6e0a3b

コンフリクト解消ツール

git mergetool

真ん中がオリジナルファイルなのでそこを修正する

1つ前のコミットコメント修正

git commit --amend

エディタが開くのでそこで修正

既にpushしてあるコミットコメントを変更して再度pushすると以下のようなエラーが起こる

To hoge.org:hogehoge/testgroup.git
! [rejected]        develop -> develop (non-fast-forward)
error: failed to push some refs to 'git@hoge.org:hogehoge/testgroup.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

pullするとmergeログが残る。

だれも取り込んでないbranchであればリモートのbranchを消して再度pushすればmergeログが増えずに更新できる。

2つ以上前のコミットコメント修正

git rebase -i [1つ古いリビジョンid]

リビジョンidから現在までの一覧が以下記述とともにエディタで開く 以下のようにpickをeditに変更する

変更前

pick af2a169 dev_1
pick 15d2362 dev_2
pick 03565e8 dev_3

変更後

edit af2a169 dev_1
pick 15d2362 dev_2
pick 03565e8 dev_3

更新できたら

git commit --amend -m "コミットコメント" 

コミットできたら以下コマンドでコンソールを戻す

git rebase --continue

3つのコミットをまとめる

git rebase -i HEAD~3

以下のようにpickをsquashに変更する

変更前

pick d75ebc5 dev_4
pick 3c59fef dev_5
pick f387ef3 dev_6

変更後

pick d75ebc5 dev_4
squash 3c59fef dev_5
squash f387ef3 dev_6

コミット

git commit --amend

"Interactive rebase already started"エラーが出てしまうときは以下コマンドで取り消す

$ git rebase --abort

コミット内容を修正する

git rebase -i HEAD~3

以下のようにpickをsquashに変更する

変更前

pick d75ebc5 dev_4
pick 3c59fef dev_5
pick f387ef3 dev_6

変更後

edit d75ebc5 dev_4
pick 3c59fef dev_5
pick f387ef3 dev_6

変更ファイルを追加

git add hoge.txt

再度コミット

git commit --amend

コミットできたら以下コマンドでコンソールを戻す

git rebase --continue

gitログをツリーで表示

git log --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset%cd %Cblue%cn %Cred%d %Creset%s'

gitログ検索

git log --grep=hogehoge

git差分をlogから検索

git log hogehoge.java | grep commit | awk '{ print $2 }' | xargs -IXXX git show XXX hogehoge.java

vimが開くので/piyopiyoなどで文字列検索

gitログのコミット者から検索

git log | grep taro -A 3 -B 1

前1後3行も合わせて表示

全ての過去コミット一覧

git reflog 

rebaseやcherry-pickなどのログも表示される

dirの作成がかぶった場合

競合はしない。

gitサイズ

$ git count-objects -vH
count: 3204
size: 128.04 MiB
in-pack: 15597
packs: 5
size-pack: 623.93 MiB
prune-packable: 322
garbage: 0
size-garbage: 0 bytes

プロジェクト内で別gitプロジェクト管理(submodule)

sampleprojectに別プロジェクト(samplelibrary)を追加

git clone --recursive git@hosting:[user1]/sampleproject.git 
git submodule add git@hosting:[user1]/samplelibrary.git
cd samplelibrary
git submodule init
git submodule update

改めて別の場所にcloneするとlibraryは取ってこれない・・・

git clone git@hosting:[user1]/sampleproject.git 

改めて別の場所に別プロジェクトごとcloneするときはrecursiveオプションを追加する

git clone --recursive git@hosting:[user1]/sampleproject.git

参考:https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E3%82%B5%E3%83%96%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB

wip運用

  • 空でcommitできる
  • 作業前branchとしてcommitする
git commit --allow-empty -m "WIP: 追加機能"

参考gitサイト

Gitでやらかした時に使える19個の奥義 http://qiita.com/muran001/items/dea2bbbaea1260098051