Zenn
Open10

GItをおさらい

kakkkykakkky

蛙本 第二版を読み直しつつ、コマンド等をおさらいしていく。

kakkkykakkky

リポジトリの作成

  • 初期化
git init

設定

誰がそのコミットをしたかなどは、ユーザー情報(名前、メアド)が記録される。
その他諸々の設定は以下のコマンド。

git config [option] {key} {value}

git config有効範囲

オプション 有効範囲
--system PC全体(すべてのユーザー)
--global 現在のユーザー(その人のすべてのリポジトリ)
--local それぞれのリポジトリ

ユーザー設定

// ユーザー名参照
git config --global user.name

// メアド変更
git config --global user.email hoge@hoge.com
kakkkykakkky

コミット

Gitが持つ3つの状態

  • ワーキングディレクトリ
  • ステージングエリア
    • コミットに含めたい変更をステージング
  • Gitディレクトリ
    • コミットを行い、変更を記録

ファイル・変更の状態

  • Untracked
    • 追跡対象から削除された
  • Unmodified
    • ファイルが編集されていない
  • Modified
    • 何らかの編集がされている
  • Staged
    • Untrackedからgit addしてステージングされた変更

リポジトリの変更状態を確認

作成したファイルは、Untrackedだった。
この段階だと、ワーキングディレクトリに変更が蓄えられていく。

% git status

// 出力
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        sometext.txt

変更をステージして追跡対象とする

ステージするコマンド。
このスナップショットを変更に含める。

git add {filename}
  • 先のsometext.txtの変更は、Stagedの状態になる。
  • ステージされた変更が蓄えられる場所は、ステージングエリア or インデックスとよばれる。
 % git add sometext.txt 
 % git status

// 出力
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   sometext.txt
  • UntrackedからTrackedになる。以降、追跡対象となる。

リポジトリに変更をコミットする

git commit [option]
  • コミットが成功すると、ステージされた変更を反映した状態が最新となり、ワーキングディレクトリ≒Gitリポジトリとなる。
  • 故に、ワーキングディレクトリには変更がないという状態に。
    • Unmodified な状態
    • 一度 git addされたファイルは、永遠に Tracked
      • その中で、Unmodified・Modified・Stagedに移り変わっていく
%git commit -m "txtファイルの作成"
[master (root-commit) a5baf1b] txtファイルの作成
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 sometext.txt

% git status
On branch master
nothing to commit, working tree clean

コミット記録を確認

git log [option]
  • コミットハッシュ
    • コミットを識別するID
% git log
commit a5baf1bf80d95151336cc3ccd7382049ac544498 (HEAD -> master)
Author: hoge <hogehoge@hoge.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成

追跡対象となっているファイルを編集してコミット

先のsometext.txtを編集してみると、そのファイルは Modifiedな状態になる。

% git status

// 出力
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sometext.txt

no changes added to commit (use "git add" and/or "git commit -a")

git addすると、ステージされ、コミット対象となる。

kakkkykakkky

コミットを取り消す

アンステージ

  • 誤って変更をステージした場合、変更をワーキングディレクトリに戻すことをアンステージという。
git restore --staged {name}

変更がワーキングディレクトリに戻った

% git restore --staged sometext.txt 
% git status

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sometext.txt

no changes added to commit (use "git add" and/or "git commit -a")

ワーキングディレクトリの変更を取り消す

modifiedな状態から、Unmodifiedに戻す。
--stagedオプションを外すとワーキングディレクトリの変更を取り消すものとできる。

git restore {name}
  • 実行すると、ファイルのワーキングディレクトリ内のファイルの変更が戻った。
    • 記述していた文が消えた。
    • つまり、変更前のコミットの状態に戻った
git restore sometext.txt

コミットを取り消す

方法は2種ある

  • リセット
    • コミットが記録される前の状態まで変更履歴をまきもどす
  • リバート
    • コミット自体は履歴に残した状態で、「そのコミットを打ち消すコミット」を行う

取り消したコミットも残しておきたいかで選ぶ。

リセット

