Gitはいろいろ行動を制限してくる
Programerの世界的にはめっさ便利なGit。
しかし、一般人からすると不親切極まりない挙動も結構あります。
Gitには状態があって、その状態の時にしか使えないCommandがあります。
CUIのgit commandは大量にあるし、GUIのGIT管理Softでさえ、今の状態ではこのコマンドが使えるよ・・・みたいになっていない。
結局gitの挙動をある程度理解しないといけないのが初心者の最初の壁だと思う。
基本の流れは・・・
⓪local repository無状態
git clone [Remote Repository]でRemote RepositoryからlocalにCopy。
①Clone後/変更なし状態
Fileを変更する。
②変更状態
git add [File name]で変更したFileをStagingする。
③Staging状態
git commit -m [Commit message] でStagingしたFileをCommitする。
④Commit後状態
git push origin [Branch id]
→ ②へ戻る。
Gitのクセが強く、初心者がつまづく部分は下記。
- 変更状態、Staging状態ではBranchの移動、Pullなどができない。
- Stashで一時保存すると変更なし状態になってBranchの移動ができる。
- 困ったら別のフォルダにcloneして最初に戻ってみる。
(Gitのローカルのルートフォルダ名は何でもいい事の理解)
ここまでが基本の流れとして理解するべき部分です。
各状態で使えるコマンドをJSON形式でまとめました。
・カナ混じりですが、gitコマンドに使われる語は必ず英語で統一縛りでまとめてます。
・Commit後状態≒Clone後/変更なし状態 じゃん!とか変更状態とStaging状態のFileが同時に存在するんだよ!
とか細かいツッコミはあるでしょうが、運用上は問題ないっしょということで。
・随時更新します。一部自動生成で作ったので使ったことないコマンドも有り。問題が有ったら教えて。
{
"Git local repository無状態": [
{
"操作": "$ git clone https://github.com/XXXX/XXXXXX.git",
"遷移先": "Clone後/変更なし状態",
"説明": "指定されたrepositoryをlocalにcloneします。cloneが成功すると、local repositoryが作成され、初期状態に遷移します。"
}
],
"Clone後/変更なし状態": [
{
"操作": "file変更",
"遷移先": "変更状態",
"説明": "作業ツリーでfileが変更された場合にこの状態に遷移します。変更されたfileはまだstagingされていません。"
},
{
"操作": "$ git pull, $ git fetch",
"遷移先": "Clone後/変更なし状態",
"説明": "Remote Repositoryから最新の変更を取得し、local repositoryを更新します。作業ツリーに変更がない限り、変更なしの状態が維持されます。"
},
{
"操作": "$ git checkout [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "指定したbranchに切り替えます。作業ツリーに変更がない場合、状態は維持されます。"
},
{
"操作": "$ git merge [Branch id]",
"遷移先": ["Clone後/変更なし状態", "変更状態"],
"説明": "branchからのすべてのCommitの変更込みでmergeします。競合がなければ、変更なしの状態が維持されます。"
},
{
"操作": "$ git merge --no-ff [Branch id] -m [comment]",
"遷移先": ["Clone後/変更なし状態", "変更状態"],
"説明": "branchからの最終的な変更をcommitの内容を含めずmergeします。主にMainのBranchにmergeする時に使います。競合がなければ、変更なしの状態が維持されます。"
},
{
"操作": "$ git merge [Branch id] --allow-unrelated-histories -X [theirs/ours]",
"遷移先": ["Clone後/変更なし状態", "変更状態"],
"説明": "他のリモートリポジトリの内容を取り込みたい場合、git remote add other-repo https://github.com/example/other-repo.gitのようにリモートリポジトリを追加してから本コマンドを実行します。
--allow-unrelated-histories: 無関係な履歴を許可してマージします。
-X theirs: マージコンフリクトが発生した場合、相手のブランチの内容を優先します。
-X ours: マージコンフリクトが発生した場合、自分のブランチの内容を優先します。
"
},
{
"操作": "$ git merge --abort",
"遷移先": "Clone後/変更なし状態",
"説明": "mergeの途中でエラーが発生した場合、mergeを中止し、状態を元に戻します。"
},
{
"操作": "$ git branch [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "新しいbranchを作成します。作成後も現在の状態が維持されます。"
},
{
"操作": "$ git checkout [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "既存のbranchに切り替えます。作業ツリーに変更がなければ、変更なしの状態に戻ります。"
},
{
"操作": "$ git checkout -b [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "新しいbranchを作成し、同時にそのbranchに切り替えます。"
},
{
"操作": "$ git branch -m [old Branch id] [new Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "既存のbranch名を新しい名前に変更します。状態は維持されます。"
},
{
"操作": "$ git branch -d [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "指定したlocalbranchを削除します。状態は維持されます。"
},
{
"操作": "$ git push -u origin [local Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "localの新しいbranchをremote にpushし、defaultで追跡するよう設定します。"
},
{
"操作": "$ git branch -r",
"遷移先": "Clone後/変更なし状態",
"説明": "Remote Repositoryのbranch一覧を表示します。状態は維持されます。"
},
{
"操作": "$ git pull --rebase",
"遷移先": "Clone後/変更なし状態",
"説明": "Localの履歴がRemoteと異なる履歴をたどった場合でも、Localの履歴が消えて、Remoteの履歴にmergeされます。(rebaseと同じ挙動)"
},
{
"操作": "$ git reset [Commitのハッシュ値]",
"遷移先": "変更状態",
"説明": "指定したCommitまでのCommitを取り消し、作業ツリーもその状態に戻します。履歴自体が消える"
},
{
"操作": "$ git rebase [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "現在のbranchのBaseを指定したbranchに変更します。"
},
{
"操作": "$ git revert [Commitのハッシュ値]",
"遷移先": "Clone後/変更なし状態",
"説明": "指定したCommitを打ち消す新しいCommitを作成します。変更前の履歴が残ります"
}
],
"変更状態": [
{
"操作": "file変更",
"遷移先": "変更状態",
"説明": "作業ツリーでfileが変更された場合にこの状態に遷移します。変更されたfileはまだstagingされていません。"
},
{
"操作": "$ git add [File name]",
"遷移先": "Staging状態",
"説明": "変更されたfileをstaging エリアに追加します。fileがstagingされると、Staging状態に進みます。"
},
{
"操作": "$ git checkout HEAD [File name]",
"遷移先": "変更状態",
"説明": "指定したfileを最後のCommitの状態に戻します。変更状態が維持されます。"
},
{
"操作": "$ git reset HEAD [File name]",
"遷移先": "変更状態",
"説明": "staging エリアからfileを取り消し、作業ツリーでの変更を維持します。"
},
{
"操作": "$ git stash save",
"遷移先": "Clone後/変更なし状態",
"説明": "現在の変更をstashし、一時的に退避させます。作業ツリーがクリーンになり、変更なしの状態に戻ります。"
},
{
"操作": "$ git stash apply [stash name]",
"遷移先": "変更状態",
"説明": "stashした変更を作業ツリーに再適用します。"
},
{
"操作": "$ git stash drop [stash name]",
"遷移先": "Clone後/変更なし状態",
"説明": "指定したstashを削除します。"
},
{
"操作": "$ git stash clear",
"遷移先": "Clone後/変更なし状態",
"説明": "すべてのstashを削除し、クリーンな状態にします。"
},
{
"操作": "$ git rm -f [File name]",
"遷移先": "変更状態",
"説明": "指定したfileを削除し、削除されたfileが変更状態に追加されます。"
},
{
"操作": "$ git mv [元のFile name] [変えたいFile name]",
"説明": "fileの名前を変更します。",
"遷移先": "変更状態"
}
],
"Staging状態": [
{
"操作": "$ git commit -m [Commit message] ",
"遷移先": "Commit後状態",
"説明": "stagingされたfileをrepositoryにCommitし、履歴に追加します。Commit後の状態に遷移します。"
},
{
"操作": "$ git reset HEAD [File name]",
"遷移先": "変更状態",
"説明": "staging エリアから指定fileを取り消し、変更状態に戻します。"
}
],
"Commit後状態": [
{
"操作": "$ git commit --amend -m [Commit message]",
"説明": "直前のCommitを修正します。新たにFileの変更を加える事ができます。-mの引数を加えるとCommit messageの修正を含めることができます。修正履歴は残りません。",
"遷移先": "Commit後状態"
},
{
"操作": "$ git push origin [Branch id]",
"遷移先": "Clone後/変更なし状態",
"説明": "localのCommitをRemote Repositoryにpushします。"
},
{
"操作": "$ git push -f",
"説明": "Remote Repositoryに強制的にpushします。remote branchをlocalの状態で上書きします。",
"遷移先": "Clone後/変更なし状態"
},
{
"操作": "$ git pull",
"遷移先": "Clone後/変更なし状態",
"説明": "Remote Repositoryの最新の変更を取り込みます。"
},
{
"操作": "$ git log",
"遷移先": "Commit後状態",
"説明": "Commit履歴を表示します。"
}
]
}
あとは、元々command lineツールであり、引数で様々な機能を実現しているせいか、 細かい動作を実現するGUIが無い気がする。この辺もいい感じのGUI作って欲しいもんです。
##こんな感じのコマンド
git merge --no-ff [Branch id] -m "Version 0.00a Merge [Branch id]"
git reset [Commitのハッシュ値]#これくらいはGUIで実装して欲しいんだけど!