MarkdownとBullet Journal

いわゆるプログラマーのつぶやき

【Git】ハンク操作

Gitは行単位でstagingやresetが出来る

  • 作業ディレクトリの変更内容をステージングする git add files コマンド
  • ステージングをクリアする git reset files コマンド
  • 作業ディレクトリをステージングの内容に戻す git checkout files コマンド。
  • 指定commitの内容をステージングに戻す git reset "commit指定" files コマンド。
  • 指定commitの内容を作業ディレクトリとステージングに戻す git checkout "commit指定" files コマンド。

以上の各コマンドはファイル単位だけではなく、変更箇所の行の塊(ハンク)単位でも作業を行える。以下ハンク単位や、さらにハンクの中の一部の行だけをstagingやresetする方法を記載する。reset, checkoutの行編集はaddと論理が反転する点に注意

①git add -pで特定ハンクだけstagingする場合

特定ハンクだけをstagingしたい場合は、git add -p filesと-pオプション(--patch)を使う。 git add -p filesコマンドを打つと、対象のファイルにハンクが8個ある場合、最初のハンクが表示され、選択を求められる。

$ git add -p sample.sh
diff --git a/sample.sh b/sample.sh
index 5252aee..44eeb14 100644
--- a/sample.sh
+++ b/sample.sh
@@ -6,15 +6,16 @@

(変更の無い直前行が表示)  # - 変更箇所(ハンク)の表示
-1. 変更前の行①          # - 変更箇所(ハンク)の表示
-2. 変更前の行②          # - 変更箇所(ハンク)の表示
+1. 変更後の行①          # - 変更箇所(ハンク)の表示
+2. 変更後の行②          # - 変更箇所(ハンク)の表示
(変更の無い直後行が表示)  # - 変更箇所(ハンク)の表示

(1/8) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?] 

各選択肢の説明:

  • y : このハンクをstagingする
  • n : このハンクをstagingしない
  • q : staging作業をここまでで中断する
  • a : このハンクをstagingし、残りのハンクも全てstagingする
  • d : このハンクをstagingせず、残りのハンクも全てstagingしない
  • s : ハンクを分割する
  • e : エディターを用いてさらに細かく行単位でstagingする(次の②で説明)

各ハンクを見て、stagingしたい場合はy、したく無い場合はnを押していくと選択したハンクだけstagingされる。

②git add -pでハンクの特定行だけstagingする方法

これは特定ハンクの中からさらに希望する行だけをstagingする方法だ。エディターを使うことで1行単位の選択が可能になる。

$ git add -p sample.sh
diff --git a/sample.sh b/sample.sh
index 5252aee..44eeb14 100644
--- a/sample.sh
+++ b/sample.sh
@@ -6,15 +6,16 @@

(変更の無い直前行が表示)  # - 変更箇所(ハンク)の表示
-1. 変更前の行①          # - 変更箇所(ハンク)の表示
-2. 変更前の行②          # - 変更箇所(ハンク)の表示
+1. 変更後の行①          # - 変更箇所(ハンク)の表示
+2. 変更後の行②          # - 変更箇所(ハンク)の表示
(変更の無い直後行が表示)  # - 変更箇所(ハンク)の表示

(1/8) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?] e↩️と打つとVimが起動する

eを選択するとVimが起動して次の編集画面が現れる

# Manual hunk edit mode -- see bottom for a quick guide
@@ -6,15 +6,16 @@
(変更の無い直前行が表示)  # - エディターに変更箇所として表示される
-1. 変更前の行①          # - エディターに変更箇所として表示される
-2. 変更前の行②          # - エディターに変更箇所として表示される
+1. 変更後の行①          # - エディターに変更箇所として表示される
+2. 変更後の行②          # - エディターに変更箇所として表示される
(変更の無い直後行が表示)  # - エディターに変更箇所として表示される
----
  • stagingしたい行は、そのまま何もしない(自動的にstagingになる)
  • stagingしたくない行は編集が必要
  • 以下、「変更後の行②」をstagingしない時の編集作業