< 抑えるべき3つ >

  • ワーキングディレクトリ
  • ステージングエリア
  • HEAD
    • 現在自分が参照しているコミットを示すポインタ
    • コミットが記録されるたびにこれも移動していく
    • ワーキングディレクトリ、ステージングエリアの変更は、HEADが指し示すコミットの状態をベースとして検出される

< 3つのうち、どの状態を巻き戻すか >

動作モードops 動作
--soft HEADの位置のみを巻き戻す(コミット操作のみ取り消す)
--mixed(デフォルト) HEADの位置とステージ操作を取り消す
--hard HEAD、ステージ操作、ワーキングディレクトリ、の全てを巻き戻す

戻したい時点のコミットハッシュを指定する

 git log
commit 8f3fb105c77a63d8d0afa9df5d30e77c89de9b5b (HEAD -> master)
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 11:43:58 2025 +0900

    変更

commit a5baf1bf80d95151336cc3ccd7382049ac544498  // ← ここまで戻したい
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成
yutakakiki@kakinokiyuunoMacBook-Air git_practice_2 % 
  • --softの場合
    コミットが取り消され、ステージングされた状態に戻っている。
% git reset --soft a5baf1bf80d95151336cc3ccd7382049ac544498

% git status 
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   sometext.txt

%git log
commit a5baf1bf80d95151336cc3ccd7382049ac544498 (HEAD -> master)
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成
  • --mixedの場合
    コミットが取り消され、アンステージされている。
% git reset  a5baf1bf80d95151336cc3ccd7382049ac544498

Unstaged changes after reset:
M       sometext.txt

% git status

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sometext.txt

no changes added to commit (use "git add" and/or "git commit -a")

% git log
                                         
commit a5baf1bf80d95151336cc3ccd7382049ac544498 (HEAD -> master)
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成
yutakakiki@kakinokiyuunoMacBook-Air git_practice
  • --hardの場合
    コミットも取り消され、ワーキングディレクトリの変更も取り消されている。
    全てが前のコミットの状態に戻感じ。
% git reset --hard a5baf1bf80d95151336cc3ccd7382049ac544498
HEAD is now at a5baf1b txtファイルの作成

% git status
On branch master
nothing to commit, working tree clean. // Unmodifiedなので、編集していたファイルの内容も破棄された

% git log 
commit a5baf1bf80d95151336cc3ccd7382049ac544498 (HEAD -> master)
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成

リバート

% git log              
commit 4dff77bbcf4ad672b24e355242e18c66afddea37 (HEAD -> master) // この変更を取り消したい
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 11:59:44 2025 +0900

    変更

commit a5baf1bf80d95151336cc3ccd7382049ac544498
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成

取り消したいコミットハッシュIDを選択

% git revert --no-edit 4dff77bbcf4ad672b24e355242e18c66afddea37

[master de5cff9] Revert "変更"
 Date: Sun Mar 30 12:02:33 2025 +0900
 1 file changed, 1 deletion(-)

% git status
On branch master
nothing to commit, working tree clean

% git log
commit de5cff96482d227b116cbd91d9cb1077513c2ca8 (HEAD -> master)   // 取り消しコミット
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 12:02:33 2025 +0900

    Revert "変更"
    
    This reverts commit 4dff77bbcf4ad672b24e355242e18c66afddea37.

commit 4dff77bbcf4ad672b24e355242e18c66afddea37
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 11:59:44 2025 +0900

    変更

commit a5baf1bf80d95151336cc3ccd7382049ac544498
Author: YutaKakiki <uta31501224@gmail.com>
Date:   Sun Mar 30 10:57:56 2025 +0900

    txtファイルの作成

コミットは残っているので、resetとは全く別物だが、表面上は git reset --hardと同じく、ワーキングディレクトリも巻き戻されるっぽい。

kakkkykakkky

ブランチを切る

ブランチのリスト

git branch

ブランチの作成

git branch {name}

作成してみると

% git branch sub
% git branch                      
* master
  sub

削除

% git branch -d {name}
Deleted branch {name} (was de5cff9).

