gitで新しいファイルの一部のみをステージングする方法は?


221

私は大好き --interactive追加GIT。これは私の毎日のワークフローの一部です。

問題は、追跡されていないファイルでは機能しないようです。私がやりたいのは、新しいファイルを追跡することですが、その一部のみを追加します。つまり、この新しいファイルの一部はまだステージングの準備ができていません。

たとえば、git add -iを使用すると、新しいコードの一部をステージングするためにパッチオプションを選択し、個々のハンクを編集して、デバッグコードのコメントをステージングしないで残すことができます。私がこの方法で作業するのは、現在取り組んでいるメガパッチのどこにまだ作業が必要であるかが明確になるためです。

残念ながら、追跡されていないファイルで同じことを行うことはできないようです。ファイル全体をステージングするか、何もステージングしません。私が使用している回避策は、新しいファイルが空の場合にステージングまたはコミットしてから、通常の方法で個々の変更をステージングすることです。しかし、このソリューションは汚いハックのように感じられ、私が忘れたり、考えを変えたりすると、本来よりも多くの問題が発生します。

したがって、問題は、新しいファイルの一部のみをステージングして、この新しいファイルを追跡しながら、コンテンツの全体または一部をステージングしないままにする方法ですか。

回答:


415

おっと、そのすべてupdate-indexhash-objectビジネスは非常に複雑に見えます。代わりにこれはどうですか:

git add -N new_file
git add -i

からgit help add

-N, --intent-to-add
    Record only the fact that the path will be added later.  An entry
    for the path is placed in the index with no content.  This is useful
    for, among other things, showing the unstaged content of such files
    with git diff and committing them with git commit -a.

9
++ 1!当然の信用。私は今ではこれらのマンページを知っていることを少し信頼しています...</shame>
sehe

1
よく見つかりました。manページをもう少しスクロールする必要がありました。おそらく、Git Proバッジを返却する必要があります。
dave1010

3
新しいファイルから行をステージングするためにgit-guiが内部でこれを使用しないのはなぜですか。
Deiwin 2014

6
素晴らしい-N発見、ありがとう!-pその場合は組み合わせて使いたいですが。gid add -N the_filegit add -p。これ-Nも機能することを追加する必要があります-A
Cyril CHAPON 2015

@Deiwin-[guitool]を.gitconfigに追加して「git add -N $ FILENAME」を実行できます:[guitool "Add with intent"] cmd = "git add -N $ FILENAME" needsfile = yes noconsole = yes
スティーブフォリー

7

これを行う最も簡単な方法(および一般的にimhoインタラクティブステージング)はgit guiです。gitにバンドルされており、gitでサポートされているほとんどすべてのプラットフォームで動作するはずです。

単に実行するgit guiと、GUIが開き、ハンクのステージングとステージング解除が可能になり、追跡されているファイルと追跡されていないファイルの1行でさえ実行できます。

Git Guiスクリーンショット


これは創造的な答えであり、時には非常に役立つ場合があります。
Pablo Olmos de Aguilera C.

3
すべてのgitディストリビューションに含まれているわけではないことに注意してくださいgit gui。たとえば、Debianでは、「git-gui」と呼ばれる別のパッケージにあります。
cristoper 14

この機能を何年も探し続けてきました(十分ではありません)。これは人生を変えるものです
オースティンマートン2014年

2
私にとって、追跡されgit guiていないファイルの単一行のステージングは​​機能していません。実際、これらのメニューオプションは無効になっています
Deiwin

2
@Deiwin質問でこれを見逃していたに違いありません。私のスクリーンショットには、すでに追跡されているファイルが表示されています。git gui新しいファイルに使用したい場合は、git add -N new_file最初に実行する必要があります– Richard Hansenの回答を参照してください。
クロニアル2015

6
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
git add --interactive newfile

簡単なデモ:

mkdir /tmp/demo
cd /tmp/demo
git init .

echo hello > newfile
git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile
  • ヒント「空」のblobがgitオブジェクトデータベースにすでに存在していることが確実な場合は、e69de29bb2d1d6434b8b29ae775ad8c2e48c5391代わりにハッシュをハードコーディングできます。そんなことはお勧めしません_
  • ヒント Windowsを使用している場合は、のNUL:代わりに使用できます/dev/null。それ以外の場合は、次のようなものを使用しますecho -n '' | git hash-object --stdin -w

これで、インデックスにはnewfile空のblob が含まれ、空のblobがまだ存在しない場合はオブジェクトデータベースに入力されています。

$ find .git/objects/ -type f 
.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391

$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   newfile
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   newfile
#

$ git diff
diff --git a/newfile b/newfile
index e69de29..ce01362 100644
--- a/newfile
+++ b/newfile
@@ -0,0 +1 @@
+hello

これはまさにあなたが望むものでなければなりません。非常にインテリジェントなインデックス管理のためにvim逃亡プラグインをお勧めします(Better git add -pを参照してください


1
これはうまくいくようです。覚えるのが少し複雑なので、「stage-empty-file」にエイリアスを付けました。
dave1010

@ dave1010:お役に立てて嬉しいです!ええ、エイリアスを追加することを考えましたが、ワイルドカードや複数のファイル名の引数など、一般的にどのように処理するかを知りませんでした。だから私はしないことを選んだ
11

2

編集:これは現在機能していないようです。私はそれが前にあったと確信しています(git 1.7.1)。うまくいかない場合は、/dev/null上記のseheが示唆するように、ステージングをお勧めします。

git update-index --add --cacheinfo 100644 $(git hash-object -w /dev/null) newfile

Windows(なし/dev/null)を使用している場合は、空のファイルへのパスに置き換えることができます。

元の答え

あなたが欲しい

git add -p # (or --patch)

これにより、追跡されていないファイルが追加されます。manページから:

インデックスと作業ツリーの間でパッチの塊をインタラクティブに選択し、それらをインデックスに追加します。これにより、ユーザーは変更されたコンテンツをインデックスに追加する前に違いを確認できます。

これは効果的にadd --interactiveを実行しますが、初期コマンドメニューをバイパスし、直接パッチサブコマンドにジャンプします。詳細については、「インタラクティブモード」を参照してください。


2
興味深いことに、私にはうまくいきません(git 1.7.4)。git add -p newfileまったく機能しません(nu効果)。git add --interactive'[a] dd untracked'には効果がgit add newfileあります。編集はgit 1.7.5.3でもチェックされています。サイコロなし
11

Windowsのための良いヒント、私の答えにそのためのヒントを追加しました。Thx
sehe

-3

別の可能性の記録のためだけに:私は使用します

git add -N file
git add -p file

そして、ハンクをステージングしたり、インプレースで編集したりできます。


1
この回答は、2011年にさかのぼる承認された回答と同じです。反対票。
スタニスラフパンケビッチ2018年

受け入れられた回答はadd -Nと組み合わされadd -iます。私も作品のadd -p代わりにそれを追加しましたadd -i
ペドロアダムベルガラ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.