# Manual hunk edit mode -- see bottom for a quick guide
@@ -6,15 +6,16 @@
(変更の無い直前行が表示)
-1. 変更前の行① 
 2. 変更前の行②          # まずstagingしたくない行の-行の - をスペースに置き換える
+1. 変更後の行① 
                        # 次にstagingしたくない行の+行を削除する
(変更の無い直後行が表示) 
  • これで保存すると指定した行だけstagingとなる

③git reset -pで特定ハンクだけunstagingする場合

stagingされた状態から、特定ハンクだけをunstagingしたい場合は、git reset -p filesと-pオプション(--patch)を使う。 git reset -pコマンドを打つと、対象のファイルにハンクが8個ある場合、最初のハンクが表示され、選択を求められる。

$ git reset -p sample.sh
diff --git a/sample.sh b/sample.sh
index 5252aee..44eeb14 100644
--- a/sample.sh
+++ b/sample.sh
@@ -6,15 +6,16 @@

(変更の無い直前行が表示)  # - 変更箇所(ハンク)の表示
-1. 変更前の行①          # - 変更箇所(ハンク)の表示
-2. 変更前の行②          # - 変更箇所(ハンク)の表示
+1. 変更後の行①          # - 変更箇所(ハンク)の表示
+2. 変更後の行②          # - 変更箇所(ハンク)の表示
(変更の無い直後行が表示)  # - 変更箇所(ハンク)の表示

(1/8) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?] 

各ハンクを見て、unstagingしたい場合はy、したく無い場合はnを押していくと選択したハンクだけunstagingされる。

④git reset -pでさらに特定行だけunstagingする方法

特定ハンクの中からさらに希望する行だけをunstagingする方法だ。エディターを使うことで1行単位の選択が可能になる。

$ git reset -p sample.sh
diff --git a/sample.sh b/sample.sh
index 5252aee..44eeb14 100644
--- a/sample.sh
+++ b/sample.sh
@@ -6,15 +6,16 @@

(変更の無い直前行が表示)  # - 変更箇所(ハンク)の表示
-1. 変更前の行①          # - 変更箇所(ハンク)の表示
-2. 変更前の行②          # - 変更箇所(ハンク)の表示
+1. 変更後の行①          # - 変更箇所(ハンク)の表示
+2. 変更後の行②          # - 変更箇所(ハンク)の表示
(変更の無い直後行が表示)  # - 変更箇所(ハンク)の表示

(1/8) Unstage this hunk [y,n,q,a,d,j,J,g,/,e,?] e↩️と打つとVimが起動する

eを選択するとVimが起動して次の編集画面が現れる

# Manual hunk edit mode -- see bottom for a quick guide
@@ -6,15 +6,16 @@
(変更の無い直前行が表示)  # - エディターに変更箇所として表示される
-1. 変更前の行①          # - エディターに変更箇所として表示される
-2. 変更前の行②          # - エディターに変更箇所として表示される
+1. 変更後の行①          # - エディターに変更箇所として表示される
+2. 変更後の行②          # - エディターに変更箇所として表示される
(変更の無い直後行が表示)  # - エディターに変更箇所として表示される
----
  • unstagingしたい行は、そのまま何もしない(自動的にunstagingになる)
  • unstagingしたくない行は編集が必要
  • 以下、「変更後の行②」をunstagingしない時の編集作業
# Manual hunk edit mode -- see bottom for a quick guide
@@ -6,15 +6,16 @@
(変更の無い直前行が表示)  #
-1. 変更前の行①          #
   # -- まずunstagingしたくない行の -が付いている行を削除し、
+1. 変更後の行①          # 
 2. 変更後の行②          # 次にその行の +をスペースに置き換える 
(変更の無い直後行が表示)  # 
  • これで保存すると指定した通りunstagingとなる
  • git add -pとは逆の編集になる(add -pでは -をスペースに置き換えて +行を削除する)
  • 何回か繰り返すと理解できると思う