指定のブランチに切り替える(チェックアウト)

  • 参照ブランチを切り替えることをチェックアウトという
% git checkout sub          
Switched to branch 'sub'

また、チェックアウトすることで、HEADの位置が移動する。
チェックアウトしてみると、ワーキングディレクトリも変わった。

// subブランチで編集
% git add .
% git commit -m"Subの内容を編集"
[sub 5d1bf62] Subの内容を編集
 1 file changed, 1 insertion(+)

// masterブランチに戻る
% git checkout master           
Switched to branch 'master'

ブランチの分岐を確認

  • ブランチの分岐を確認可能
  • / でコミットの分岐がわかる
git log --graph --all
% git log --graph --all
* commit 6c7e370de0a40fce2688bf3bd26f49f4a6c254a7 (HEAD -> master)
| Author: YutaKakiki <hoge@hoge.com>
| Date:   Sun Mar 30 14:15:01 2025 +0900
| 
|     masterの内容を編集
|   
| * commit 5d1bf62ef2fcdb953d6f37dce2fe115a4674239e (sub)
|/  Author: YutaKakiki <hoge@hoge.com>
|   Date:   Sun Mar 30 14:09:37 2025 +0900
|   
|       Subの内容を編集
| 
* commit de5cff96482d227b116cbd91d9cb1077513c2ca8
| Author: YutaKakiki <hoge@hoge.com>
| Date:   Sun Mar 30 12:02:33 2025 +0900
| 
|     Revert "変更"
|     
|     This reverts commit 4dff77bbcf4ad672b24e355242e18c66afddea37.
| 
* commit 4dff77bbcf4ad672b24e355242e18c66afddea37
| Author: YutaKakiki <hoge@hoge.com>
| Date:   Sun Mar 30 11:59:44 2025 +0900
| 
|     変更
| 
* commit a5baf1bf80d95151336cc3ccd7382049ac544498
  Author: YutaKakiki <hoge@hoge.com>
  Date:   Sun Mar 30 10:57:56 2025 +0900
  
      txtファイルの作成
kakkkykakkky

ブランチの変更を取り込む(マージ)

マージする側のブランチに新しいコミットがない場合(ファストフォワード)

  • つまりマージされる側のブランチが最新というか、先行してコミットが行われていると考えられる

    • 「マージする側」のブランチを「マージされる側」のブランチに移動することで、ブランチの状態を一致させる
  • masterブランチにsub2ブランチをマージする
    コミット履歴は以下の通り

% git log --graph --all
* commit 4e72819c15ace422ba7c708aabbb68961a07d924 (sub2)
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Mon Mar 31 00:05:55 2025 +0900
| 
|     sub2を変更
| 
* commit 6c7e370de0a40fce2688bf3bd26f49f4a6c254a7 (HEAD -> master)
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 14:15:01 2025 +0900
| 
|     masterの内容を編集
|   
| * commit 5d1bf62ef2fcdb953d6f37dce2fe115a4674239e (sub)
|/  Author: YutaKakiki <uta31501224@gmail.com>
|   Date:   Sun Mar 30 14:09:37 2025 +0900
|   
|       Subの内容を編集
| 
* commit de5cff96482d227b116cbd91d9cb1077513c2ca8
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 12:02:33 2025 +0900
| 
|     Revert "変更"
|     
|     This reverts commit 4dff77bbcf4ad672b24e355242e18c66afddea37.
| 
* commit 4dff77bbcf4ad672b24e355242e18c66afddea37
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 11:59:44 2025 +0900
| 
|     変更
| 
* commit a5baf1bf80d95151336cc3ccd7382049ac544498
  Author: YutaKakiki <uta31501224@gmail.com>
  Date:   Sun Mar 30 10:57:56 2025 +0900
  
      txtファイルの作成

sub2(マージされる側)が最新で、先行してコミットされている。

git merge [option] {name}

First-Forwardと出ている。

% git merge sub2
Updating 6c7e370..4e72819
Fast-forward
 sometext.txt | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

