22

私は git pre-commit フックを書いています。
スクリプトは一部のコードを再フォーマットする可能性があるため、ステージングされたファイルを変更できます。

すでにステージングされているすべてのファイルを再ステージングするにはどうすればよいですか?

4

3 に答える 3

19

pre-commit hookコンテキストがなくても、次のコマンドを使用して、ステージングされたファイルのリストを取得できます。

git diff --name-only --cached

したがって、ステージングされたファイルのインデックスを再作成する場合は、次を使用できます。

git diff --name-only --cached | xargs -l git add

このpre-commit hookコンテキストでは、David Winterbottom のアドバイスに従い、ステージングされていない変更を何よりも先に隠しておく必要があります。

この手法により、ステージングされていない変更のインデックス作成や変更について心配する必要がなくなります。したがって、ステージングされたすべてのファイルをステージングする必要はありませんが、更新されたすべてのファイルをステージングする必要があります。

# Stash unstaged changes
git stash -q --keep-index

# Edit your project files here
...

# Stage updated files
git add -u

# Re-apply original unstaged changes
git stash pop -q
于 2014-11-13T14:24:15.947 に答える
14

@tziの答えが気に入りました。ただし、David Winterbottom の引用記事では、コミット履歴の一部が失われるというエッジケースの懸念がコメントで提起されています。とはいえ、コメンテーターが言うほど悲観的ではなく、問題のある慣習を持っている人にとってはエッジケースです. それはいつ起こるか

  1. ファイルをステージングする (バージョン A)
  2. コミットする前に同じファイルを編集する (バージョン B)
  3. 変更されたファイル (バージョン B) ではなく、最初にステージングされたファイル (バージョン A) をコミットしたい

コミットが失敗した場合、または成功してコミット前に stash をポップした場合、最初にステージングされたファイル (v. A) はコミットされずに上書きされるため (v. B で) 失われます。明らかに壊滅的ではなく、最新の編集 (v. B) をまだ持っていますが、一部の人々のワークフローや (次善の) コミット プラクティスを妨げる可能性があります。これを回避するには、スクリプトの終了を確認し、いくつかのスタッシング トリックを実行して元の状態に戻します (インデックスには v. A があり、WD には v. B があります)。

事前コミット

#!/bin/sh

... # other pre-commit tasks

## Stash unstaged changes, but keep the current index
### Modified files in WD should be those of INDEX (v. A), everything else HEAD
### Stashed was the WD of the original state (v. B)

git stash save -q --keep-index "current wd"

## script for editing project files
### This is editing your original staged files version (v. A), since this is your WD 
### (call changed files v. A')

./your_script.sh

## Check for exit errors of your_script.sh; on errors revert to original state 
## (index has v. A and WD has v. B)

RESULT=$?
if [ $RESULT -ne 0 ]; then
git stash save -q "original index"
git stash apply -q --index stash@{1}
git stash drop -q; git stash drop -q
fi
[ $RESULT -ne 0 ] && exit 1

## Stage your_script.sh modified files (v. A')

git add -u

git stash popこれは、コミットする前に、ステージングされたファイル (v. A) を変更されたファイル (v. B) で上書きするものであるためです。実際には、ほとんどの場合、スクリプトは失敗しませんが、それでもgit stash poppre-commit フックでは、スクリプトで変更されたファイル (v . A') とステージングされていない変更 (v. B) とのマージ競合が発生します。これにより、ファイルがまったくコミットされなくなりますが、スクリプトは最初にステージングされたファイル (v. A') を変更し、ステージングされていないステージング後に変更されたファイル (v. B) を変更します (おそらく、重要な履歴を失うことはないと仮定your_script.shするだけです)。インデントのようなものなので、v. A と v. A' はほとんど同じです)。

概要:ベスト プラクティスを使用し、ステージングされたファイルを再度変更する前にコミットする場合、元の答えは最も簡単で優れています。私の意見では、そうしないという悪い習慣があり、履歴に両方のバージョン (ステージングされたバージョンと変更されたバージョン) が必要な場合は、注意する必要があります (なぜこれが悪い習慣なのかについての議論です)! いずれにせよ、これは可能なセーフティネットになる可能性があります。

于 2016-09-15T22:28:38.597 に答える