git reset -p "commit指定" filesは、上記同様なので説明を省略する

⑤git checkout -pで特定ハンクだけ作業ディレクトリからDiscardする場合

作業ディレクトリの変更ファイルの特定ハンクだけをstagingから戻す場合は、git checkout -p filesと-pオプション(--patch)を使う(変更箇所が破棄される点に注意)。 git checkout -pコマンドを打つと、対象のファイルにハンクが8個ある場合、最初のハンクが表示され、選択を求められる。

$ git checkout -p sample.sh
diff --git a/sample.sh b/sample.sh
index 5252aee..44eeb14 100644
--- a/sample.sh
+++ b/sample.sh
@@ -6,15 +6,16 @@

(変更の無い直前行が表示)  # - 変更箇所(ハンク)の表示
-1. 変更前の行①          # - 変更箇所(ハンク)の表示
-2. 変更前の行②          # - 変更箇所(ハンク)の表示
+1. 変更後の行①          # - 変更箇所(ハンク)の表示
+2. 変更後の行②          # - 変更箇所(ハンク)の表示
(変更の無い直後行が表示)  # - 変更箇所(ハンク)の表示

(1/8) Discard This hunk from worktree [y,n,q,a,d,j,J,g,/,e,?] 

各ハンクを見て、Discard(作業ディレクトリの編集箇所を破棄してstagingに戻す)場合はy、したく無い場合はnを押していくと選択したハンクだけDiscardされる。

⑥git checkout -pで指定ハンクからさらに特定行だけDiscardする方法

特定ハンクの中からさらに希望する行だけをDiscardする方法だ。エディターを使うことで1行単位の選択が可能になる。

$ git checkout -p sample.sh
diff --git a/sample.sh b/sample.sh
index 5252aee..44eeb14 100644
--- a/sample.sh
+++ b/sample.sh
@@ -6,15 +6,16 @@

(変更の無い直前行が表示)  # - 変更箇所(ハンク)の表示
-1. 変更前の行①          # - 変更箇所(ハンク)の表示
-2. 変更前の行②          # - 変更箇所(ハンク)の表示
+1. 変更後の行①          # - 変更箇所(ハンク)の表示
+2. 変更後の行②          # - 変更箇所(ハンク)の表示
(変更の無い直後行が表示)  # - 変更箇所(ハンク)の表示

(1/8) Discard This hunk from worktree[y,n,q,a,d,j,J,g,/,e,?] e↩️と打つとVimが起動する

eを選択するとVimが起動して次の編集画面が現れる

# Manual hunk edit mode -- see bottom for a quick guide
@@ -6,15 +6,16 @@
(変更の無い直前行が表示)  # - エディターに変更箇所として表示される
-1. 変更前の行①          # - エディターに変更箇所として表示される
-2. 変更前の行②          # - エディターに変更箇所として表示される
+1. 変更後の行①          # - エディターに変更箇所として表示される
+2. 変更後の行②          # - エディターに変更箇所として表示される
(変更の無い直後行が表示)  # - エディターに変更箇所として表示される
----
  • Discardしたい行は、そのまま何もしない(自動的にunstagingになる)
  • Discardしたくない行は編集が必要
  • 以下、「変更後の行②」をDiscardしない時の編集作業
# Manual hunk edit mode -- see bottom for a quick guide
@@ -6,15 +6,16 @@
(変更の無い直前行が表示)  #
-1. 変更前の行①          #
   # -- まずDiscardしたくない行の -が付いている行を削除し、
+1. 変更後の行①          # 
 2. 変更後の行②          # 次にその行の +をスペースに置き換える 
(変更の無い直後行が表示)  # 
  • これで保存すると指定した通りDiscardする
  • git add -pとは逆の編集になる(add -pでは -をスペースに置き換えて +行を削除する)

git checkout -p "commit指定" filesは、上記同様なので説明を省略する