ログを確認すると、masterが最新のsub2ブランチの位置に移動したことがわかる。

% git log --graph --all
* commit 4e72819c15ace422ba7c708aabbb68961a07d924 (HEAD -> master, sub2) // 移動してる
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Mon Mar 31 00:05:55 2025 +0900
| 
|     sub2を変更
| 
* commit 6c7e370de0a40fce2688bf3bd26f49f4a6c254a7
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 14:15:01 2025 +0900
| 
|     masterの内容を編集
|   
| * commit 5d1bf62ef2fcdb953d6f37dce2fe115a4674239e (sub)
|/  Author: YutaKakiki <uta31501224@gmail.com>
|   Date:   Sun Mar 30 14:09:37 2025 +0900
|   
|       Subの内容を編集
| 
* commit de5cff96482d227b116cbd91d9cb1077513c2ca8
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 12:02:33 2025 +0900
| 
|     Revert "変更"
|     
|     This reverts commit 4dff77bbcf4ad672b24e355242e18c66afddea37.
| 
* commit 4dff77bbcf4ad672b24e355242e18c66afddea37
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 11:59:44 2025 +0900
| 
|     変更
| 
* commit a5baf1bf80d95151336cc3ccd7382049ac544498
  Author: YutaKakiki <uta31501224@gmail.com>
  Date:   Sun Mar 30 10:57:56 2025 +0900
  
      txtファイルの作成

マージする側のブランチに新しいコミットがある場合(マージコミット)

  • 変更履歴が分岐しているので単純にブランチのポインタを移動することはできない

  • 以下の3つの状態を比較して統合した新たなコミット(マージコミット)を作成し、それに移動させる

    • マージする側のブランチのコミット
    • マージされる側のブランチのコミット
    • 上の二つで共通で最新のコミット

以下の状態のようにブランチが分かれている、masterにsub2をマージする

* commit 32c48189ba336ec9084ea60dc9dac88f663ee9b1 (HEAD -> sub2)
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Mon Mar 31 00:25:12 2025 +0900
| 
|     sub2にsometext3を追加
|   
| * commit bd1760eafb176606c9f36f21eb25b8712504cb8d (master)
|/  Author: YutaKakiki <uta31501224@gmail.com>
|   Date:   Mon Mar 31 00:24:04 2025 +0900
|   
|       masterにsometext2を追加
| 
* commit 4e72819c15ace422ba7c708aabbb68961a07d924
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Mon Mar 31 00:05:55 2025 +0900
| 
|     sub2を変更
| 

この場合、先述の通りマージコミットが作成される。
--no-editをつけると、コミット名を指定しなくてもよくなる。

% git merge --no-edit sub2
Merge made by the 'ort' strategy.
 sometext3.txt | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 sometext3.txt

コミットログをみると、マージコミットとして新たなコミットが作成されていて、masterブランチがそこに移動していることがわかる。

*   commit 57fff246aed98bb09559618785d65a0bf89296fe (HEAD -> master)
|\  Merge: bd1760e 32c4818
| | Author: YutaKakiki <uta31501224@gmail.com>
| | Date:   Mon Mar 31 01:11:16 2025 +0900
| | 
| |     Merge branch 'sub2'
| | 
| * commit 32c48189ba336ec9084ea60dc9dac88f663ee9b1 (sub2)
| | Author: YutaKakiki <uta31501224@gmail.com>
| | Date:   Mon Mar 31 00:25:12 2025 +0900
| | 
| |     sub2にsometext3を追加
| | 
* | commit bd1760eafb176606c9f36f21eb25b8712504cb8d
|/  Author: YutaKakiki <uta31501224@gmail.com>
|   Date:   Mon Mar 31 00:24:04 2025 +0900
|   
|       masterにsometext2を追加
| 
* commit 4e72819c15ace422ba7c708aabbb68961a07d924
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Mon Mar 31 00:05:55 2025 +0900
| 
|     sub2を変更
| 

コンフリクトの可能性

うまく差分を統合できないときに発生する。
例えば、masterブランチとsubブランチは、同じファイルの同じ行に対して別々の変更を加えていて、コンフリクトを発生させる。

