program tip

git에게 인덱스 만 숨기라고 어떻게 말합니까?

radiobox 2020. 12. 24. 23:34
반응형

git에게 인덱스 만 숨기라고 어떻게 말합니까?


방금 "git add -p"를 사용하여 인덱스에 많은 변경 사항을 추가했으며 이전 커밋에 포함되어야하는 변경 사항을 놓쳤다는 것을 깨달았습니다.

이 모든 새로운 변경 사항을 인덱스에 추가했기 때문에 지금 --amend를 커밋 할 수 없으며 모두 추가하는 데 오랜 시간이 걸리므로 'git reset'을 사용하여 인덱스에서 모두 제거하고 싶지 않습니다. 다시 안으로.

내가 필요한 것은 색인 만 숨길 'git stash'와 같은 것입니다. 작업 파일은 그대로 두어야합니다. 그런 다음 색인을 숨기고, 누락 된 변경 사항을 추가하고, 커밋 한 다음 숨김을 꺼내고 내 색인을 원래대로 되돌릴 수 있습니다.

'git stash'가이 작업을 수행 할 수있는 것 같지 않지만 뭔가 누락 되었습니까? 감사!


가장 간단한 방법은 지금 해당 변경 사항을 중단하고 새 커밋을 만든 다음 수정하는 데 사용하려는 변경 사항으로 두 번째 커밋을 만든 다음 git rebase -i원래 HEAD로 스쿼시하는 데 사용 하는 것입니다.

대안은 커밋을 만들고 태그를 지정하고로 롤백 git reset HEAD^하고 변경 사항을 추가하고 HEAD를 수정 한 다음 태그가 지정된 커밋을 선택하는 것입니다.


내가 찾은 가장 가까운 것은 git stash --patch. 작업 트리 및 색인에 대한 각 변경 사항을 안내하여 숨길 항목을 선택할 수 있습니다.

http://www.kernel.org/pub/software/scm/git/docs/git-stash.html


왜 속임수를 쓰지 않습니까?

git stash --keep-index

현재 색인에없는 모든 것을 가져옵니다. 그때,

git stash

준비된 물건 만 보관할 수 있습니다.

git stash pop

첫 번째 숨김, 변경 사항을 추가하십시오. 그때,

git commit --amend ...
git reset --hard

작업 트리를 정리 한 다음

git stash pop --index

색인 변경 사항을 되돌리려면


git stash 실제로 인덱스 콘텐츠로 커밋을 만든 다음 그 위에 추적 된 모든 파일의 콘텐츠로 커밋을 추가합니다.

이것을 보려면 : 숨김을 만든 다음 실행하십시오.

git log --oneline --graph stash@{0}

따라서 기술적으로 숨길 때 다음을 통해 색인을 다시 가져올 수 있습니다 stash@{0}^2.

$ git show --name-only stash@{0}^2
$ git checkout stash@{0}^2 -- .

또한 숨긴 다음 추적되었지만 추가되지 않은 파일 의 내용을 가져올 수도 있습니다.

# get the diff between what was indexed and the full stashed content :
$ git diff -p stash@{0}^2 stash@{0}  >  diff.patch
# apply this diff :
$ git apply diff.patch

인덱스를 커밋하고 수정 커밋을 만들고 autosquash를 사용하여 리베이스합니다.

git commit
git add -p                         # add the change forgotten from HEAD^
git commit --fixup HEAD^           # commits with "fixup! <commit message of HEAD^>"
git rebase --autosquash -i HEAD~3

이것은 작동하는 것 같습니다. 강력한 지 확인하기 위해 모든 상황에서 테스트하지 않았습니다.

git commit -m _stash && git stash && git reset HEAD^ && git stash save  && git stash pop stash@{1}

그러나 인덱스를 일시적으로 효과적으로 커밋하고 작업 디렉토리를 숨기고 커밋을 되돌려 인덱스를 되돌리고 다른 숨김으로 저장 한 다음 숨김에서 원래 작업 디렉토리를 다시 복원합니다.

이것을 git 별칭으로 추가하면 간단합니다.

[alias]
    istash = "!f() { git commit -m _stash && git stash && git reset HEAD^ && git stash save $1 && git stash pop stash@{1}; }; f"

이렇게하면 다음과 같이 사용할 수 있습니다.

git istash [optional stash name]

magit for emacs를 사용하면 magit-stash-index 명령으로이를 수행 할 수 있습니다.


