web-dev-qa-db-ja.com

特定のファイルへの変更を隠します

愚かなことに、Eclipseにインポートして自動フォーマットを実行した大きなgitプロジェクトがあります。これで、プロジェクト内のすべてのファイルが変更済みとして表示されます。フォーマットされたファイルをコミットするのではなく、フォーマットされただけで他の変更がなかったすべてのファイルを元に戻します。例えば:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)

#     modified: dir/file1.cpp
#     modified: dir/file1.h
#     modified: dir/file2.cpp
#     modified: dir/file2.h
#     modified: dir/file3.cpp
#     modified: dir/file3.h
#     modified: dir/file4.cpp
#     modified: dir/file4.h

そんなこと知ってる file2.cppfile2.h、およびfile3.cppはコンテンツで変更されています(つまり、フォーマットだけではありません)。これらの3つのファイルへの変更を隠してから、古いリビジョンをチェックアウトして、これらのファイルに変更を再適用できるようにします。私はむしろ次のようなものを避けたいです:

$ cp file2.cpp ~/tmp
$ git checkout blahblahblah
$ cp ~/tmp/file2.cpp .

スタッシングを伴わないこれを行う明白な方法があれば、私に知らせてください。何でも仕事を成し遂げます。

41
ewok

変更を保持したいファイルをadd、残りのファイルをstash、スタッシュをクリアできます:

git add file2.cpp file2.h file3.cpp
git stash --keep-index

この時点で、不要な変更を隠しました。永久に削除したい場合は、次を実行します:

git stash drop

これで、file2.cppfile2.h、およびfile3.cppコミットのステージング。その後、これらのファイルを隠したい(そしてコミットしない)場合:

git reset
git stash

これで、これらの3つのファイルのみが隠された状態で、以前のコミットになります。

更新:

Git 2.13以降には、特定のファイルをgit stash PushVonCが答えで説明しているように

34
redhotvengeance

file2.cppfile2.h、およびfile3.cppがコンテンツで変更された(つまり、フォーマットだけではない)ことを知っています。
これら3つのファイルへの変更を隠してから古いリビジョンをチェックアウトして、これらのファイルに変更を再適用できるようにします。

Git 2.13(2017年第2四半期)では、git stashには、特定のファイルの変更を隠しておく方法が公式にあります。

git stash Push [--] [<pathspec>...]

commit 9e14090commit 1ada502commit df6bba0 (28 Feb 28)、および commit 9ca6326commit 6f5ccd4commit f5727e2 (2017年2月19日)by Thomas Gummerer(tgummerer
C浜野潤夫-gitster- in commit 44c3f09 、2017年3月10日)

As now documented

スナップショットをすばやく作成するには、「プッシュ」を省略できます。
このモードでは、スペルミスのサブコマンドによる不要な隠蔽を防ぐために、オプションではない引数を使用できません。
これに対する2つの例外は、stash -pとpathspecsのエイリアスとして機能するstash Push -pであり、明確にするために二重ハイフン--の後に許可されます。

pathspecが 'git stash Push'に指定されている場合、新しいスタッシュは、pathspecに一致するファイルの変更状態のみを記録します。
インデックスエントリと作業ツリーファイルは、これらのファイルについてもHEADの状態にロールバックされ、pathspecに一致しないファイルはそのまま残ります。

commentsmedmunds で指摘されているように、git stashはルートフォルダーに対する相対パス を使用することに注意してください。 git repo の。

43
VonC

素敵なオプションは、インタラクティブな隠しモードを使用しています。

git stash --patch

それは主にインタラクティブな追加モードのように機能します:作業ツリーでの変更を示す一連の差分が表示され、隠したいファイル(またはファイルの特定の部分のみ)を選択する必要があります。 、残りはそのまま残されます。

man git-stashから:

--patchを使用すると、HEADと隠蔽する作業ツリーとの差分からハンクをインタラクティブに選択できます。隠蔽エントリは、そのインデックス状態がインデックス状態と同じになるように構築されますリポジトリ、およびそのワークツリーには、インタラクティブに選択した変更のみが含まれます。選択した変更は、ワークツリーからロールバックされます。git-add(1)の "インタラクティブモード"セクションを参照してください パッチモード。

あなたの場合は、意味のある変更を失うことなく、フォーマットのみのハンクを表示して個別にスタッシュできます。

14
Diego V

Git stash -pも使用できます。この方法で、どのハンクをスタッシュに追加するかを選択でき、ファイル全体も選択できます。

各ハンクに対していくつかのアクションが求められます:

y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
6
Kashan

これは、git diffおよびgit apply IMOの適切な使用法です。

git diff file2.cpp file2.h file3.cpp > ../my-changes.patch
git checkout ...
git apply ../my-changes.patch

diffの後、パッチファイルを調べて、すべての変更がそこにあることを確認できます。

パッチがきれいに適用されない場合は、--rejectオプションを使用して適用する必要があることに注意してください。 適用のマニュアルページ も参照してください。

3
robinst