分岐しているからマージコミット。

* commit 6c7e370de0a40fce2688bf3bd26f49f4a6c254a7
| Author: YutaKakiki <uta31501224@gmail.com>
| Date:   Sun Mar 30 14:15:01 2025 +0900
| 
|     masterの内容を編集
|   
| * commit 5d1bf62ef2fcdb953d6f37dce2fe115a4674239e (sub)
|/  Author: YutaKakiki <uta31501224@gmail.com>
|   Date:   Sun Mar 30 14:09:37 2025 +0900
|   
|       Subの内容を編集
| 

コンフリクト発生

% git merge sub
Auto-merging sometext.txt
CONFLICT (content): Merge conflict in sometext.txt
Automatic merge failed; fix conflicts and then commit the result.
% git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   sometext.txt

no changes added to commit (use "git add" and/or "git commit -a")

ファイルの中身

.<<<<<<< HEAD // マージする側のブランチの変更
masterの内容
sub2の内容
=======
Subの内容
>>>>>>> sub   // マージされる側のブランチの変更

コンフリクトを解消する

  • <<<<HEADなどは手動で削除
  • 正しい状態に編集した後、いつも通りコミットし直す
% git log --graph --all           
*   commit cfffb76257b89f6de6728b2842d05520a8cb7a0f (HEAD -> master)
|\  Merge: 57fff24 5d1bf62
| | Author: hogehoge <hoge@hoge.com>
| | Date:   Mon Mar 31 10:39:55 2025 +0900
| | 
| |     Merge branch sub
| | 
| * commit 5d1bf62ef2fcdb953d6f37dce2fe115a4674239e (sub)
| | Author: hogehoge <hoge@hoge.com>
| | Date:   Sun Mar 30 14:09:37 2025 +0900
| | 
| |     Subの内容を編集
| |   
* |   commit 57fff246aed98bb09559618785d65a0bf89296fe
|\ \  Merge: bd1760e 32c4818
| | | Author: hogehoge <hoge@hoge.com>
| | | Date:   Mon Mar 31 01:11:16 2025 +0900
| | | 
| | |     Merge branch 'sub2'
| | | 
| * | commit 32c48189ba336ec9084ea60dc9dac88f663ee9b1 (sub2)
| | | Author: hogehoge <hoge@hoge.com>
| | | Date:   Mon Mar 31 00:25:12 2025 +0900
| | | 
| | |     sub2にsometext3を追加
| | | 
* | | commit bd1760eafb176606c9f36f21eb25b8712504cb8d
|/ /  Author: hogehoge <hoge@hoge.com>
| |   Date:   Mon Mar 31 00:24:04 2025 +0900
| |   
| |       masterにsometext2を追加
| | 
* | commit 4e72819c15ace422ba7c708aabbb68961a07d924
| | Author: hogehoge <hoge@hoge.com>
| | Date:   Mon Mar 31 00:05:55 2025 +0900
| | 
| |     sub2を変更
| | 
* | commit 6c7e370de0a40fce2688bf3bd26f49f4a6c254a7
|/  Author: hogehoge <hoge@hoge.com>

マージ自体を取りやめる

選択肢は2つ

  • マージを中止
git merge --abort
  • 現在のブランチが指している最新のコミットを指定してリセットする。
    • コンフリクト以外の変更内容も破棄されうるため注意
git reset --hard {コミットハッシュ}
kakkkykakkky

応用

ファイルの特定の変更のみステージする

-pオプションをつけてaddする

git add -p 
  • ハンク
    • ステージングエリアとワーキングディレクトリの差分
    • ファイルの変更の一部
% git add -p
diff --git a/sometext.txt b/sometext.txt
index 8548d46..f1ef1cc 100644
--- a/sometext.txt  // ステージングエリア
+++ b/sometext.txt. // ワーキングディレクトリ
@@ -1,3 +1,4 @@
 masterの内容.  // 変更されていない
 sub2の内容  // 変更されていない