이 작업을 수행해야했고 결국 스크립팅을위한 git stash 옵션 중 일부를 사용하게되었습니다. Git stash create를 사용하면 stash 객체 (인덱스 포함)를 생성 (적용하지 않음) 할 수 있습니다. Git stash store는 git stash save가 암시 적으로 수행하는 git reset --hard를 수행하지 않고 git stash 스택에 추가합니다. 이렇게하면 스택에 stash 객체를 추가하고 인덱스를 수동으로 재설정하여 인덱스를 효과적으로 숨길 수 있습니다.

# This will add an entry to your git stash stack, but *not* modify anything
git stash store -m "Stashed index" $(git stash create)

# This will reset the index, without touching the workspace.
git reset --mixed 

이제 효과적으로 색인을 숨겼으며 완료되면 git stash pop --index를 수행 할 수 있습니다.

한 가지주의 할 점은 생성 된 stash 객체에는 인덱스에만 관심이 있더라도 작업 영역과 인덱스에서 변경된 파일이 모두 포함되어 있으므로 --index 플래그 ( "숨김에서 색인 만 적용"이 아니라 "숨김에서 색인도 적용"을 의미 함). 이 경우 팝업하기 전에 "git reset --hard"를 수행 할 수 있습니다 (재설정중인 변경 사항이 팝업 또는 직후에 적용하는 변경 사항과 동일하므로 위험하지 않습니다. 보인다.)


git stash -k
git stash
git stash apply stash@{1}
git stash drop stash@{1}

다음은 정확히이 작업을 수행하기 위해 과거에 작성한 작은 스크립트입니다.

(참고 : 원래 https://stackoverflow.com/a/17137669/531021에 게시 했지만 여기에도 적용되는 것 같습니다.이 질문은 정확히 중복되는 질문이 아니기 때문에 두 질문 모두에서 가능한 답변이라고 생각합니다. 사례)

#!/bin/sh

# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`

# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`

# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`

# get back to a clean state with no changes, staged or otherwise
git reset -q --hard

# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to suceed
git cherry-pick -n $INDEXCOMMIT
git stash

# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT

CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
    # If there are no conflicts, it's safe to reset, so that
    # any previously unstaged changes remain unstaged
    #
    # However, if there are conflicts, then we don't want to reset the files
    # and lose the merge/conflict info.
    git reset -q
fi

위의 스크립트를 git-stash-index경로의 어딘가에 저장 한 다음 git stash-index로 호출 할 수 있습니다.

# <hack hack hack>
git add <files that you want to stash>
git stash-index

이제 숨김에는 준비한 변경 사항 만 포함 된 새 항목이 포함되고 작업 트리에는 여전히 준비되지 않은 변경 사항이 포함됩니다.

주요 문제점은 충돌을 일으키지 않고 색인 된 변경 사항을 깨끗하게 제거 할 수 없다는 것입니다. 예를 들어 작업 트리에 색인화 된 변경 사항에 의존하는 변경 사항이 포함되어있는 경우.

이 경우 이러한 충돌은 체리 선택 / 병합 후와 유사하게 일반적인 병합되지 않은 충돌 상태로 유지됩니다.

예 :

git init
echo blah >> "blah"
git add -A
git commit -m "blah"

echo "another blah" >> blah
git add -A
echo "yet another blah" >> blah

# now HEAD contains "blah", the index contains "blah\nanother blah"
# and the working tree contains "blah\nanother blah\nyetanother blah"

git stash-index

# A new stash is created containing "blah\nanother blah", and we are
# left with a merge conflict, which can be resolved to produce
# "blah\nyet another blah"

If you add files ready to commit to the index, but want to stage only them, you can use the function below.

>> momomo.com.git.stash.added

or

>> momomo.com.git.stash.added "name of the  stash"

Bash function:

momomo.com.git.stash.added() {
    local name="$1";

    if [[ "${name}" == "" ]]; then
        name="$(date)"
    fi

    # This will stash everything, but let the added ones remain
    # stash@{1} 
    git stash --keep-index

    # This will stash only the remaining ones
    # @stash@{0}
    git stash save "${name}"

    # Restore everything by applying the first push stash which is now at index 1
    git stash apply stash@{1}

    # Then drop it
    git stash drop stash@{1}

    # At the top of the stash should now be only the originally indexed files
}

Note that you will need to re add things to the index now.

ReferenceURL : https://stackoverflow.com/questions/5281663/how-do-you-tell-git-to-stash-the-index-only

반응형