-
+hogehoge // ワーキングディレクトリの変更
+fugafuga // ワーキングディレクトリの変更
(1/1) Stage this hunk [y,n,q,a,d,e,p,?]? 

@@ -1,3 +1,4 @@の意味

@@
-1,3  // ステージングエリアの1〜2行目 を表示している
+1,4 // ワーキングディレクトリの1〜4行目 を表示している
@@
  • 一部を変更してハンクをステージング
    Stage this hunk [y,n,q,a,d,e,p,?]?に対して、eだと、ファイルを編集し、ファイルを閉じるとステージが完了する。

一部だけがステージされている。

% git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   sometext.txt

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sometext.txt
コマンド 意味
y このハンクをステージに追加する
n このハンクをスキップ(追加しない)
q それ以降のハンクをすべてスキップ
a 以降のすべてのハンクを自動的に追加
d 以降のすべてのハンクを自動的にスキップ
e 手動でハンクを編集
? コマンドのヘルプを表示
  • 本当に一部のハンクをステージできたかを確認する
    ステージングエリアとワーキングディレクトリの差分を表示
git diff

ステージングエリアとワーキングディレクトリの差分は+fugafugaであり、+fugafugaはワーキングディレクトリにあるということがわかる。

% git diff
diff --git a/sometext.txt b/sometext.txt
index d9f4e49..f1ef1cc 100644
--- a/sometext.txt
+++ b/sometext.txt
@@ -1,3 +1,4 @@
 masterの内容
 sub2の内容
 hogehoge
+fugafuga
  • HEADとステージングエリアの比較
git diff --cached
% git diff --cached
diff --git a/sometext.txt b/sometext.txt
index 8548d46..d9f4e49 100644
--- a/sometext.txt. // HEAD
+++ b/sometext.txt. // ステージングエリア
@@ -1,3 +1,3 @@
 masterの内容. // 共通で不変
 sub2の内容. // 共通で不変
-                         // HEAD
+hogehoge   //ステージングエリアの変更 

変更を一時退避させる

  • ブランチAで作業している途中でブランチBにチェックアウトすると、チェックアウトに失敗するかも

    • チェックアウト先とコンフリクトする内容が残っているとまずい。
  • そこで、スタッシュという機能

    • ブランチAの変更を一時格納できる
    • ブランチBでの作業後に、格納した変更を復元可能

masterブランチで作業した途中(sometext2.txtに追記)でsub2に切り替えると

% git checkout sub2    
error: Your local changes to the following files would be overwritten by checkout:
        sometext2.txt
Please commit your changes or stash them before you switch branches.
Aborting

そこで、スタッシュを使う

git stash save

セーブする

% git stash save
Saved working directory and index state WIP on master: 352a8a7 textにhogehogeを追記

切り替えに成功した

% git checkout sub2
Switched to branch 'sub2'

スタッシュのリストを表示する

git stash list
% git stash list
stash@{0}: WIP on master: 352a8a7 textにhogehogeを追記

表示内容の意味

stash@{スタッシュのID} : WIP on {ブランチ名} : {コミットハッシュ} {コミットメッセージ}

スタッシュを復元

git stash pop

チェックアウト後して戻った後、復元。
ファイルにも変更内容が復元されていることが確認可能。

% git checkout master
Switched to branch 'master'

% git stash pop
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sometext2.txt

no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (d9706e645d5f3085096277e085ad0d0af9de1ba5)
  • 注意点として、復元するファイルに、コミットされていない変更が書き加えられているとコンフリクトが発生しpopに失敗するかも。
    • 変更を加える前にpopするか
    • 変更をコミットした後にpopするか
      • コミット内容とコンフリクトが生じる可能性もある
      • その場合は、マージコミットのコンフリクトと同じ手順

以下は、未コミット時にpopした時のエラー

% git stash pop      
error: Your local changes to the following files would be overwritten by merge:
        sometext2.txt
Please commit your changes or stash them before you merge.
Aborting
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   sometext2.txt

no changes added to commit (use "git add" and/or "git commit -a")
The stash entry is kept in case you need it again.

コミットしてからpopしてコンフリクトが発生した場合のエラー

% git stash pop
Auto-merging sometext2.txt
CONFLICT (content): Merge conflict in sometext2.txt
On branch master
Unmerged paths:
  (use "git restore --staged <file>..." to unstage)
  (use "git add <file>..." to mark resolution)
        both modified:   sometext2.txt

no changes added to commit (use "git add" and/or "git commit -a")
The stash entry is kept in case you need it again.

git logにスタッシュが確認できた

| * commit adf07f9198d2edef0351ff998166e0d69890cf15 (refs/stash)
|/| Merge: 7f01188 f1e0a38
| | Author: YutaKakiki <uta31501224@gmail.com>
| | Date:   Mon Mar 31 11:55:14 2025 +0900
| | 
| |     WIP on master: 7f01188 poyo を追記
| | 
| * commit f1e0a3870fa25c4c1c36ff91c753f1329d8a4b9b
|/  Author: YutaKakiki <uta31501224@gmail.com>
|   Date:   Mon Mar 31 11:55:14 2025 +0900
|   
|       index on master: 7f01188 poyo を追記

特定のファイル・ディレクトリを管理から外す

  • 新しく作成されるファイルの場合

    • .gitignoreに追加
  • すでに管理されているファイルを除外する場合

    • .gitignoreでは、すでに管理されているファイルを途中から除外できない
    • 一度ファイルを削除してコミットを行う必要がある
    • 以下の順序で行う
      1. git rm --cached {ファイル名}
      2. コミット
  • ファイルの削除〜ステージングまでをやってくれるコマンド

    • --cachedオプションをつけることで、ワーキングディレクトリにファイルを残しつつ、バージョン管理から外すことができる。
git rm [option] {name}
kakkkykakkky

Github

クローン

  • PCにリモートリポジトリをコピーすること
git clone {URL}
  • ブランチやコミット情報もコピーされているため、 git branch git log で確認できる
  • クローンすると、特殊なブランチがある。
    • origin/main
    • origin/HEAD
  • origin はリモートリポジトリのデフォルトの名前
    • 上の二つは、リモートリポジトリの状態をPCで保持しておくために利用される

リモートリポジトリとローカルのリポジトリを同期する

ローカル▶︎リモートリポジトリ(プッシュ)

  • コミットをリモートリポジトリにプッシュして同期する

  • 登録されているリモートリポジトリを閲覧

git remote -v

例えば以下のように

% git remote -v
origin  https://github.com/kakkky/go-todo-api-v2.git (fetch)
origin  https://github.com/kakkky/go-todo-api-v2.git (push)
  • リモートリポジトリのURLがoriginという名前で登録されている

    • リモートリポジトリを指定する際には、originという名前を使える
  • プッシュ

git push [option] {remote_repository_name} {branch_name}
  • -uオプション
    • 指定したブランチと同じ名前を持つリモートリポジトリのブランチを「上流ブランチ」として登録できる
    • これにより、以降は「リモートリポジトリ名」(大体origin)&「ブランチ名(大体main)」を省略できるようになる

以下のようにプッシュすると

git push -u origin main

次から省略可能

git push 

また、ローカルで作成したブランチをプッシュすることも可能
例えば、リモートリポジトリにローカルで作成したsubブランチをプッシュ

git push -u origin sub

リモートリポジトリ▶︎ローカル(フェッチ)

  • リモートリポジトリの変更(コミット・ブランチ)を取得する
  • しかし、ローカルのmainブランチの状態は変化しない
    • リモートリポジトリのブランチであるorigin/mainの状態が更新されるのみ
git fetch // リモートリポジトリの変更を取得

これで取得して、git logをみると、origin/main``origin/HEADがリモートブランチで行われていたコミットに移動しているのがわかる。

commit 23r934t035t0358430t83
(origin/main,origin/HEAD).    // ここ
| Author : ユーザー名....
| 
| 
        リモートブランチの変更

しかし、HEAD -> mainは移動していない

commit 23r934t035t0358430t83
(HEAD -> main).    // ここ
| Author : ユーザー名....
| 
| 
        ローカルのコミット

リモートリポジトリの追跡ブランチにチェックアウトすれば変更を取得できる

git checkout origin/main

また、ローカルに変更を反映させる場合は、mainorigin/mainブランチをマージする。

git checkout main
git merge origin/main // リモート追跡ブランチをマージ
  • リモートリポジトリで作成されているブランチをフェッチする
    普通にfetchを行う
git fetch

しかし、git branchを確認してもそのブランチは表示されない
フェッチしたはずのブランチをローカルで作成するには、以下のように -bオプションをつけ、リモートブランチ(origin/xxxx)を基とした新たなブランチにチェックアウトする

git checkout -b {ローカルでつけたい名前} {origin/作成されたブランチ}

リモートリポジトリ▶︎ローカル(プル)

  • リモートリポジトリの変更を取得し、同時に反映も行う
    • フェッチ〜ローカル(main)へのマージ
git pull origin main

push操作で、git push -u origin mainと上流ブランチを登録している場合は、

git pull

と省略することも可能

kakkkykakkky

リモートリポジトリとの同期に行き詰まった時

プッシュに失敗

  • ローカルの変更を反映しようとして、その時にリモートで新たな(ローカルには反映されていない)変更があった場合は、コンフリクトする
    • その場合は、リモートリポジトリの変更をローカルにとりこみ、PC上でコンフリクトを解消した上で改めてプッシュする

流れ

git push // コンフリクトで失敗
git pull
  • 手動で統合
  • マージコミットを行う
git push. // 改めて

https://qiita.com/tearoom6/items/0237080aaf2ad46b1963#git-config-pullrebase-false

  • また、pushでコンフリクトが発生した際には、ローカルからの強制プッシュでリモートリポジトリをローカルの変更で上書きすることは可能
    • 安易に行わないことが現実的
    • 他のユーザーが上書き前の状態で作業しているかもしれない
      • またそっちでコンフリクトが起きるかも
git push -f

プルが失敗した時

リモートリポジトリの変更とローカルの競合

リモートリポジトリの変更をプルした時、ローカルでも変更が加えられているという場合にコンフリクトが発生する可能性がある。
その場合は、ローカルの変更をなくした状態でプルする必要がある。

  • 変更を破棄する or git stash
git stash //変更を一時退避
git pull  // リモートリポジトリの変更を取得して反映
git stash pop // 復元

その後、ステージングしてコミット

ローカルの変更をコミット→プルした時

リモート追跡ブランチとローカルのブランチのマージでコンフリクト。
※pushする前で、リモート追跡ブランチには反映できていない!!!のが理由かな。

pullで2つのブランチの変更をマージしようとして、コンフリクトが起きたら、マージコミットを行ったあとで別途Pushを行う。


kakkkykakkky

Git flow

ブランチ

  • mainブランチ

    • リリースされるコード
  • developブランチ

    • 開発作業を行う本線
    • リリースのための最新のコードを管理
    • ここでは直接作業しない
  • featureブランチ

    • 開発する機能ごとに作成されるブランチ
      • feature/xxx
      • 開発が終わればdevelopブランチにマージされる
  • releaseブランチ

    • もう少しでリリース!な段階で修正が必要になった時、developブランチから作成
      • 大きな開発作業は行わず、バグ修正等の最終調整を行う
    • リリース準備が整ったらmainにマージ
  • hotflixブランチ

    • リリースされたブランチ(main)において、急務で直すべき不具合が発生した時に使われる
    • 修正が終わればmainにマージ
    • 同時にdevelopにもマージ

GitHub flow

  • 1日のうちに複数回デプロイを行う開発に適している。

  • mainブランチはいつでもデプロイ可能な状態

  • develop,featureなど、用途別ブランチはない

  • 開発用のブランチには説明的な名前をつける

  • ローカルでコミットしたものをリモートにpush

  • ブランチをマージする際にプルリクを作成

    • OKなら、mainにマージされる
ログインするとコメントできます